数据结构(bellman-ford算法求最短路径)

本文深入探讨了Bellman-Ford算法,一种用于求解有向图中源点到所有其他点最短路径的经典算法。文章详细介绍了算法的流程、Python代码实现过程,并讨论了如何检测负权回路。适合对图算法感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bellman-ford算法求源点到任意点最短路径

一、算法流程

  1. 初始化所有的node节点。每个节点中存储从源点到达这个节点的距离,源点的值为0,其它的节点则为无穷大。
  2. 循环节点,遍历所有的有向边,对有向边进行松弛计算,不断逼近正确的路线。
  3. 遍历所有的有向边 edges(start,end)可能出现的路线情况,如果出现
    dicts[edge[‘end’]]> dicts[edge[‘start’]] + edge[‘weight’] 的情况,表示存在负权回路的情况,如果存在负权回路的话,就会因为出现无法收敛而导致不能求出最短路径的情况。

二、代码实现过程(python)

定义算法类
class Bellman_ford():
    def __init__(self,node_num:int,startedvertex:str):
        self.edges = []
        self.maxint = float('Inf')  #源点和某点不可达时的距离,无穷大
        self.dicts ={} #各边距离字典
        self.node_num = node_num #节点数
        self.startedvertex = startedvertex #源点字符

定义添加数据函数
    #判断字典是否存在node的下标,否则添加字典,初始化值为maxint
    def has_node(self,nodes):
        for node in nodes:
            if node not in self.dicts.keys():
                self.dicts[node] = self.maxint
                self.strList.append(node)
    # 添加数据
    def add(self,start:str,end:str,weight:int):
        # start:有向边起点;end:有向边的终点;weight:有向边的权重
        self.has_node([start,end])
        self.edges.append({
            'start':start,
            'end':end,
            'weight':weight
        })
定义初始化数据函数
    #开始初始化
    def init(self):
        for dict in self.dicts.keys():
            self.dicts[dict] = self.maxint
        self.dicts[self.startedvertex] = 0
        #字符排序
        for i in range(len(self.strList)):
            for j in range(i):
                if self.strList[i] < self.strList[j]:
                    temp = self.strList[i]
                    self.strList[i] = self.strList[j]
                    self.strList[j] = temp
开始计算最短边
    def start(self):
        flag = 'true'
        # 初始化其他有向边的权重
        for i in range(self.node_num-1):
            for edge in self.edges:
                # 松弛逼近,不断地选择一条边,做松弛改进操作,直到得出正确的解答
                if self.dicts[edge['end']] > self.dicts[edge['start']] + edge['weight']:
                    self.dicts[edge['end']] = self.dicts[edge['start']] + edge['weight']
            temp = self.dicts.copy()
            self.dictsList.append(temp)

        for edge in self.edges:
            #判断是否存在负权回路的情况
            if self.dicts[edge['end']] > self.dicts[edge['start']] + edge['weight']:
                flag = 'false'
                break

        return {
            'dictsList':self.dictsList,
            'flag':flag
        }
调用算法类
if __name__ == "__main__":
	#Input格式:Nodenumber;startedvertex;edge,edge,weight;edge,edge,weight;…
    inp = input()
    inplist = inp.split(';')
    bf = None
    for i in range(len(inplist)):
        if i == 1:
            bf = Bellman_ford(node_num=int(inplist[0]), startedvertex=inplist[1])
        elif i > 1:
            inpstr = inplist[i].split(',')
            bf.add(start=inpstr[0],end=inpstr[1],weight=int(inpstr[2]))
    bf.init()
    rt = bf.start()
    #Output格式:node;node;node;…… distance;distance;distance;....... distance;distance;distance;.......如果為無限,輸出 inf (例如 : 0;8;2;inf;inf)
    print(";".join(["%s" %bf.strList[i] for i in range(len(bf.strList))]))
    for i in range(len(rt['dictsList'])):
        print(";".join(["%s" % rt['dictsList'][i][bf.strList[j]] for j in range(len(bf.strList))]))
    print(rt['flag'])
### Bellman-Ford算法的C语言实现 Bellman-Ford算法用于解决单源最短路径问题,能够处理带有负权重边的情况。该算法通过逐步松弛所有边来找到从起点到其他节点的最短距离[^1]。 以下是使用C语言编写的Bellman-Ford算法的一个简单版本: ```c #include <stdio.h> #include <limits.h> // 定义图结构体 struct Edge { int src, dest, weight; }; struct Graph { int V, E; struct Edge* edge; }; void BellmanFord(struct Graph* graph, int src) { int V = graph->V; int E = graph->E; int dist[V]; // 初始化距离数组 for (int i = 0; i < V; ++i) dist[i] = INT_MAX; dist[src] = 0; // 松弛操作 for (int i = 1; i <= V - 1; ++i) { for (int j = 0; j < E; ++j) { int u = graph->edge[j].src; int v = graph->edge[j].dest; int weight = graph->edge[j].weight; if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) dist[v] = dist[u] + weight; } } // 检查是否存在负权环路 for (int i = 0; i < E; ++i) { int u = graph->edge[i].src; int v = graph->edge[i].dest; int weight = graph->edge[i].weight; if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) { printf("Graph contains negative weight cycle\n"); return; } } // 打印结果 printf("Vertex Distance from Source\n"); for (int i = 0; i < V; ++i) printf("%d \t\t %d\n", i, dist[i]); } // 辅助函数创建图形实例 struct Graph* createGraph(int V, int E) { struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph)); graph->V = V; graph->E = E; graph->edge = (struct Edge*)malloc(graph->E * sizeof(struct Edge)); return graph; } ``` 此代码片段展示了如何定义图的数据结构以及执行Bellman-Ford算法的核心逻辑。注意,在实际应用中可能还需要考虑内存管理和其他边界条件等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值