[Python3]Bellman-Ford的实现及Yen式优化

2023-10-07 20:50

本文主要是介绍[Python3]Bellman-Ford的实现及Yen式优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原理分析见本人Github:

https://github.com/youhengchan/Yen-Bellman-Ford/blob/master/group2_ppt_yen.pdf

测试数据:

原始算法:

伪代码:

实现:

import timegraph_size = 10
counter = 0class Edge:def __init__(self, u, v, w):self.u = uself.v = vself.w = wdef recursive_print(dis, pre):global graph_sizedef print_helper(index, destination):if pre[index] == index:print("Route : {} -> ".format(index), end="")returnprint_helper(pre[index], destination)if index == destination:print("{} Distance = {}".format(destination, dis[destination]), end="")else:print("{} -> ".format(index), end="")for i in range(graph_size):if pre[i] == i:print("Route : {} Distance = 0".format(i), end="")else:print_helper(i, i)print("")def bellman_ford(edges, source):global graph_size, counterbegin = time.perf_counter()dis = []  # distance from source to the nodepre = []  # predecessor of nodeerror = Falsefor i in range(graph_size):dis.append(float('inf'))pre.append(i)dis[source] = 0# Initialize the graphfor i in range(graph_size - 1):   # |V| - 1 timescounter += 1# change = Falsefor edge in edges:if dis[edge.u] != float("inf") and dis[edge.v] > (dis[edge.u] + edge.w):dis[edge.v] = dis[edge.u] + edge.wpre[edge.v] = edge.u# change = True# if not change:#     break# check for the negative-weight cyclefor edge in edges:if (dis[edge.u] + edge.w) < dis[edge.v]:print("dis[{}] ({}) < dis[{}] ({}) + {}".format(edge.u, dis[edge.u], edge.v, dis[edge.v], edge.w))error = Trueend = time.perf_counter()return error, dis, pre, end-begindef main():global counteredges = []edges.append(Edge(0, 9, 9))edges.append(Edge(0, 2, 3))edges.append(Edge(0, 5, 5))edges.append(Edge(7, 9, 2))edges.append(Edge(7, 3, 0))edges.append(Edge(2, 7, 1))edges.append(Edge(9, 4, 3))edges.append(Edge(3, 4, 2))edges.append(Edge(3, 8, 1))edges.append(Edge(8, 2, 8))edges.append(Edge(8, 6, 2))edges.append(Edge(4, 8, -8))edges.append(Edge(6, 1, 0))edges.append(Edge(5, 1, 2))edges.append(Edge(1, 4, 9))err, dis, pre, time_consumption = bellman_ford(edges, 0)if err:print("Negative-weight cycle exist")else:print("Time consumption = ", time_consumption)recursive_print(dis, pre)print("Counter = ", counter)if __name__ == "__main__":main()

运行结果:

Yen氏优化:

伪代码:

实现:

import time
graph_size = 10
counter = 0class Edge:def __init__(self, u, v, w):self.u = uself.v = vself.w = wdef recursive_print(dis, pre):global graph_sizedef print_helper(index, destination):if pre[index] == index:print("Route : {} -> ".format(index), end="")returnprint_helper(pre[index], destination)if index == destination:print("{} Distance = {}".format(destination, dis[destination]), end="")else:print("{} -> ".format(index), end="")for i in range(graph_size):if pre[i] == i:print("Route : {} Distance = 0".format(i), end="")else:print_helper(i, i)print("")def yen_bellman_ford(edges, edge_plus, edge_minus, source):begin = time.perf_counter()global graph_size, counterdis = []  # distance from source to the nodepre = []  # predecessor of nodeerror = Falsefor i in range(graph_size):dis.append(float('inf'))pre.append(i)dis[source] = 0# Initialize the graphfor i in range(graph_size - 1):   # |V| - 1 timescounter += 1change = Falsefor edge in edge_plus:if dis[edge.u] != float("inf") and dis[edge.v] > (dis[edge.u] + edge.w):dis[edge.v] = dis[edge.u] + edge.wpre[edge.v] = edge.uchange = Truefor edge in edge_minus:if dis[edge.u] != float("inf") and dis[edge.v] > (dis[edge.u] + edge.w):dis[edge.v] = dis[edge.u] + edge.wpre[edge.v] = edge.uchange = Trueif not change:break# check for the negative-weight cyclefor edge in edges:if (dis[edge.u] + edge.w) < dis[edge.v]:print("dis[{}] ({}) < dis[{}] ({}) + {}".format(edge.u, dis[edge.u], edge.v, dis[edge.v], edge.w))error = Trueend = time.perf_counter()return error, dis, pre, end-begindef main():edges = []edge_plus = []edge_minus = []edge_plus.append(Edge(0, 2, 3))edge_plus.append(Edge(0, 5, 5))edge_plus.append(Edge(0, 9, 9))edge_plus.append(Edge(1, 4, 9))edge_plus.append(Edge(2, 7, 1))edge_plus.append(Edge(3, 4, 2))edge_plus.append(Edge(3, 8, 1))edge_plus.append(Edge(4, 5, 0))edge_plus.append(Edge(4, 8, -8))edge_plus.append(Edge(7, 9, 2))edge_minus.append(Edge(9, 4, 3))edge_minus.append(Edge(8, 6, 2))edge_minus.append(Edge(8, 2, 8))edge_minus.append(Edge(7, 3, 0))edge_minus.append(Edge(6, 1, 0))edge_minus.append(Edge(5, 1, 2))edges.extend(edge_minus)edges.extend(edge_plus)err, dis, pre, time_consumption = yen_bellman_ford(edges, edge_plus, edge_minus, 0)if err:print("Negative-weight cycle exist")else:print("Time consumption = ", time_consumption)recursive_print(dis, pre)print("Counter = ", counter)if __name__ == "__main__":main()

