Last active
April 10, 2020 15:29
-
-
Save B1Z0N/285a9c7ab29d0992d0232a3e5ede0eea to your computer and use it in GitHub Desktop.
Build full relation matrix based on minimal relations number interactively
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Build full relation matrix | |
| # based on minimal relations number | |
| # interactively | |
| def floyd_warshall(graph, v): | |
| """ | |
| :param graph: 2D array calculated from weight[edge[i, j]] | |
| :type graph: List[List[float]] | |
| :param v: number of vertices | |
| :type v: int | |
| :return: shortest distance between all vertex pairs | |
| distance[u][v] will contain the shortest distance from vertex u to v. | |
| 1. For all edges from v to n, distance[i][j] = weight(edge(i, j)). | |
| 3. The algorithm then performs distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j]) for each | |
| possible pair i, j of vertices. | |
| 4. The above is repeated for each vertex k in the graph. | |
| 5. Whenever distance[i][j] is given a new minimum value, next vertex[i][j] is updated to the next vertex[i][k]. | |
| """ | |
| dist = [[float("inf") for _ in range(v)] for _ in range(v)] | |
| for i in range(v): | |
| for j in range(v): | |
| dist[i][j] = graph[i][j] | |
| # check vertex k against all other vertices (i, j) | |
| for k in range(v): | |
| # looping through rows of graph array | |
| for i in range(v): | |
| # looping through columns of graph array | |
| for j in range(v): | |
| if ( | |
| dist[i][k] != float("inf") | |
| and dist[k][j] != float("inf") | |
| and dist[i][k] + dist[k][j] < dist[i][j] | |
| ): | |
| dist[i][j] = dist[i][k] + dist[k][j] | |
| return dist | |
| def to_muR(m): | |
| """ | |
| :param m: 2D array calculated from floyd-warshall alogrithm | |
| :type m: List[List[float]] | |
| From shortest paths matrix to our relations matrix | |
| Example: | |
| Task: x1 > x2, x2 ~ x3 | |
| From the shortest path matrix using Floyd Warshall algorithm | |
| 0 1 2 | |
| INF 0 1 | |
| INF 1 0 | |
| To the relation matrix of all Xi based on our minimal set of relations(task) | |
| 1 1 1 | |
| 0 1 1 | |
| 0 1 1 | |
| """ | |
| v = len(m) | |
| transform = lambda val: 0 if val == float('inf') or val == 0 else 1 | |
| return [[transform(m[i][j]) if i != j else 1 for j in range(v)] for i in range(v)] | |
| def print_matrix(m): | |
| v = len(m) | |
| print(' ', end='') | |
| for i in range(v): | |
| print('x{}'.format(i + 1), end=' ') | |
| print() | |
| for i in range(v): | |
| print('x{} ['.format(i + 1), end=' ') | |
| for j in range(v - 1): | |
| print(m[i][j], end=' ') | |
| print(str(m[i][v- 1]) + ' ]') | |
| def insert_relations(): | |
| def wrong_input(): | |
| raise ValueError("Wrong input or formatting, read carefully and double check") | |
| v = int(input("Enter number of alternatives: ")) | |
| graph = [[float("inf") if i !=j else 0.0 for i in range(v)] for j in range(v)] | |
| print("Now enter relations in a format of: ") | |
| print("x1 > x2") | |
| print("x3 < x1") | |
| print("x2 ~ x1") | |
| print("Spaces are mandatory") | |
| print("Enter empty line, when ready: ") | |
| def xi_to_i(xi): | |
| import re | |
| return int(re.findall(r'\d+', xi)[-1]) | |
| def set_rel(graph, src, dest, rel): | |
| if rel == '>': | |
| graph[src][dest] = 1.0 | |
| elif rel == '<': | |
| graph[dest][src] = 1.0 | |
| elif rel == '~': | |
| graph[src][dest] = 1.0 | |
| graph[dest][src] = 1.0 | |
| else: | |
| wrong_input() | |
| while True: | |
| relation = str(input()) | |
| if relation == '': | |
| break | |
| op1, rel, op2 = relation.split() | |
| v1, v2 = xi_to_i(op1) - 1, xi_to_i(op2) - 1 | |
| if v1 >= v or v2 >= v: | |
| wrong_input() | |
| set_rel(graph, v1, v2, rel) | |
| return graph, v | |
| def main(): | |
| graph, v = insert_relations() | |
| shortest_paths_matrix = floyd_warshall(graph, v) | |
| relations_matrix = to_muR(shortest_paths_matrix) | |
| print_matrix(relations_matrix) | |
| if __name__ == "__main__": | |
| main() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
python3 relation_builder.pyOne Rn at a time