Skip to content

Instantly share code, notes, and snippets.

@B1Z0N
Last active April 10, 2020 15:29
Show Gist options
  • Select an option

  • Save B1Z0N/285a9c7ab29d0992d0232a3e5ede0eea to your computer and use it in GitHub Desktop.

Select an option

Save B1Z0N/285a9c7ab29d0992d0232a3e5ede0eea to your computer and use it in GitHub Desktop.
Build full relation matrix based on minimal relations number interactively
# 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()
@B1Z0N
Copy link
Author

B1Z0N commented Apr 10, 2020

Usage

  1. Download
  2. Run python3 relation_builder.py
  3. Enter data(read instructions from shell)

One Rn at a time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment