How to find all the paths from each router to the rest?
Question:
map = {
routers[0]: [routers[3], routers[4]],
routers[1]: [routers[5], routers[6]],
routers[2]: [routers[7], routers[8]],
routers[3]: [routers[0], routers[4], routers[8]],
routers[4]: [routers[0], routers[3], routers[5], routers[9]],
routers[5]: [routers[1], routers[4], routers[6]],
routers[6]: [routers[1], routers[5], routers[7], routers[9]],
routers[7]: [routers[2], routers[6], routers[8]],
routers[8]: [routers[2], routers[3], routers[7], routers[9]],
routers[9]: [routers[4], routers[6], routers[8]]
}
The keys are the routers and their values are there neighbors.
For example, routers[0] is connected to both routers[3] and routers[4].
And I’m trying to create a table for each router like this:
routers[0] = {
router[1]: router[x],
router[2]: router[y],
# and so on.
}
Where the keys are the destinations and the values are the next routers.
I did it, but it’s too messy. Is there a better way to do that?
Here is more info:
Answers:
Not sure how you are making a dictionary where the keys are also dictionaries, but you can write a breadth-first-search function to find the shortest path and then just grab the first step at index 1.
routers = [f'router{i}' for i in range(10)]
router_map = {
routers[0]: [routers[3], routers[4]],
routers[1]: [routers[5], routers[6]],
routers[2]: [routers[7], routers[8]],
routers[3]: [routers[0], routers[4], routers[8]],
routers[4]: [routers[0], routers[3], routers[5], routers[9]],
routers[5]: [routers[1], routers[4], routers[6]],
routers[6]: [routers[1], routers[5], routers[7], routers[9]],
routers[7]: [routers[2], routers[6], routers[8]],
routers[8]: [routers[2], routers[3], routers[7], routers[9]],
routers[9]: [routers[4], routers[6], routers[8]]
}
def shortest_path(start, dest, router_map = router_map):
visited = [start]
paths = [[start]]
while dest not in visited:
paths = [path + [neighbor]
for path in paths
for neighbor in router_map[path[-1]]]
visited = set([node for path in paths for node in path])
return [path for path in paths if dest in path]
for i in range(1, 10):
print(shortest_path(routers[0], routers[i]))
It seems you are looking for all_shortest_paths
. You can use a library like networkx
to do it for you.
Assuming your list of routers is definded like :
routers = list(range(len(map))
you could do:
import networkx as nx
G = nx.Graph()
for k, v in map.items():
G.add_edges_from([(k, r) for r in v])
all_shortest_paths_dict = {
k: {r: list(nx.all_shortest_paths(G, k, r)) for r in range(len(map)) if r != k}
for k in map
}
print(all_shortest_paths_dict)
{0: {1: [[0, 4, 5, 1]],
2: [[0, 3, 8, 2]],
3: [[0, 3]],
4: [[0, 4]],
5: [[0, 4, 5]],
6: [[0, 4, 5, 6], [0, 4, 9, 6]],
7: [[0, 3, 8, 7]],
8: [[0, 3, 8]],
9: [[0, 4, 9]]},
1: {0: [[1, 5, 4, 0]],
2: [[1, 6, 7, 2]],
3: [[1, 5, 4, 3]],
4: [[1, 5, 4]],
5: [[1, 5]],
6: [[1, 6]],
7: [[1, 6, 7]],
8: [[1, 6, 7, 8], [1, 6, 9, 8]],
9: [[1, 6, 9]]},
......
map = {
routers[0]: [routers[3], routers[4]],
routers[1]: [routers[5], routers[6]],
routers[2]: [routers[7], routers[8]],
routers[3]: [routers[0], routers[4], routers[8]],
routers[4]: [routers[0], routers[3], routers[5], routers[9]],
routers[5]: [routers[1], routers[4], routers[6]],
routers[6]: [routers[1], routers[5], routers[7], routers[9]],
routers[7]: [routers[2], routers[6], routers[8]],
routers[8]: [routers[2], routers[3], routers[7], routers[9]],
routers[9]: [routers[4], routers[6], routers[8]]
}
The keys are the routers and their values are there neighbors.
For example, routers[0] is connected to both routers[3] and routers[4].
And I’m trying to create a table for each router like this:
routers[0] = {
router[1]: router[x],
router[2]: router[y],
# and so on.
}
Where the keys are the destinations and the values are the next routers.
I did it, but it’s too messy. Is there a better way to do that?
Here is more info:
Not sure how you are making a dictionary where the keys are also dictionaries, but you can write a breadth-first-search function to find the shortest path and then just grab the first step at index 1.
routers = [f'router{i}' for i in range(10)]
router_map = {
routers[0]: [routers[3], routers[4]],
routers[1]: [routers[5], routers[6]],
routers[2]: [routers[7], routers[8]],
routers[3]: [routers[0], routers[4], routers[8]],
routers[4]: [routers[0], routers[3], routers[5], routers[9]],
routers[5]: [routers[1], routers[4], routers[6]],
routers[6]: [routers[1], routers[5], routers[7], routers[9]],
routers[7]: [routers[2], routers[6], routers[8]],
routers[8]: [routers[2], routers[3], routers[7], routers[9]],
routers[9]: [routers[4], routers[6], routers[8]]
}
def shortest_path(start, dest, router_map = router_map):
visited = [start]
paths = [[start]]
while dest not in visited:
paths = [path + [neighbor]
for path in paths
for neighbor in router_map[path[-1]]]
visited = set([node for path in paths for node in path])
return [path for path in paths if dest in path]
for i in range(1, 10):
print(shortest_path(routers[0], routers[i]))
It seems you are looking for all_shortest_paths
. You can use a library like networkx
to do it for you.
Assuming your list of routers is definded like :
routers = list(range(len(map))
you could do:
import networkx as nx
G = nx.Graph()
for k, v in map.items():
G.add_edges_from([(k, r) for r in v])
all_shortest_paths_dict = {
k: {r: list(nx.all_shortest_paths(G, k, r)) for r in range(len(map)) if r != k}
for k in map
}
print(all_shortest_paths_dict)
{0: {1: [[0, 4, 5, 1]],
2: [[0, 3, 8, 2]],
3: [[0, 3]],
4: [[0, 4]],
5: [[0, 4, 5]],
6: [[0, 4, 5, 6], [0, 4, 9, 6]],
7: [[0, 3, 8, 7]],
8: [[0, 3, 8]],
9: [[0, 4, 9]]},
1: {0: [[1, 5, 4, 0]],
2: [[1, 6, 7, 2]],
3: [[1, 5, 4, 3]],
4: [[1, 5, 4]],
5: [[1, 5]],
6: [[1, 6]],
7: [[1, 6, 7]],
8: [[1, 6, 7, 8], [1, 6, 9, 8]],
9: [[1, 6, 9]]},
......