算法笔记-动态规划-最短路径迪杰斯特拉算法

作者:星河滚烫兮


前言

  图的最短路径问题在现实生活中有很广阔的应用,最短路径又分为单源最短路径与多源最短路径,前者求出固定起点到其他节点的最短路径,后者求出可变起点到其他节点的最短路径。同时,又有多种思想来求解,比如贪心算法与动态规划求解最短路径,前者求得局部最优解,时间复杂度与空间复杂度低代价小,被广泛应用;后者求得全局最优解,但时间复杂度与空间复杂度相对高,本文迪杰斯特拉算法便是动态规划思想。
  迪杰斯特拉算法设置动态规划数组dp,根据最优化策略进行状态转移,更新dp数组(保存状态)。该算法描述与过程均放在代码注释中,大家结合代码与注释学习。


以下是代码使用的图示例:

C代码

/*这里我们关心算法的实现而淡化图这种数据结构的表示,所以我们这里用简化的邻接矩阵表示邻接矩阵G与dp数组我们定义为全局变量(在写大型工程时不要这么做)由于我们将两个dp数组设置为定长,增加了判断-1的时间,所以我们程序的时间复杂度达到了O(n3),可以把两个dp数组设置为变长则缩短至O(n2),大家可以自己动手试试
*/
#include<stdio.h>
#include<stdlib.h>              // 使用malloc函数
#define INFINITY 65535           // 定义正无穷
#define MAXSIZE 10              // 定义最大节点数
enum Nodes{A, B, C, D, E};      // 令A,B,C,D,E作为常量,分别等于邻接矩阵下标0,1,2,3,4typedef struct{int matrix[MAXSIZE][MAXSIZE];int size;                  // 节点数
}Graph;     // 创建简化版邻接矩阵数据结构
typedef struct{int index;int value;
}elem;      // 模拟字典的数据结构方便函数返回键值对typedef struct{int *dp_com;        // 已确定最短路径的节点集合int *dp_row;        // 未确定最短路径的节点集合int length;
}Dp;        // 创建双dp数组数据结构
Dp dp;/*邻接矩阵初始化
*/
Graph G = {{{0,30,20,10,INFINITY},{30,0,INFINITY,10,5},{20,INFINITY,0,5,20},{10,10,5,0,10},{INFINITY,5,20,10,0}}, 5};
/* 双动态规划数组初始化
*/
void dp_Init(Graph g, int start, Dp *p)    // 注意:这里不能让指针直接指向G的某一行,因为那样操作dp时也会修改G
{int i;p->length = g.size;p->dp_com = (int *)malloc(sizeof(int)*g.size);p->dp_row = (int *)malloc(sizeof(int)*g.size);for(i=0;i<g.size;i++)p->dp_row[i] = g.matrix[start][i];                 // -1代表为空for(i=0;i<g.size;i++)p->dp_com[i] = -1;                 // -1代表为空
}
/*输出dp数组
*/
void dp_display(Dp dp)
{int i;printf("\tdp_complete:  {");for(i=0;i<G.size;i++){if(dp.dp_com[i]==INFINITY)printf("∞ ");elseprintf("%d ",dp.dp_com[i]);}printf("\b}\n");printf("\t   dp_row  :  {");for(i=0;i<G.size;i++){if(dp.dp_row[i]==INFINITY)printf("∞ ");elseprintf("%d ",dp.dp_row[i]);}printf("\b}\n");
}
/*输出邻接矩阵
*/
void GraphDisplay(Graph g)
{for(int i=0; i<g.size; i++){for(int j=0; j<g.size; j++){if(g.matrix[i][j]==INFINITY)printf("∞ ");elseprintf("%d ",g.matrix[i][j]);}printf("\n");}
}
/*获得数组最小值
*/
elem getmin(Dp dp)
{elem min={-1, INFINITY};for(int i=0; i<dp.length;i++)if(dp.dp_row[i]!=-1&&dp.dp_row[i]<min.value){min.index = i;min.value = dp.dp_row[i];}return min;
}
/*子最短路径更新
*/
void SubOptimizition(Graph g, Dp *dp)   // 动态规划子问题最优化过程:根据dp_com更新dp_row数组各元素
{for(int i=0; i<dp->length; i++){if(dp->dp_row[i]!=-1)for(int j=0; j<dp->length; j++){if(dp->dp_com[j]!=-1)     if(dp->dp_com[j]+g.matrix[j][i]<dp->dp_row[i])          // 更新row数组达到最优化过程dp->dp_row[i] = dp->dp_com[j]+g.matrix[j][i];}}
}
/*
路径规划过程:->选取当前最短子路径min(dp_row)的索引与值即键值对->用该最短子路径更新对应dp_com位置,同时该dp_row位置置为-1表示不存在为空->使用刚刚更新后的dp_com数组,最优化dp_row数组,完成状态转移->返回第一步重复,直至dp_row数组全空
*/
void PathProgram(Graph g, Dp *dp)       // 路径规划过程:选取当前最短路径min(dp_row)
{elem i = getmin(*dp);while (i.value!=INFINITY){dp->dp_com[i.index] = i.value;dp->dp_row[i.index] = -1;SubOptimizition(g,dp);i = getmin(*dp);}}int main()
{dp_Init(G,A,&dp);printf("图的邻接矩阵如下:\n");GraphDisplay(G);printf("初始时的dp数组:\n");dp_display(dp);PathProgram(G,&dp);printf("结束时的dp数组:\n");dp_display(dp);
}

>算法笔记-动态规划-最短路径迪杰斯特拉算法相关推荐

  1. 最短路径——迪杰斯特拉算法——图的数据结构

    最短路径是在工程上经常用到的概念,在这里给出了从单源点到任意顶点的迪杰斯特拉算法. 先来看看基本概念: 用代码C语言实现如下: #include<string.h>#include< ...

  2. 最短路径迪杰斯特拉算法--邻接矩阵

    一.算法介绍 迪杰斯特拉算法(解决单源最短路径) 基本思想:每次找到离源点(如1号节点)最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余所有点的最短路径. 基本步骤:1,设置标记数组bo ...

  3. 算法与数据结构(六) 迪杰斯特拉算法的最短路径(Swift版)

    上篇博客我们详细的介绍了两种经典的最小生成树的算法,本篇博客我们就来详细的讲一下最短路径的经典算法----迪杰斯特拉算法.首先我们先聊一下什么是最短路径,这个还是比较好理解的.比如我要从北京到济南,而 ...

  4. 别说了,世界那么大我想去看看!(最短路径-迪杰斯特拉算法弗洛伊德算法)

    前言: 一直想去外面的世界看看,中国城市那么多,那么美,怎么样才可以用最少的钱,最短的时间游遍我想去的城市呢?(我在做梦?不不不!迪杰斯特拉算法和弗洛伊德算法来了)      这两个算法有着广泛的用途 ...

  5. 常用算法(八)——迪杰斯特拉算法

    迪杰斯特拉算法 大纲目录 迪杰斯特拉算法 迪杰斯特拉算法 一.应用场景-最短路径问题 二.迪杰斯特拉(Dijkstra)算法介绍 三.迪杰斯特拉(Dijkstra)算法过程 四.源码 一.应用场景-最 ...

  6. dij算法堆优化_迪杰斯特拉算法(Dijkstra) (基础dij+堆优化) BY:优少

    算法实现步骤: a.初始时,只包括源点,即S = {v},v的距离为0.U包含除v以外的其他顶点,即:U ={其余顶点},若v与U中顶点u有边,则(u,v)为正常权值,若u不是v的出边邻接点,则(u, ...

  7. dij算法堆优化_迪杰斯特拉算法(Dijkstra) (基础dij+堆优化) BY:优少(示例代码)...

    算法实现步骤: a.初始时,只包括源点,即S = {v},v的距离为0.U包含除v以外的其他顶点,即:U ={其余顶点},若v与U中顶点u有边,则(u,v)为正常权值,若u不是v的出边邻接点,则(u, ...

  8. 图的最短路径--迪杰斯特拉算法 c语言

    还是按照书上的例子: 完整代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #def ...

  9. 最短路径迪杰斯特拉算法 c语言,Dijkstra第K最短路径算法

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 //运筹学之最短路径 #include #include #define M 99999 int main() { int G[100][100]; in ...

最新文章

  1. python进程执行带有参数的任务(args、kwargs)
  2. python 使用UUID库生成唯一ID
  3. java左移、右移、无符号右移
  4. 黑马程序员pink老师前端入门教程,零基础必看的JavaScript基础语法视频教程(DOM)
  5. 怎么从转移特性曲线上看dibl_「科普向」这篇让你快速搞懂IGBT的静态特性
  6. Python入门--列表,字典,元组,集合总结
  7. Idea和Eclipse快捷键对比
  8. 淘宝 卖家信用等级的图示
  9. mybatis与spring集成
  10. Unity基础案例讲解:创建小型太空射击游戏(四)
  11. python制作简单网页_怎么用python简单的制作一个网页
  12. 英文名字按首字母排序分类显示
  13. mac字体渲染精细处理
  14. OSPF的NBMA环境建立邻居及排错,理论+实战讲解,干货分享
  15. 10. JavaScript
  16. 注册服务号、订阅号流程
  17. 基于matlab的陷波滤波器设计
  18. 在2012年01月20号这一天,2345浏览器的V1.3版本出世了,又修复什么Bug?
  19. [SWPUCTF 2018]SimplePHP
  20. Proe无法保存DWG格式的问题

热门文章

  1. 思科 计算机网络 第十一章测试考试答案
  2. 深入浅出 gRPC 02:gRPC 客户端创建和调用原理
  3. 忆暖行动|“儿孙自有儿孙福,咱开开心心的就好”迟到的小幸福
  4. Web安全知识体系总结
  5. Vue实现字符串换行
  6. 魔兽世界编程宝典读书笔记(10)
  7. 最佳网络地图服务对比分析:Google Maps 与 OpenStreetMap
  8. unity 半透明混合问题_Unity Shader教程 八、半透明物体的初步探索
  9. linux 解压zip文件及各种问题解决
  10. 万拓超融合存储CS100-36