当前位置: 首页 > news >正文

最短路径和关键路径的算法

最短路径和关键路径的算法

如下图
当我们在求下图的最短路径时,可以采用迪杰斯特拉算法和弗洛伊德算法

迪杰斯特拉算法
原理:每次比较每个顶点与起始顶点之间的权值,并找出最小权值的那一个顶点,最后,利用path数组进行反推
在这里插入图片描述
代码如下

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
#define MAX 0x10000
typedef int VertexType;
typedef int EdgeType;
typedef struct
{VertexType vertex[MAXSIZE];EdgeType arc[MAXSIZE][MAXSIZE];int vertex_num;int edge_num;
}Mat_Graph;
void CreateGraph(Mat_Graph* G)
{G->vertex_num = 9;G->edge_num = 16;for (int i = 0;i < G->vertex_num;i++){G->vertex[i] = i;}for (int i = 0;i < G->vertex_num;i++){for (int j = 0;j < G->vertex_num;j++){if (i == j){G->arc[i][j] = 0;}else{G->arc[i][j] = MAX;}}}G->arc[0][1] = 1;G->arc[0][2] = 5;G->arc[1][2] = 3;G->arc[1][3] = 7;G->arc[1][4] = 5;G->arc[2][4] = 1;G->arc[2][5] = 7;G->arc[3][4] = 2;G->arc[3][6] = 3;G->arc[4][5] = 3;G->arc[4][6] = 6;G->arc[4][7] = 9;G->arc[5][7] = 5;G->arc[6][7] = 2;G->arc[6][8] = 7;G->arc[7][8] = 4;for (int i = 0;i < G->vertex_num;i++){for (int j = 0;j < G->vertex_num;j++){G->arc[j][i] = G->arc[i][j];}}
}
//选择顶点
int choose(int distance[], int found[], int vertex_num)
{int min = MAX;int minpos = -1;for (int i = 0;i < vertex_num;i++){if (distance[i] < min && found[i] == 0){min = distance[i];minpos = i;}}return minpos;
}
//迪杰斯特拉算法
void dijstra(Mat_Graph* G, int begin)
{int found[MAXSIZE];//确定顶点是否被遍历int path[MAXSIZE];//数组值表示距离数组下标代表的点最近的点int distance[MAXSIZE];//每一个顶点距离起始点的距离for (int i = 0;i < G->vertex_num;i++){found[i] = 0;path[i] = -1;distance[i] = G->arc[begin][i];}found[0] = 1;distance[0] = 0;int next;for (int i = 1;i < G->vertex_num;i++){next = choose(distance, found, G->vertex_num);found[next] = 1;for (int j = 0;j < G->vertex_num;j++){if (found[j] == 0){if (distance[next] + G->arc[next][j] < distance[j]){//每次替换距离值distance[j] = distance[next] + G->arc[next][j];path[j] = next;}}}}for (int i = 1;i < G->vertex_num;i++){printf("V0->V%d : %d\n", i, distance[i]);int j = i;printf("V%d<-", i);{while(path[j] != -1){printf("V%d<-", path[j]);j = path[j];}}printf("V0\n");}
}
int main()
{Mat_Graph G;CreateGraph(&G);dijstra(&G, 0);return 0;
}

运行结果如下
在这里插入图片描述
表示是利用path数组进行反推

弗洛伊德算法
在这里插入图片描述

弗洛伊德算法是利用两个数组来进行判断两个顶点之间的最短路径是否经过了中间结点
代码如下

//弗洛伊德算法
void floyd(Mat_Graph* G)
{int path[MAXSIZE][MAXSIZE];//判断是否存在中间结点int distance[MAXSIZE][MAXSIZE];//两点之间的距离for (int i = 0;i < G->vertex_num;i++){for (int j = 0;j < G->vertex_num;j++){path[i][j] = j;distance[i][j] = G->arc[i][j];}}for (int i = 0;i < G->vertex_num;i++){for (int j = 0;j < G->vertex_num;j++){for (int k = 0;k < G->vertex_num;k++){if (distance[j][k] > distance[j][i] + distance[i][k]){distance[j][k] = distance[j][i] + distance[i][k];path[j][k] = path[j][i];}}}}int k;for (int i = 0;i < G->vertex_num;i++){for (int j = i + 1;j < G->vertex_num;j++){printf("V%d->V%d  weight:%d  ", i, j, distance[i][j]);k = path[i][j];printf("path:V%d->", i);while (k != j){printf("V%d->", k);k = path[k][j];}printf("V%d\n", j);}printf("\n");}
}
int main()
{Mat_Graph G;CreateGraph(&G);floyd(&G);return 0;
}

运行结果如下(只是其中i=0的一部分)
在这里插入图片描述

http://www.dtcms.com/a/347783.html

相关文章:

  • Linux学习:信号的保存
  • 【什么是大模型自注意力机制?】
  • 腾讯wxg后台开发面经
  • A Large Scale Synthetic Graph Dataset Generation Framework的学习笔记
  • JavaSpring+mybatis+Lombok,实现java架构[保姆教程]
  • KVM虚拟化:提升企业效率的利器
  • 编程刷题-P1746 离开中山路 BFS/最短路径
  • 数据结构算法:顺序表
  • 电脑零广告快响应提速(一)之卸载搜狗输入法使用RIME—东方仙盟
  • qt ElaWidgetTools第一个实例
  • linux进程调度相关头文件sched.h介绍与使用指南
  • 油猴(tampermonkey)脚本下载及安装使用教程!绿色版
  • [python编程] 零基础入门面向对象
  • Python面向对象高级编程——定制类
  • 本地部署开源书签管理工具 LinkAce 并实现外部访问( Windows 版本)
  • git实战问题(6)git push 时发现分支已被更新,push失败了怎么办
  • EPWpy 安装教程
  • 原初书写与符号嬗变:文字学理论的多维透视与当代重估
  • 【LeetCode】24. 两两交换链表中的节点
  • 青少年机器人技术(五级)等级考试试卷(2021年12月)
  • Linux:4_进程概念
  • Python 文件操作全解析:模式、方法与实战案例
  • openharmony之启动恢复子系统详解
  • 控制建模matlab练习14:线性状态反馈控制器-③极点配置
  • 河南萌新联赛2025第(六)场:郑州大学
  • nodejs 集成mongodb实现增删改查
  • 基于深度学习的中草药识别系统:从零到部署的完整实践
  • CA6150主轴箱系统设计cad+设计说明书
  • Java 学习笔记(基础篇8)
  • MQTT 核心概念与协议演进全景解读(二)