第二部分 在有m个顶点的完全图中找到路径长度为n的最短路径,从任意顶点出发到任意顶点结束
程序员文章站
2024-03-15 18:54:18
...
该文承接上一篇文章(https://blog.csdn.net/dahuayaoer/article/details/81180641)继续实现后面两部分:3)计算路径中权重和最小值,利用Dijkstra思想。最后一步,将三部分代码组合起来实现完整的算法
3)计算排列中的最小权重之和
我直接使用Dijkstra的源码,参考了:http://python.jobbole.com/83965/
# -*-coding:utf-8 -*-
class DijkstraExtendPath():
def __init__(self, node_map):
self.node_map = node_map
self.node_length = len(node_map)
self.used_node_list = []
self.collected_node_dict = {}
def __call__(self, from_node, to_node):
self.from_node = from_node
self.to_node = to_node
self._init_dijkstra()
return self._format_path()
def _init_dijkstra(self):
self.used_node_list.append(self.from_node)
self.collected_node_dict[self.from_node] = [0, -1]
for index1, node1 in enumerate(self.node_map[self.from_node]):
if node1:
self.collected_node_dict[index1] = [node1, self.from_node]
self._foreach_dijkstra()
def _foreach_dijkstra(self):
if len(self.used_node_list) == self.node_length - 1:
return
for key, val in self.collected_node_dict.items():
if key not in self.used_node_list and key != to_node:
self.used_node_list.append(key)
else:
continue
for index1, node1 in enumerate(self.node_map[key]):
if node1 and index1 in self.collected_node_dict and self.collected_node_dict[index1][0] > node1 + val[0]:
self.collected_node_dict[index1][0] = node1 + val[0]
self.collected_node_dict[index1][1] = key
elif node1 and index1 not in self.collected_node_dict:
self.collected_node_dict[index1] = [node1 + val[0], key]
self._foreach_dijkstra()
def _format_path(self):
node_list = []
temp_node = self.to_node
node_list.append((temp_node, self.collected_node_dict[temp_node][0]))
# print((temp_node, self.collected_node_dict[temp_node][0]))
while self.collected_node_dict[temp_node][1] != -1:
temp_node = self.collected_node_dict[temp_node][1]
node_list.append((temp_node, self.collected_node_dict[temp_node][0]))
node_list.reverse()
return node_list
def set_node_map(node_map, node, node_list):
for x, y, val in node_list:
node_map[node.index(x)][node.index(y)] = node_map[node.index(y)][node.index(x)] = val
import networkx as nx
if __name__ == "__main__":
# we need the structure of input data are as follows
# node = ['A', 'B', 'C']
# node_list = [('A', 'C', 8), ('A', 'B', 2), ('B', 'C', 6)]
# node_map = [[0 for val in xrange(len(node))] for val in xrange(len(node))]
# set_node_map(node_map, node, node_list)
# firstly, build a graph; then transfer the value of graph to right data structure
G = nx.Graph()
G.add_weighted_edges_from([(1, 2, 1), (1, 3, 2), (2, 4, 2), (3, 4, 1)])
node1 = list(G.nodes)
node_list1 = []
for n, nbrs in G.adj.items():
for nbr, eattr in nbrs.items():
wt = eattr['weight']
n=str(n)
nbr=str(nbr)
wt=str(wt)
edgeWeight = n +nbr +wt
node_list1.append(edgeWeight)
node_list2 = []
for f in range(1, len(node_list1)):
wei = node_list1[f].replace(" ", "")
findata2 = []
findata = tuple(wei)
for l in range(0, 3):
findata2.append(int(findata[l]))
findata3 = tuple(findata2)
node_list2.append(findata3)
# above all we get the right data structure node1 and node_list2 then use the Dijkstra algorithem directly
node_map = [[0 for val in xrange(len(node1))] for val in xrange(len(node1))]
set_node_map(node_map, node1, node_list2)
# A -->; D
from_node = node1.index(1)
to_node = node1.index(2)
dijkstrapath = DijkstraExtendPath(node_map)
path = dijkstrapath(from_node, to_node)
print path
至此,还剩最后过程,将三个步骤结合起来,完整的代码如下: