Обычно это выглядит правильно.
Вы можете использовать bidirectional_dijkstra .Это может быть значительно быстрее, если вы знаете исходные и целевые узлы вашего пути (см. Мои комментарии внизу).
Чтобы решить проблему веса ребра и узла, есть два варианта.Сначала обратите внимание, что вы после суммы узлов по пути.Если я присваиваю каждому ребру вес w(u,v) = w(u) + w(v)
, то сумма весов по нему равна w(source) + w(target) + 2 sum(w(v))
, где узлы v
- это все узлы, найденные на этом пути.Все, что имеет минимальный вес с этими весами ребер, будет иметь минимальный вес с весами узлов.
Таким образом, вы можете пойти и назначить каждому ребру вес, который будет суммой двух узлов.
for edge in G.edges():
G.edges[edge]['weight'] = G.nodes[edge[0]]['weight'] + G.nodes[edge[1]]['weight']
Но альтернатива состоит в том, чтобы отметить, что вес, введенный в bidirectional_dijkstra
, может быть функцией, которая принимает ребро в качестве ввода.Определите свою собственную функцию, чтобы получить сумму весов двух узлов:
def f(edge):
u,v = edge
return G.nodes[u]['weight'] + G.nodes[v]['weight']
, а затем в своем вызове выполните bidirectional_dijkstra(G, source, target, weight=f)
Так что я предлагаю выбрать либо назначить каждомудобавьте вес, равный сумме весов узлов, или определите функцию, которая даст эти веса только для ребер, с которыми сталкивается алгоритм.С точки зрения эффективности, я ожидаю, что потребуется больше времени, чтобы выяснить, что лучше, чем кодирование любого алгоритма.Единственная проблема производительности заключается в том, что при назначении всех весов будет использоваться больше памяти.Предполагая, что память не является проблемой, используйте ту, которая, по вашему мнению, проще всего реализовать и поддерживать.
Некоторые комментарии к двунаправленной дижкрахте: представьте, что у вас есть две точки в пространстве на расстоянии R друг от друга, и вы хотитенайти кратчайшее расстояние между ними.Алгоритм dijkstra (который является значением по умолчанию для shorttest_path) исследует каждую точку на расстоянии D от исходной точки.По сути это похоже на расширение воздушного шара с центром в первой точке, пока он не достигнет другой.Это имеет объем (4/3) пи R ^ 3.С bidirectional_dijkstra
мы раздуваем воздушные шары по центру каждого, пока они не коснутся.Каждый из них будет иметь радиус R / 2.Таким образом, объем равен (4/3) пи (R / 2) ^ 3 + (4/3) пи (R / 2) ^ 3, что составляет четверть объема исходного шара, поэтому алгоритм исследовал четвертьпространства.Поскольку сети могут иметь очень высокое эффективное измерение, экономия часто намного больше.