运行结果:

这篇关于[Python3]Bellman-Ford的实现及Yen式优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/160366

相关文章

SpringBoot基于沙箱环境实现支付宝支付教程

《SpringBoot基于沙箱环境实现支付宝支付教程》本文介绍了如何使用支付宝沙箱环境进行开发测试,包括沙箱环境的介绍、准备步骤、在SpringBoot项目中结合支付宝沙箱进行支付接口的实现与测试... 目录一、支付宝沙箱环境介绍二、沙箱环境准备2.1 注册入驻支付宝开放平台2.2 配置沙箱环境2.3 沙箱

Nginx实现高并发的项目实践

《Nginx实现高并发的项目实践》本文主要介绍了Nginx实现高并发的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用最新稳定版本的Nginx合理配置工作进程(workers)配置工作进程连接数(worker_co

python中列表list切分的实现

《python中列表list切分的实现》列表是Python中最常用的数据结构之一,经常需要对列表进行切分操作,本文主要介绍了python中列表list切分的实现,文中通过示例代码介绍的非常详细,对大家... 目录一、列表切片的基本用法1.1 基本切片操作1.2 切片的负索引1.3 切片的省略二、列表切分的高

基于Python实现一个PDF特殊字体提取工具

《基于Python实现一个PDF特殊字体提取工具》在PDF文档处理场景中,我们常常需要针对特定格式的文本内容进行提取分析,本文介绍的PDF特殊字体提取器是一款基于Python开发的桌面应用程序感兴趣的... 目录一、应用背景与功能概述二、技术架构与核心组件2.1 技术选型2.2 系统架构三、核心功能实现解析

Java嵌套for循环优化方案分享

《Java嵌套for循环优化方案分享》介绍了Java中嵌套for循环的优化方法,包括减少循环次数、合并循环、使用更高效的数据结构、并行处理、预处理和缓存、算法优化、尽量减少对象创建以及本地变量优化,通... 目录Java 嵌套 for 循环优化方案1. 减少循环次数2. 合并循环3. 使用更高效的数据结构4

使用Python实现表格字段智能去重

《使用Python实现表格字段智能去重》在数据分析和处理过程中,数据清洗是一个至关重要的步骤,其中字段去重是一个常见且关键的任务,下面我们看看如何使用Python进行表格字段智能去重吧... 目录一、引言二、数据重复问题的常见场景与影响三、python在数据清洗中的优势四、基于Python的表格字段智能去重

Spring AI集成DeepSeek实现流式输出的操作方法

《SpringAI集成DeepSeek实现流式输出的操作方法》本文介绍了如何在SpringBoot中使用Sse(Server-SentEvents)技术实现流式输出,后端使用SpringMVC中的S... 目录一、后端代码二、前端代码三、运行项目小天有话说题外话参考资料前面一篇文章我们实现了《Spring

Nginx中location实现多条件匹配的方法详解

《Nginx中location实现多条件匹配的方法详解》在Nginx中,location指令用于匹配请求的URI,虽然location本身是基于单一匹配规则的,但可以通过多种方式实现多个条件的匹配逻辑... 目录1. 概述2. 实现多条件匹配的方式2.1 使用多个 location 块2.2 使用正则表达式

使用Apache POI在Java中实现Excel单元格的合并

《使用ApachePOI在Java中实现Excel单元格的合并》在日常工作中,Excel是一个不可或缺的工具,尤其是在处理大量数据时,本文将介绍如何使用ApachePOI库在Java中实现Excel... 目录工具类介绍工具类代码调用示例依赖配置总结在日常工作中,Excel 是一个不可或缺的工http://

SpringBoot实现导出复杂对象到Excel文件

《SpringBoot实现导出复杂对象到Excel文件》这篇文章主要为大家详细介绍了如何使用Hutool和EasyExcel两种方式来实现在SpringBoot项目中导出复杂对象到Excel文件,需要... 在Spring Boot项目中导出复杂对象到Excel文件,可以利用Hutool或EasyExcel