基于Dijkstra算法的最短路径问题的解决
ki帛2024/07/23软件综合数学 IP:重庆

        在日常生活中,我们可能会遇到像导航路线选择的问题.这时我们就需要从诸多路径中选择最短的一条.

为了解决此类问题我们需要引入一个概念——图.

图-1.png (图-1)

如图-1,这就是一个图.图中的每一个节点叫作顶点,连接两个顶点的线段叫作.当然,有一些图中由顶点指向顶点的边是有向的(比如该图)叫作有向图,也有的图由顶点指向顶点的边是无向的叫作无向图.图中的每一条边都可以有一个权值$f$,比如图中BD边的权值就可记作$f_{BD} = 5$.

若将图描述为一个集合$G$,那么则有

$$V,E\subset\\G$$(1)

其中$V,E$分别为点集和边集,他们都是$G$的子集.

尽然了解了图的概念,我们将讲解一下Dijkstra算法.

参照百度百科对Dijkstra算法的介绍:迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题.迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止.

设带权图$G = (V,E)$,求v到其它点的最短路径.开一个二维列表Weight作为边的权值,d[i]为点的值(初始为无穷大).sign[i]为标记列表,数值类型为bool,初始为False.

大致步骤如下:

  1. d[v] = 0,sign[v] = True

  2. 对当前已确定的点i,寻找所有未确定的点j,若边<i,j>存在则进行松弛操作d[j] < d[i] + Weight[i][j]

  3. 确定i和d[i].即对所有为未打上标记的点j,枚举找出最小的点d[j],令sign[j] = True.

    重复2、3步骤直到所有的点都被确定为止.

    显然,理想情况下上述算法的时间复杂度为$O(n^2)$

    以下是我用python编写的测试代码:


import openpyxl
import heapq

def read_graph_from_excel(filepath):
    workbook = openpyxl.load_workbook(filepath)
    sheet = workbook.active
    graph = {}
   
    for row in sheet.iter_rows(min_row=3, values_only=True):  # Start from row 3 now, since we skip the first two rows
        node1, node2, weight = row[0], row[1], row[2]
        if node1 not in graph:
            graph[node1] = []
        if node2 not in graph:
            graph[node2] = []
        graph[node1].append((node2, weight))
        graph[node2].append((node1, weight))  # Assuming an undirected graph
   
    return graph

def dijkstra(graph, start):
    distances = {vertex: float('infinity') for vertex in graph}
    distances[start] = 0
    pq = []  # Priority queue
    for neighbor, weight in graph[start]:
        heapq.heappush(pq, (0, neighbor))  # Set initial distance to 0 for neighbors of start node
    while pq:
        current_distance, current_vertex = heapq.heappop(pq)
       
        if current_distance > distances[current_vertex]:
            continue
       
        for neighbor, weight in graph[current_vertex]:
            distance = current_distance + weight
           
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(pq, (distance, neighbor))
   
    return distances

# Read the graph from Excel
file_path = r"C:\Users\Administrator\Desktop\new1\s.xlsx"
graph = read_graph_from_excel(file_path)

# Run Dijkstra algorithm
start_node = 1  # Change this to match the first node in your Excel file
distances = dijkstra(graph, start_node)

# Print the results
for node, distance in distances.items():
    if node != start_node:
        print(f"Shortest path to node {node}: {distance}")

程序保存在C:\Users\Administrator\Desktop\new2目录下的s1.xlsx文件作为输入(不知道为啥我一用相对路径就报错,所以我选择了绝对路径😂),xlsx文件的A列用来保存原顶点,B列用来保存与其连接的顶点,C列用来保存权值.测试的图如下:

无标题.png (图-2)

结果为

Shortest path to node 2: 3
Shortest path to node 3: 6
Shortest path to node 4: 5
Shortest path to node 5: 7
Shortest path to node 1: 2


来自:计算机科学 / 软件综合数理化 / 数学
1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
chenruixi
5个月1天前 IP:湖南
934499

Lz显然没有认真思考,而且闲的蛋疼

看到贪心和图,不应该先用归纳法证明一下么

代码也是浓浓的GPT味,换成我,函数括号里肯定不写空格,而且不会用邻接表(不过Python好像没结构体)。


引用
评论(1)
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

ki帛
进士 机友 笔友
文章
2
回复
30
学术分
0
2022/11/24注册,2时11分前活动

技术型《学渣》

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:重庆
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}