【上篇】Python实现最短路问题常见求解算法——Label Correcting Algorithm(deque)

news/2024/12/14 14:39:45/

基于python语言,实现deque label correcting 算法对最短路问题(Shortest Path Problem)进行求解。

目录

  • 1. 适用场景
  • 2. 算法说明
  • 3. 测试网络
  • 4. 代码实现
  • 5. 求解结果
  • 6. 代码及数据文件
  • 参考

1. 适用场景

  • 无负环网络
  • 起点与终点间至少存在一条可行路径
  • 可求解单一起点到多点的最短路径

2. 算法说明

应用标号法求解最短路问题时有两种选择,一是采用 label setting 策略,即 label setting algorithm,如经典的 Dijkstra’s algorithm ,或采用label correcting策略,即 label correcting algorithm,如经典的 FIFO label correcting algorithmDeque label correcting algorithm。二者在最短路问题上都表现出较好的效率,但与 label setting algorithm算法相比,label correcting algorithm 算法更为灵活,易于扩展,且可以检测出含有负环的网络本文采用python语言实现Deque label correcting algorithm 对不含负环网络的最短路问题进行求解。对于含有负环网络的最短路问题将在后续文章分享。

3. 测试网络

这里以Tempe ASU网络为测试数据集,网络如下图所示,可通过osm2gmns工具包获取。
在这里插入图片描述

4. 代码实现

(1)定义网络数据结构

# define network data struct
class Network():def __init__(self):self.node_neighbors={}self.node_x_coord={}self.node_y_coord={}self.node_id_list=[]self.number_of_nodes=0self.link_cost={}self.link_list=[]self.source_node_id=0self.sink_node_id=1

(2)读取网络文件

# read network csv files
def read_network_file(node_file,link_file,network):# read node csv filewith open(node_file) as node_f:node_reader=csv.reader(node_f)next(node_reader)for row in node_reader:network.node_id_list.append(int(row[0]))network.node_x_coord[int(row[0])] = float(row[1])network.node_y_coord[int(row[0])] = float(row[2])network.node_neighbors[int(row[0])] = []# read link csv filewith open(link_file) as f:link_reader = csv.reader(f)next(link_reader)for row in link_reader:from_node_id = int(row[1])to_node_id = int(row[2])cost = float(row[3])network.node_neighbors[from_node_id].append(to_node_id)network.link_list.append([from_node_id, to_node_id])network.link_cost[from_node_id, to_node_id] = costnetwork.number_of_nodes = len(network.node_id_list)return network

(3)可视化最短路径

def show_shortest_path(net,path_node_id_list):for from_node_id,to_node_id in net.link_list:x_coords=[net.node_x_coord[from_node_id],net.node_x_coord[to_node_id]]y_coords=[net.node_y_coord[from_node_id],net.node_y_coord[to_node_id]]plt.plot(x_coords,y_coords,color='black',linewidth=0.5)path_x_coord=[]path_y_coord=[]for node_id in path_node_id_list:path_x_coord.append(net.node_x_coord[node_id])path_y_coord.append(net.node_y_coord[node_id])plt.plot(path_x_coord,path_y_coord,color='b')plt.xlabel('x_coord')plt.ylabel('y_coord')plt.show()

(4)保存最短路径信息

# save the shortest path information to csv file
def save_to_file(network,path_node_id_list,path_cost,node_predecessor=None,node_label_cost=None):outfile = open('shortest_path.csv', 'w', newline='', errors='ignore')write = csv.writer(outfile)write.writerow(['source_node_id', 'sink_node_id', 'total cost', 'path node id list'])path = '-'.join([str(i) for i in path_node_id_list])line = [network.source_node_id, network.sink_node_id,path_cost,path]write.writerow(line)# whether save the shortest path information from  the source node to other nodesif node_predecessor and node_label_cost:try:for node_id in network.node_id_list:if node_id!=network.source_node_id and node_id!=network.sink_node_id:path_node_id_list = [node_id]pre_node_id = node_predecessor[node_id]path_cost = 0if node_label_cost[node_id]<float('inf'):while pre_node_id != network.source_node_id:path_node_id_list.insert(0, pre_node_id)path_cost += network.link_cost[path_node_id_list[0], path_node_id_list[1]]pre_node_id = node_predecessor[pre_node_id]path_node_id_list.insert(0, network.source_node_id)path_cost += network.link_cost[path_node_id_list[0], path_node_id_list[1]]path = '-'.join([str(i) for i in path_node_id_list])line = [network.source_node_id, node_id, path_cost, path]write.writerow(line)else:line = [network.source_node_id, node_id, 'inf', 'nan']write.writerow(line)except Exception as e:passoutfile.close()

(5)采用label correcting算法的deque实现寻找最短路径

