Python实现Bellman-Ford算法

1、代码实现

import queue
# 点集
# case 1
# node_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
# case 2
node_list = ['A', 'B', 'C', 'D', 'E']
source = 'A'
time = 0
# has_negative_cycle = False
iteration = 0
next_node_list = queue.Queue(maxsize=len(node_list))
next_node_list.put(source)
# 图
# case 1
# graph = {'A': {'B': 6, 'C': 5, 'D': 5},  # 表示从A指向BCD
#          'B': {'E': -1},
#          'C': {'B': -2, 'E': 1},
#          'D': {'C': -2, 'F': -1},
#          'E': {'G': 3},
#          'F': {'G': 3},
#          'G': {}}
# case 2
graph = {'A': {'B': -1, 'C': 4},  # 表示从A指向BCD
         'B': {'C': 3, 'D': 2, 'E': 2},
         'C': {},
         'D': {'B': 1, 'C': 5},
         'E': {'D': -3}}
# distance存储从源点到各个点的最短距离
# case 1
# distance = {'A': 0, 'B': float('Inf'), 'C': float('Inf'), 'D': float('Inf'), 'E': float('Inf'), 'F': float('Inf'),
#             'G': float('Inf')}
# case 2
# distance = {'A': 0, 'B': float('Inf'), 'C': float('Inf'), 'D': float('Inf'), 'E': float('Inf')}
# 初始化distance操作
distance = {}
temp_node_set = set()
for key, value in graph.items():
    temp_node_set.add(key)
    for key1, value1 in value.items():
        temp_node_set.add(key1)
for i in temp_node_set:
    if i == source:
        distance[source] = 0
    else:
        distance[i] = float('Inf')
# print(distance)
# 父节点初始化
# case 1
# parent_node = {'B': None, 'C': None, 'D': None, 'E': None, 'F': None, 'G': None}
# case 2
# parent_node = {'B': None, 'C': None, 'D': None, 'E': None}
parent_node = {}
for i in temp_node_set:
    if i != source:
        parent_node[i] = None
print(parent_node)
# 正无穷加任意数等于正无穷,输出为True
# print(float('Inf') == float('Inf')+1000)
edge_set = set()
# case 1
# edge_num = 10
# case 2
# edge_num = 8
edge_num = 0
# 计算图中有多少条边
for value in graph.values():
    edge_num = edge_num + len(value)
while True:
    # if next_node_list.empty():  # 按找这种方式,图存在闭环会无法判断
    if len(edge_set) == edge_num:  # 全部遍历过一次
        # if iteration == 0:  # 重新迭代一次发现权重没有变化,中止迭代
        #     break
        # else:
        if iteration != 0:  # 这个time是为了检验再迭代一次,权重有没有变化
            print('------进入新一轮迭代------')
            time = time + 1
            iteration = 0
            edge_set = set()
            next_node_list = queue.Queue(maxsize=len(node_list))  # 长度为如果超过的话,队列会阻塞
            next_node_list.put(source)
            if time > 1000:
                print("存在负数闭环,找不到最优解。")
                break
            # print(distance)
        else:
            break

    node = next_node_list.get()  # 返回并删除头部元素
    # print(node+"出队")
    # print(graph[node].items())
    for key, value in graph[node].items():
        if len(edge_set) == edge_num:  # 所有边都遍历结束了
            break
        edge_set.add(node + key)
        next_node_list.put(key)
        # print(edge_set)
        # print("父节点"+node)
        if value + distance[node] < distance[key]:
            iteration = iteration + 1
            distance[key] = value + distance[node]  # 更新权重
            parent_node[key] = node  # 更新父节点
        print(parent_node)
        print(distance)
        # print(edge_set)

    # print(iteration)
print(distance)
print(parent_node)

2、总结

  我使用了队列的数据结构,在代码中也做了详细的注释,会不定期更新…如果觉得我写的还不错,请点个赞吧~

你可能感兴趣的:(算法,python,bellman-ford)