以node / link文件表征的道路网络-----dijkstra算法yyds-----基于南京公路公开数据做路径规划(中)------Python实现

从理论到实现,需要数据、需要代码、需要运气

以node / link文件表征的道路网络-----dijkstra算法yyds-----基于南京公路公开数据做路径规划(上)
基本讲清楚了最短路算法的基本原理

下面主要做几件事:
①把node和link文件导入
②把有效字段输入算法
③输出我想要的结果

核心算法如下:

import pandas as pd
import numpy as np
import seaborn as sns
sns.set(style="ticks", color_codes=True)

def dijkstra(start, adjacency_matrix):
    passed = [start]  
    nopass = [x for x in range(len(adjacency_matrix)) if x != start]  
    dis = adjacency_matrix[start]  
    
    while len(nopass):
        idx = nopass[0]
        for i in nopass:
            if dis[i] < dis[idx]:
                idx = i

        nopass.remove(idx)
        passed.append(idx)

        for i in nopass:
            if dis[idx] + adjacency_matrix[idx][i] < dis[i]:
                dis[i] = dis[idx] + adjacency_matrix[idx][i]
                route_list_index[i].append(idx)

    return dis

下面就是些导入数据之类的:

class ReadData:
    def __init__(self, node, link):  # 类属性
        self.node = 'node.csv'
        self.link = 'link.csv'

    def read_node(self):  
        self.node_list = []
        with open(self.node, "r") as fl_node:
            df_node = pd.read_csv(fl_node)
            for i in range(0, len(df_node)):
                a = Node()  
                a.node_id = df_node.loc[i, "node_id"]
                a.x = df_node.loc[i, "x_coord"]
                a.y = df_node.loc[i, "y_coord"]
                self.node_list.append(a)
        # print("读取的node结果为:")
        # print(df_node)
        # 看看数据有没有导入成功是个好习惯,后续的该类做法,就作为中间过程,不保留了
        
    def read_link(self): 
        self.link_list = []
        with open(self.link, "r") as fl_link, open(self.node, "r") as fl_node:
            df_link = pd.read_csv(fl_link)
            df_node = pd.read_csv(fl_node)
            # link_uni_lst = list(pd.unique(df_link["link_id"]))
            node_uni_lst = list(pd.unique(df_node["node_id"]))

            for i in range(0, len(df_link)):
                # print("read link", i/len(df_link))
                b = Link()  
                b.link_id = df_link.loc[i, "link_id"]
                b.length = df_link.loc[i, "length"]
                b.lanes = df_link.loc[i, "lanes"]
                b.free_speed = df_link.loc[i, "free_speed"]
                b.from_node_id = df_link.loc[i, "from_node_id"]
                b.to_node_id = df_link.loc[i, "to_node_id"]
                b.spend_time = df_link.loc[i, "length"] / (df_link.loc[i, "free_speed"]/3.6)  
                
                from_node = self.node_list[node_uni_lst.index(b.from_node_id)]
                from_node.flow_out_link.append(b.link_id)
                from_node.flow_out_node.append(b.to_node_id)

                to_node = self.node_list[node_uni_lst.index(b.to_node_id)]
                to_node.flow_in_link.append(b.link_id)
                to_node.flow_in_node.append(b.from_node_id)
                self.link_list.append(b)
    

class Node:  
    def __init__(self):
        self.node_id = None
        self.x = None
        self.y = None
        self.flow_in_link = [] 
        self.flow_out_link = []  
        self.flow_in_node = []  
        self.flow_out_node = []  


class Link:  
    def __init__(self):
        self.link_id = None
        self.length = None
        self.lanes = None
        self.free_speed = None
        self.from_node_id = None
        self.to_node_id = None
        self.spend_time = None



network = ReadData(0, 0)
print(network.read_node()) 
print(network.read_link()) 
print()

node_uni = list(pd.unique(pd.read_csv('node.txt')["node_id"]))
link_uni = list(pd.unique(pd.read_csv('link.txt')["link_id"]))
size = len(node_uni)  
dis = np.ones((size, size))*100000  
for i in range(0, len(network.link_list)):  
    dis[node_uni.index(network.link_list[i].from_node_id), node_uni.index(network.link_list[i].to_node_id)] = network.link_list[i].length

for i in range(0, size):
    dis[i, i] = 0


start_id = 5653  # 这里是起点编号
end_id = 2916 # 这里是终点编号

start_node_index = node_uni.index(start_id)  
end_node_index = node_uni.index(end_id)
route_list_index = [[] for i in range(0, size)]  
route_list_id = [] 
distance_list = dijkstra(start_node_index, dis)  
k = route_list_index[end_node_index][0]

while k != start_node_index:
    print(node_uni[k])
    route_list_id.append(node_uni[k])
    if len(route_list_index[k]) != 0:
        k = route_list_index[k][0]
    else:
        k = start_node_index
route_list_id.append(start_id)
route_list_id.reverse()
route_list_id.append(end_id)

至此算法运算结束
那就输出我们想要的结果吧:

print('起点标号:', start_id, ',在储存结构中的索引:', start_node_index)
print('终点标号:', end_id, ',在储存结构中的索引:', end_node_index)
#print('两点之间的距离为', distance_list[end_node_index], '米')
print('两点之间的路径为', route_list_id)

在这里插入图片描述
完事儿
下一篇讲我和代码的辛酸故事,代码复现不了的原因,或许在后面
在这里插入图片描述

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值