使用NetworkX在加权图中搜索最短路径时的附加约束

时间:2014-03-12 13:42:08

标签: graph dijkstra networkx

我向您询问有关使用NetworkX

在加权图中搜索最短路径时添加其他约束的问题

示例图:

G.add_edge(A, B, weight=1)
G.add_edge(B, C, weight=2)
G.add_edge(A, C, weight=1)
..
..
..
G.add_edge(Y, Z, weight=6)

所以,现在我想找到从A到F的最短路径,包括一些点,例如:C,L,G,R(排序没有意义)。如何使用NetworkX。

谢谢!

1 个答案:

答案 0 :(得分:1)

这可能不是最好的解决方案,但无论如何:

import networkx as nx
from string import letters
from random import sample, randint
from itertools import permutations

# generate random graph    
G = nx.Graph()

nodes = list(letters[:20])

for anode in nodes:
   G.add_node(anode, weight=randint(1,20))

for edge in [sample(nodes, 2) for i in range(60)]:
   G.add_edge(*edge)

现在,让我们定义路径搜索功能:

def multiple_dijkstra(G, apath, result, n=0, i=1):
   """For a path of: a - b - c - d, search recursively for the shortest
   paths between 'a' and 'b', then 'b' and 'c', then 'c' and 'd'.
   Return a list which is a path from 'a' to 'd' through 'b' and 'c'."""
   try:
      result.extend(nx.dijkstra_path(G, apath[n], apath[i])[:-1])
      multiple_dijkstra(G, apath, result, n+1, i+1)
      return result
   except IndexError:
      result.extend(nx.dijkstra_path(G, apath[n], apath[i-1]))
      return result

def possible_paths(start_node, end_node, *between):
   """Generate all possible paths based on permutations of *between"""
   for permutation in permutations(between, len(between)):
      yield [start_node] + list(permutation) + [end_node]

def gothrough_possible_paths(start_node, end_node, *between):
   """Test all permutations for shortest path"""
   for apath in possible_paths(start_node, end_node, *between):
      result = []
      shortest_path = multiple_dijkstra(G, apath, result)
      print 'Testing path: {}\nResult: {} (length: {})'.format(
                             ' - '.join(apath),
                             ' - '.join(shortest_path),
                             len(shortest_path))

现在,我们可以搜索最短的路径:

# let's pick 5 random nodes: a start node, end node and three in-between nodes
n1, n2, n3, n4, n5 = sample(nodes, 5)

# ...and search for the shortest paths between 'n1' and 'n2'
# such that 'n3', 'n4' and 'n5' are in-between nodes
gothrough_possible_paths(n1, n2, n3, n4, n5)

可能的结果:

Testing path: e - h - g - j - t
Result: e - k - h - k - g - k - b - j - b - t (length: 10)
Testing path: e - h - j - g - t
Result: e - k - h - k - b - j - o - c - g - k - b - t (length: 12)
Testing path: e - g - h - j - t
Result: e - k - g - k - h - k - b - j - b - t (length: 10)
Testing path: e - g - j - h - t
Result: e - k - g - k - b - j - b - k - h - l - t (length: 11)
Testing path: e - j - h - g - t
Result: e - j - b - k - h - k - g - k - b - t (length: 10)
Testing path: e - j - g - h - t
Result: e - j - o - c - g - k - h - l - t (length: 9)

因此,从et的最短路径是jgh(按此顺序),实际路径是:e - j - o - c - g - k - h - l - t

我不是这方面的专家,因此我对更好的解决方案感到好奇。但希望这会有所帮助。