Python实现最短路问题常见求解算法——A*算法

转载链接
路径规划之 A 算法*
https://developer.aliyun.com/article/685477
https://www.redblobgames.com/pathfinding/a-star/introduction.html

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

1. 适用场景

  • 无负环网络
  • 起点与终点间至少存在一条可行路径

2. 测试网络

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

3. 代码实现

(1)定义数据结构

class Network():
    def __init__(self):
        self.source_node_id=None
        self.sink_node_id=None

        self.node_id_list=[]
        self.node_x_coord={}
        self.node_y_coord={}
        self.node_neighbors={}
        self.number_of_nodes=0
        self.link_list=[]
        self.link_cost={}

(2)读取csv网络文件

node.csv
在这里插入图片描述
link.csv
在这里插入图片描述

def read_data(node_file,link_file,net):
    #读取node文件
    with open(node_file) as f:
        node_reader = csv.reader(f)
        next(node_reader)
        for row in node_reader:
            net.node_id_list.append(int(row[0]))
            net.node_x_coord[int(row[0])]=float(row[1])
            net.node_y_coord[int(row[0])]=float(row[2])
            net.node_neighbors[int(row[0])]=[]
    #读取link文件
    with 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])
            net.node_neighbors[from_node_id].append(to_node_id)
            net.link_list.append([from_node_id,to_node_id])
            net.link_cost[from_node_id,to_node_id]=cost
    net.number_of_nodes=len(net.node_id_list)

(3)评估函数

def evaluate_remaining_distance(current,net):
    return abs(net.node_x_coord[current]-net.node_x_coord[net.sink_node_id])\
           +abs(net.node_y_coord[current]-net.node_y_coord[net.sink_node_id])

(4)最短路径可视化函数

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()

(5)最短路搜索

def find_shortest_path(net):
    frontier = PriorityQueue()
    frontier.put((net.source_node_id,0))
    came_from = {}
    cost_so_far = {}
    came_from[net.source_node_id] = None
    cost_so_far[net.source_node_id] = 0

    while not frontier.empty():
        current=frontier.get()[0]

        if current == net.sink_node_id:
            break

        for next_node in net.node_neighbors[current]:
            new_cost = cost_so_far[current] + net.link_cost[current, next_node]
            if next_node not in cost_so_far or new_cost < cost_so_far[next_node]:
                cost_so_far[next_node] = new_cost
                priority = new_cost + evaluate_remaining_distance(next_node,net)
                frontier.put((next_node,priority))
                came_from[next_node] = current

    path_node_id_list=[net.sink_node_id]
    pre_node_id=came_from[net.sink_node_id]
    path_cost=0
    while pre_node_id!=net.source_node_id:
        path_node_id_list.insert(0,pre_node_id)
        path_cost+=net.link_cost[path_node_id_list[0],path_node_id_list[1]]
        pre_node_id=came_from[pre_node_id]
    path_node_id_list.insert(0,net.source_node_id)
    path_cost += net.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"%(net.source_node_id,net.sink_node_id,path_cost))
    print("the shortest path from node id=%s to node id=%s is: %s"%(net.source_node_id,net.sink_node_id,path))

    show_shortest_path(net,path_node_id_list)

(6)主函数

if __name__=='__main__':
    net=Network()
    net.source_node_id=4298
    net.sink_node_id=169
    read_data('./node.csv','./link.csv',net)

    if net.source_node_id not in net.node_id_list:
        print(" %s not found"%net.source_node_id)
        sys.exit(0)
    if net.sink_node_id not in net.node_id_list:
        print(" %s not found"%net.sink_node_id)
        sys.exit(0)

    find_shortest_path(net)

(7)求解结果

在这里插入图片描述

(8)样例数据集代码文件

https://github.com/PariseC/Shortest_Path_Algorithm/tree/master/A%20star

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,可以使用networkx库来求解最短路径问题。其中,网络图G可以使用networkx.Graph()来创建。最短路径问题有两种求解方式:每对顶点间的最短路和固定起点到其余各点的最短路。 1. 每对顶点间的最短路: 可以使用networkx库中的shortest_path函数来求解。该函数的参数包括:图G、起点source、终点target、权重weight和求解方法method。例如,可以使用shortest_path(G, source, target, weight, method)来求解每对顶点间的最短路径。 2. 固定起点到其余各点的最短路: 可以使用Dijkstra算法求解固定起点到其余各点的最短路径。在networkx库中,可以使用shortest_path_length函数来实现。该函数的参数与shortest_path函数类似,包括:图G、起点source、终点target、权重weight和求解方法method。例如,可以使用shortest_path_length(G, source, target, weight, method)来求解固定起点到其余各点的最短路径。 需要注意的是,要最短路径问题前,需要加载networkx库,并创建网络图G。此外,还需要提供图的顶点信息、权重信息等参数,以便求解最短路径问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [数学建模:图论模型 — 最短路问题Python 求解](https://blog.csdn.net/qq_55851911/article/details/124776077)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值