Я использую floyd_warshall_predecessor_and_distance
функцию Networkx
в Python 3, чтобы найти кратчайший путь на двунаправленном графике.Функция возвращает кратчайшее расстояние между заданными двумя узлами (если существует ребро) и частью пути.Я поясню, что я имею в виду, говоря «порция».Ниже приведены мои входные и выходные данные.
Входные данные :
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
V = [1, 2, 3, 4, 5]
N = [(i,j) for i in V for j in V if i!=j]
E = {} #Creating an empty dictionary to store the travel times from node i to j
Elist = (list(np.random.randint(low=1, high = 30, size = len(N))))
for i in range(len(N)):
E[N[i]] = Elist[i] # (i,j) does not have to be equal to (j,i)
E[(2, 1)] = 5
E[(5, 4)] = 0
E[(2, 4)] = 20
G=nx.DiGraph()
G.add_nodes_from(V)
for i in E:
G.add_weighted_edges_from([(i[0], i[1], E[i])])
path_lengths=nx.floyd_warshall_predecessor_and_distance(G, weight='weight')
path_lengths
Выходные данные :
({1: {2: 1, 3: 4, 4: 5, 5: 1},
2: {1: 2, 3: 4, 4: 5, 5: 1},
3: {1: 3, 2: 3, 4: 5, 5: 1},
4: {1: 4, 2: 1, 3: 4, 5: 1},
5: {1: 4, 2: 5, 3: 4, 4: 5}},
{1: defaultdict(<function networkx.algorithms.shortest_paths.dense.floyd_warshall_predecessor_and_distance.<locals>.<lambda>.<locals>.<lambda>()>,
{1: 0, 2: 13, 3: 8, 4: 1, 5: 1}),
2: defaultdict(<function networkx.algorithms.shortest_paths.dense.floyd_warshall_predecessor_and_distance.<locals>.<lambda>.<locals>.<lambda>()>,
{2: 0, 1: 5, 3: 13, 4: 6, 5: 6}),
3: defaultdict(<function networkx.algorithms.shortest_paths.dense.floyd_warshall_predecessor_and_distance.<locals>.<lambda>.<locals>.<lambda>()>,
{3: 0, 1: 10, 2: 20, 4: 11, 5: 11}),
4: defaultdict(<function networkx.algorithms.shortest_paths.dense.floyd_warshall_predecessor_and_distance.<locals>.<lambda>.<locals>.<lambda>()>,
{4: 0, 1: 5, 2: 18, 3: 7, 5: 6}),
5: defaultdict(<function networkx.algorithms.shortest_paths.dense.floyd_warshall_predecessor_and_distance.<locals>.<lambda>.<locals>.<lambda>()>,
{5: 0, 1: 5, 2: 13, 3: 7, 4: 0})})
Я специально сделалпуть для (2, 4), который равен 2> 1> 5> 4. Когда я смотрю на path_lengths[0]
, я вижу, что для перехода от узлов 2 к 4 я остановился на 5. Далее, чтобы перейти от 2 к5, я остановился на 1. Эти два говорят мне полный маршрут, но я хочу видеть весь маршрут как вывод, например, 2: {... 4: 1, 5, ...}
или {(2,4): (2,1), (1,5), (5,4)}
, а не видеть его по частям, а затем объединять части в уме.Есть ли лучший пакет в Networkx, который может это сделать?Кстати, мой двунаправленный граф не содержит отрицательных весов, и график может быть довольно большим (поэтому я выбрал эту функцию).
Вот моя попытка начать:
new = path_lengths[0]
for v in V:
for d in V:
if v!=d:
if new[v][d] != v:
new[v][d] = (new[v][d],d)
elif new[v][d] == v:
new[v][d] = (v,d)
Спасибо за ответы!