迪杰斯特拉(Dijkstra)

参考:https://www.jianshu.com/p/ff6db00ad866

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。
它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

大概就是这样一个有权图,Dijkstra算法可以计算任意节点其他节点的最短路径

 

算法思路

  1. 指定一个节点,例如我们要计算 'A' 到其他节点的最短路径
  2. 引入两个集合(S、U),S集合包含已求出的最短路径的点(以及相应的最短长度),U集合包含未求出最短路径的点(以及A到该点的路径,注意 如上图所示,A->C由于没有直接相连 初始时为∞
  3. 初始化两个集合,S集合初始时 只有当前要计算的节点,A->A = 0
    U集合初始时为 A->B = 4, A->C = ∞, A->D = 2, A->E = ∞敲黑板!!!接下来要进行核心两步骤了
  4. 从U集合中找出路径最短的点,加入S集合,例如 A->D = 2
  5. 更新U集合路径,if ( 'D 到 B,C,E 的距离' + 'AD 距离' < 'A 到 B,C,E 的距离' ) 则更新U
  6. 循环执行 4、5 两步骤,直至遍历结束,得到A 到其他节点的最短路径

算法图解

 

 

1.选定A节点并初始化,如上述步骤3所示

2.执行上述 4、5两步骤,找出U集合中路径最短的节点D 加入S集合,并根据条件 if ( 'D 到 B,C,E 的距离' + 'AD 距离' < 'A 到 B,C,E 的距离' ) 来更新U集合

 

3.这时候 A->B, A->C 都为3,没关系。其实这时候他俩都是最短距离,如果从算法逻辑来讲的话,会先取到B点。而这个时候 if 条件变成了 if ( 'B 到 C,E 的距离' + 'AB 距离' < 'A 到 C,E 的距离' )如图所示这时候A->B距离 其实为 A->D->B

 

  1. 思路就是这样,往后就是大同小异了

  1. 算法结束



#include<stdio.h>
#include<stdlib.h>
#define max1 10000000  //原词条这里的值太大,导致溢出,后面比较大小时会出错
int a[1000][1000];
int d[1000];//d表示源节点到该节点的最小距离
int p[1000];//p标记访问过的节点
int i, j, k;
int m;//m代表边数
int n;//n代表点数
int main()
{
    scanf("%d%d",&n,&m);
    int    min1;
    int    x,y,z;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        a[x][y]=z;
        a[y][x]=z;
    }
    for( i=1; i<=n; i++)
        d[i]=max1;
    d[1]=0;
    for(i=1;i<=n;i++)
    {
        min1 = max1;
        //下面这个for循环的功能类似冒泡排序,目的是找到未访问节点中d[j]值最小的那个节点,
        //作为下一个访问节点,用k标记
        for(j=1;j<=n;j++)
            if(!p[j]&&d[j]<min1)
            {
                min1=d[j];
                k=j;
            }
        //p[k]=d[k]; // 这是原来的代码,用下一 条代码替代。初始时,执行到这里k=1,而d[1]=0
       //从而p[1]等于0,这样的话,上面的循环在之后的每次执行之后,k还是等于1。
        p[k] = 1; //置1表示第k个节点已经访问过了
        for(j=1;j<=n;j++)
            if(a[k][j]!=0&&!p[j]&&d[j]>d[k]+a[k][j])
                d[j]=d[k]+a[k][j];
    }
    //最终输出从源节点到其他每个节点的最小距离
    for(i=1;i<n;i++)
        printf("%d->",d[i]);
    printf("%d\n",d[n]); 
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您介绍一下Dijkstra算法的具体步骤,并提供一份实现该算法的Python代码。 Dijkstra算法是一种用于解决单源最短路径问题的贪心算法,通过不断从未确定最短路径的节点集合中选取距离最短的节点来求解最短路径。 具体步骤如下: 1. 初始化 - 将起点的距离设为0,将所有其他节点的距离设为无穷大。 - 将起点标记为已访问,将其加入已确定最短路径的节点集合中。 2. 更新距离 - 遍历起点的所有邻居节点,计算起点到这些节点的距离,并将这些距离与当前记录的距离进行比较。如果计算出来的距离更短,则更新距离。 - 从未确定最短路径的节点集合中选取距离最短的节点,将其标记为已访问,并将其加入已确定最短路径的节点集合中。 3. 重复第二步,直到所有节点都被访问过。 下面是一份用Python实现Dijkstra算法的代码,代码中包含了关于上述步骤的详细注释。 ```python import heapq # 构建图(邻接矩阵表示法) graph = [ [0, 2, 1, 4, 5], [2, 0, 4, 2, 3], [1, 4, 0, 1, 2], [4, 2, 1, 0, 1], [5, 3, 2, 1, 0] ] # 起点 start = 0 # 记录起点到其他节点的最短距离 distances = {i: float('inf') for i in range(len(graph))} distances[start] = 0 # 记录路径 paths = {start: []} # 记录已访问的节点 visited = set() # 优先队列(堆)用于选取距离最短的节点 pq = [(0, start)] while pq: (distance, current_node) = heapq.heappop(pq) # 如果当前节点已访问,跳过 if current_node in visited: continue # 标记当前节点为已访问 visited.add(current_node) # 遍历邻居节点 for neighbor, weight in enumerate(graph[current_node]): if weight > 0: # 计算起点到邻居节点的距离 distance_to_neighbor = distance + weight # 如果计算出来的距离比当前记录的距离更短,更新距离和路径 if distance_to_neighbor < distances[neighbor]: distances[neighbor] = distance_to_neighbor paths[neighbor] = paths[current_node] + [current_node] # 将邻居节点加入优先队列 heapq.heappush(pq, (distance_to_neighbor, neighbor)) # 打印输出结果 for i in range(len(graph)): print('起点:{},终点:{},途经城市:{},最短路径长度:{}'.format( start, i, paths[i] + [i], distances[i] )) ``` 希望能对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值