[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

相关文章

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控