第二部分 在有m个顶点的完全图中找到路径长度为n的最短路径,从任意顶点出发到任意顶点结束

    该文承接上一篇文章(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

    至此,还剩最后过程,将三个步骤结合起来,完整的代码如下:

猜你喜欢

转载自blog.csdn.net/dahuayaoer/article/details/81207154