# find the shortest path from source node to sink node using deque label correcting algorithm
def find_shortest_path(network):node_predecessor = {}node_predecessor[network.source_node_id]=Nonenode_label_cost = { node_id:float('inf') for node_id in network.node_id_list}node_label_cost[network.source_node_id] = 0SEList = deque()SEList_all = []SEList.append(network.source_node_id)SEList_all.append(network.source_node_id)while len(SEList)>0:current_node_id=SEList[0]SEList.popleft()current_node_label_cost = node_label_cost[current_node_id]for to_node_id in network.node_neighbors[current_node_id]:new_label=current_node_label_cost+network.link_cost[current_node_id,to_node_id]if new_label<node_label_cost[to_node_id]:node_label_cost[to_node_id]=new_labelnode_predecessor[to_node_id]=current_node_idif to_node_id in SEList_all:SEList.insert(0,to_node_id)else:SEList.append(to_node_id)SEList_all.append(to_node_id)path_node_id_list = [network.sink_node_id]pre_node_id = node_predecessor[network.sink_node_id]path_cost = 0if node_label_cost[network.sink_node_id]<float('inf'):while pre_node_id != network.source_node_id:path_node_id_list.insert(0, pre_node_id)path_cost += network.link_cost[path_node_id_list[0], path_node_id_list[1]]pre_node_id = node_predecessor[pre_node_id]path_node_id_list.insert(0, network.source_node_id)path_cost += network.link_cost[path_node_id_list[0], path_node_id_list[1]]path = '-'.join([str(i) for i in path_node_id_list])print("the trave cost from node id=%s to node id=%s is: %s" % (network.source_node_id, network.sink_node_id, path_cost))print("the shortest path from node id=%s to node id=%s is: %s" % (network.source_node_id, network.sink_node_id, path))show_shortest_path(network, path_node_id_list)save_to_file(network, path_node_id_list, path_cost,node_predecessor,node_label_cost)else:print("there is no feasible path from node id=%s to node id=%s"%(network.source_node_id,network.sink_node_id))

(6)主程序

if __name__=='__main__':# init network data structnetwork=Network()# setting source node  id and sink node idnetwork.source_node_id=4177network.sink_node_id=3881# read network filesread_network_file('./node.csv','./link.csv',network)# check whether the source node id and sink node id is in the networkif network.source_node_id not in network.node_id_list:print(" %s not found"%network.source_node_id)sys.exit(0)if network.sink_node_id not in network.node_id_list:print(" %s not found"%network.sink_node_id)sys.exit(0)# find the shortest pathfind_shortest_path(network)

5. 求解结果

在这里插入图片描述

6. 代码及数据文件

相关代码及数据文件可从github主页获取:

https://github.com/PariseC/Shortest_Path_Algorithm/tree/master/label_correcting_algorithm

参考

  1. R.K. Ahuja, T.L. Magnanti and J.B. Orlin, Network Flows: Theory, Algorithms, and Applications. Prentice-Hall, 1993. A comprehensive recent survey of the topic.

http://www.ppmy.cn/news/628648.html

相关文章

ECC校验——汉明码(Hamming Code)

本文参考板块与链接&#xff1a; https://en.wikipedia.org/wiki/Hamming_code #wiki英文版 https://zh.wikipedia.org/wiki/%E6%B1%89%E6%98%8E%E7%A0%81 #wiki中文版 前言 本文主旨意在讲清如何根据原理构造常用的汉明码&#xff0c;鉴于本人在网络查阅资料过程翻阅大量低效/…

Unable to find a single main class from the following candidates 问题解决

背景 maven父子工程间引用打包,产生的异常 [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.1.12.RELEASE:repackage (repackage) on project shop-common: Execution repackage of goal org.springfr amework.boot:spring-boot-maven-pl…

Selective Search for Object Recognition

最近被老师弄去做图像方向,完全没相关经验,都是从论文看起。之后会整理我看的一系列论文,可能会有很多错误的地方,如果有发现,欢迎提出! 很多人问要代码,在文章结尾有分享。 Selective Search for Object Recognition 是J.R.R. Uijlings发表在2012 IJCV上的一篇文章。…

Flutter Error: The method ‘inheritFromWidgetOfExactType‘ isn‘t defined for the class ‘BuildContext‘.

异常 Androidstudio 编译运行导入别人的Flutter项目时报错&#xff0c;具体异常信息&#xff1a; D:/IDE/Flutter_windows_2.0.0-stable/flutter/.pub-cache/hosted/pub.flutter-io.cn/flutter_redux-0.5.4/lib/flutter_redux.dart:77:19: Error: The method inheritFromWidg…

Correcting Chinese Spelling Errors with Phonetic Pre-training

语音预习矫正汉语拼写错误 张瑞清&#xff0c;庞超&#xff0c;张传强&#xff0c;王朔欢&#xff0c;何忠军、孙宇、吴华和海峰[1] 百度公司。中国北京上地10号街10号&#xff0c;100085{张瑞青奥尔&#xff0c;庞曹04&#xff0c;张川强&#xff0c;王寿环}http://baidu.co…

When Color Constancy Goes Wrong:Correcting Improperly White-Balanced Images阅读札记

When Color Constancy Goes Wrong: Correcting Improperly White-Balanced Images 阅读札记 论文发表于2019年的CVPR。 Abstract 本文方法主要解决校正白平衡不当的图像问题。校正白平衡不当问题真正难点不在于确定正确的白平衡是什么&#xff0c;而在于以下事实&#xff1a;相…

flutter2.1升级flutter3.0

下载最新fluttert版本 for github 升级kotlin版本 及 gradle版本 Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15. Failed to apply plugin ‘kotlin-android’. [ 4 ms] > The …

Correcting Over-Exposure in Photographs阅读札记

Correcting Over-Exposure in Photographs 阅读札记 论文发表于2010年的CVPR。 Abstract 本文方法通过分别恢复颜色和亮度来校正现有照片的曝光过度。 步骤&#xff1a;   &#xff08;1&#xff09;稍微压缩曝光良好区域的动态范围&#xff0c;为过度曝光区域的动态范围腾出…