floyd算法的C语言实现

合集下载

最短路径——floyd算法代码(c语言)

最短路径——floyd算法代码(c语言)

最短路径——floyd算法代码(c语⾔)最短路径问题昨天⾃⼰试了试写⼀下dijkstra的算法博客今天来更floyd算法,感觉⾮常简单果然暴⼒才是解决⼀切的王道⼀、总体思想floyd算法就是每⼀次从邻接矩阵选取⼀个顶点k,然后再去矩阵中遍历两个顶点i,j,看看是i→j的路径短,还是i→k→j的路径短,就是完全的暴⼒,算法和代码⾮常简单⼆、代码实现1void Floyd(Graph G)2 {3int arr[G.vexnum][G.vexnum];4for(int i = 0; i < G.vexnum; i++)5for(int j = 0; j < G.vexnum; i++)6 arr[i][j] = G.edge[i][j];78for(int k; k < G.vexnum; k++)9for(int i = 0; i < G.vexnum; i++)10for(int j = 0; j < G.vexnum; j++)11if(arr[i][j] > arr[i][k] + arr[k][j])12 arr[i][j] = arr[i][k] + arr[k][j];13 }三、代码解释其实看上⾯的代码量和代码就知道这个算法很简单 =_=传⼊Floyd算法的参数是Graph G⾸先开辟⼀个⼆维数组arr[][],并且把图的邻接矩阵G.edge[][]赋值给arr[][],算法的主要思想就是来修改arr[][]值暴⼒出最短路径1int arr[G.vexnum][G.vexnum];//开辟数组arr[][]接收图G.edge[][]的值2for(int i = 0; i < G.vexnum; i++)3for(int j = 0; j < G.vexnum; i++)4 arr[i][j] = G.edge[i][j];//遍历赋值然后就是每次选择⼀个顶点k,再去找两个顶点i,j,对⽐看看是i→j的路径短,还是i→k→j的路径短也就是arr[i][j] 和 arr[i][k] + arr[k][j]两个的值谁的⽐较⼩,然后修改arr[][]⼀直到遍历完毕1for(int k; k < G.vexnum; k++)//选取k顶点2for(int i = 0; i < G.vexnum; i++)3for(int j = 0; j < G.vexnum; j++)//再选取i,j两个顶点4if(arr[i][j] > arr[i][k] + arr[k][j])//判断i→j的路径和i→k→j的路径谁⽐较短5 arr[i][j] = arr[i][k] + arr[k][j];//如果i→k→j的路径更短,则修改数组arr[][]写完感觉好短。

c语言校园导航最短距离-floyd算法

c语言校园导航最短距离-floyd算法

校园导航最短距离-Floyd算法一、引言在现代社会中,校园导航成为了大学生、教师、甚至游客日常生活中的重要组成部分。

特别是大一新生,对校园的地理布局尚不熟悉,更需要一种高效的导航方式来帮助他们更快地找到教学楼、食堂、宿舍等地点。

而作为计算机科学领域的重要一环,C语言通过应用Floyd算法来解决校园导航最短距离的问题,给校园导航增添了新的可能性。

二、校园导航最短距离-Floyd算法的基本概念在介绍C语言以及Floyd算法在校园导航中的应用之前,我们先来了解一下校园导航最短距离-Floyd算法的基本概念。

Floyd算法是一种用于寻找加权图中顶点对之间最短路径的算法,主要用于解决多源点之间的最短路径问题。

在校园导航中,可以将校园内不同的地点看作图中的顶点,而顶点之间的路径长度则可以看作边的权重,Floyd算法就可以帮助我们快速找到任意两个地点之间的最短路径。

而C语言作为一种结构化程序设计语言,其高效、灵活的特性可以很好地支持Floyd算法的实现。

三、C语言在校园导航最短距离中的应用1. 基于邻接矩阵的图表示在C语言中,我们可以利用二维数组来表示图的邻接矩阵,用来存储不同地点之间的路径长度。

通过邻接矩阵的方式,我们可以方便地在程序中存储校园内各个地点之间的距离,为Floyd算法的实现提供了基础。

2. Floyd算法的实现在C语言中,我们可以通过嵌套循环来实现Floyd算法。

我们需要初始化一个二维数组来存储任意两个地点之间的最短距离,然后通过三重循环来不断更新这个数组,直到找到所有顶点对之间的最短路径。

C 语言的结构化特性使得Floyd算法的实现变得简洁清晰,同时也可以充分利用C语言的指针和数组操作来提高算法的效率。

四、校园导航最短距离-Floyd算法的个人观点和理解作为一名计算机科学专业的学生,我对校园导航最短距离-Floyd算法的应用深感兴趣。

我认为Floyd算法的高效性和C语言的灵活性为校园导航提供了新的可能性,可以帮助校园内的师生更快捷、准确地找到目的地。

运筹学最小支撑树算法和FLOYD算法的C语言实现

运筹学最小支撑树算法和FLOYD算法的C语言实现

运筹学最小支撑树算法和FLOYD算法的C语言实现一、最小支撑树算法:#include <stdio.h>#define butong 32767#define N 7typedef struct{int vnum;int arcs[N][N];}graph; //定义图的结构void jtu(graph *p){int i,j,n ;int v1,v2,w;printf("请输入图的顶点个数:");scanf("%d",&n);p->vnum=n;for(i=0;i<n;++i)//初始化for(j=0;j<n;++j)if(i==j)p->arcs[i][j]=0;elsep->arcs[i][j]=butong;printf("请输入边的基本信息(以输入三个-1结束):\n");do{printf("边(顶点1,顶点2,权):");scanf("%d,%d,%d",&v1,&v2,&w);if(v1>=0&&v1<n&&v2>=0&&v2<n){p->arcs[v1][v2]=w;p->arcs[v2][v1]=w;}}while(!(v1==-1&&v2==-1));}int zcs(graph G,int v, int shu[][3])//最小支撑树函数{int i,j,k,p,min,c;int lowcost[N],closest[N];for(i=0;i<G.vnum;++i){closest[i]=v;lowcost[i]=G.arcs[v][i];}c=0;p=0;for(i=0;i<G.vnum-1;++i){min=butong;for(j=0;j<G.vnum;++j)if(lowcost[j]!=0&&lowcost[j]<min){min=lowcost[j];k=j;}shu[p][0]=closest[k];shu[p][1]=k;shu[p][2]=min;p++;c+=min;lowcost[k]=0;for(j=0;j<G.vnum;++j)if(G.arcs[k][j]!=0&&G.arcs[k][j]<lowcost[j]){lowcost[j]=G.arcs[k][j];closest[j]=k;}}return c;}void main(){int i;int shu[N][3];int cost;graph G;jtu(&G);cost=zcs(G,1,shu);printf("最小支撑树:\n");printf("边\t 权\t\n");for(i=0;i<G.vnum-1;++i)printf("v%d-v%d\t%d\n",shu[i][0]+1,shu[i][1]+1,shu[i][2]); }二、FLOYD算法:#include<stdio.h>#include<math.h>#define N 100void main(){int Num;int k,i,j;float arry[N][N];float dist[N][N]={0};printf("请输入顶点个数:\n");scanf("%d",&Num);printf("请输入权值矩阵(10000表示两点不连通):\n");for(i=0;i<Num;i++)for(j=0;j<Num;j++)scanf("%f",&arry[i][j]);printf("\n\n");for(i=0;i<Num;i++)for(j=0;j<Num;j++){printf(" %3.1f",arry[i][j]);if(j==Num-1)printf("\n");}printf("\n\n");for(i=0;i<Num;i++)for(j=0;j<Num;j++){dist[i][j]=arry[i][j]; }for(k=0;k<Num-1;k++)for(i=0;i<Num;i++)for(j=0;j<Num;j++)if(dist[i][k]+dist[k][j]<dist[i][j]){dist[i][j]=dist[i][k]+dist[k][j];}printf("最短路径为:");for(i=0;i<Num;i++)for(putchar('\n'),j=0;j<Num;j++)printf(" %3.1f",dist[i][j]);printf("\n");}。

floyd算法求最短路径问题c语言

floyd算法求最短路径问题c语言

Floyd算法求最短路径问题一、背景介绍在图论中,最短路径是一个重要的研究领域。

最短路径问题可以归结为在一个有向带权图中寻找从一个顶点到另一个顶点的路径,使得路径上的所有边的权值之和最小。

解决最短路径问题的经典算法之一就是Floyd算法。

二、Floyd算法概述Floyd算法是一种动态规划算法,用于求解图中任意两个顶点之间的最短路径。

Floyd算法的基本思想是逐步地考虑图中所有的顶点作为中间节点,更新任意两个顶点之间的最短路径。

三、算法实现步骤Floyd算法的实现步骤如下:1.初始化距离矩阵:创建一个二维数组dist,用于存储任意两个顶点之间的最短路径距离。

如果存在一条直接的边连接两个顶点,则将对应位置的元素设为边的权值;否则,将对应位置的元素设为无穷大。

2.动态规划更新距离矩阵:利用三重循环遍历所有的顶点,每次循环都尝试通过当前顶点作为中间节点,更新任意两个顶点之间的最短路径距离。

具体地,对于任意的两个顶点i和j,如果存在另一个顶点k,使得经过顶点k的路径比直接连接的路径更短,则更新dist[i][j] = dist[i][k] + dist[k][j]。

3.输出最短路径:根据更新后的距离矩阵dist,可以轻松地得到任意两个顶点之间的最短路径。

四、算法复杂度分析Floyd算法的时间复杂度为O(N3),其中N表示图中顶点的个数。

Floyd算法的空间复杂度为O(N2),由于需要创建一个二维数组用于存储任意两个顶点之间的最短路径距离。

五、算法应用举例下面通过一个具体的例子来说明Floyd算法的应用。

假设有一个有向带权图,包含5个顶点和7条边,如下所示:2 30 ——► 1 ——► 2▲ / ▲ / ▲| / | /| / | /| / |/3 ——► 45图中顶点0到顶点2的最短路径为0→1→2,路径长度为5;顶点0到顶点3的最短路径为0→1→2→4→3,路径长度为11。

通过应用Floyd算法,我们可以得到所有顶点之间的最短路径。

floyd算法c语言实现

floyd算法c语言实现

Floyd算法C语言实现1. 算法介绍Floyd算法,也称为弗洛伊德算法,是一种用于寻找图中所有节点之间最短路径的算法。

它通过不断更新节点之间的最短距离来求解最短路径问题。

Floyd算法是一种动态规划的算法,其核心思想是利用中间节点逐步优化路径。

Floyd算法的时间复杂度为O(n^3),其中n为图中节点的数量。

它适用于解决有向图或无向图中节点之间的最短路径问题,可以处理图中存在负权边的情况。

2. 算法原理Floyd算法通过一个二维数组来表示图的邻接矩阵,其中每个元素表示两个节点之间的距离。

算法的核心思想是,通过不断更新这个距离矩阵,使得每个节点之间的距离逐步优化,最终得到最短路径。

算法的具体步骤如下: 1. 初始化距离矩阵,将两个相邻节点之间的距离填入矩阵中,若两个节点之间无直接连接,则距离设为无穷大。

2. 对于每对节点i和j,以及每个中间节点k,检查是否存在从节点i经过节点k到节点j的路径,如果存在则更新距离矩阵中的距离。

3. 重复步骤2,逐步更新距离矩阵,直到所有节点之间的最短路径被找到。

3. 算法实现下面是Floyd算法的C语言实现代码:#include <stdio.h>#define INF 99999#define MAX_NODES 100void floyd(int graph[MAX_NODES][MAX_NODES], int num_nodes) {int i, j, k;// 初始化距离矩阵int dist[MAX_NODES][MAX_NODES];for (i = 0; i < num_nodes; i++) {for (j = 0; j < num_nodes; j++) {dist[i][j] = graph[i][j];}}// 逐步更新距离矩阵for (k = 0; k < num_nodes; k++) {for (i = 0; i < num_nodes; i++) {for (j = 0; j < num_nodes; j++) {if (dist[i][k] + dist[k][j] < dist[i][j]) { dist[i][j] = dist[i][k] + dist[k][j]; }}}}// 打印最短路径矩阵printf("最短路径矩阵:\n");for (i = 0; i < num_nodes; i++) {for (j = 0; j < num_nodes; j++) {if (dist[i][j] == INF) {printf("INF ");} else {printf("%d ", dist[i][j]);}}printf("\n");}}int main() {int num_nodes, i, j;int graph[MAX_NODES][MAX_NODES];printf("请输入节点的数量:");scanf("%d", &num_nodes);printf("请输入图的邻接矩阵:\n");for (i = 0; i < num_nodes; i++) {for (j = 0; j < num_nodes; j++) {scanf("%d", &graph[i][j]);}}floyd(graph, num_nodes);return 0;}4. 算法测试我们来测试一下上述代码的运行结果。

Floyd算法——最短路径算法_C语言实现_阿涵_新浪博客

Floyd算法——最短路径算法_C语言实现_阿涵_新浪博客
int i,j,k;
for(i=0;i<n;i++){//初始化
for(j=0;j<n;j++){
if(G->A[i][j]<MAX_INT){
path[i][j]=j;
}else{
path[i][j]=-1;
}
D[i][j]=G->A[i][j];
}
}
for(k=0;k<n;k++){//进行n次试探
}MGraph;//邻接矩阵表示的图
//Floyd算法
//求网G(用邻接矩阵表示)中任意两点间最短路径
//D[][]是最短路径长度矩阵,path[][]最短路径标志矩阵
void Floyd(MGraph * G,int path[][MAX_VERTEX_NUM],int D[][MAX_VERTEX_NUM],int n){
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(D[i][j]>D[i][k]+D[k][j]){
D[i][j]=D[i][k]+D[k][j];//取小者
path[i][j]=path[i][k];//改Vi的后继
}
}
}
}
}
int main(){
int i,j,k,v=0,n=6;//v为起点,n为顶点个数
刘启诚
与客户共同创新(一)
惠普中国研究院
有一种生活叫“Smarter lif络低俗广告的鉴定标准
阿祥
告诉大家一个更加透明的华为

实验三最短路径的算法(离散数学实验报告)

实验三最短路径的算法(离散数学实验报告)

实验三最短路径的算法(离散数学实验报告)实验3:最短路径算法⼀、实验⽬的通过本实验的学习,理解Floyd(弗洛伊得)最短路径算法的思想⼆、实验内容⽤C语⾔编程实现求赋权图中任意两点间最短路径的Floyd算法,并能对给定的两结点⾃动求出最短路径三、实验原理、⽅法和⼿段1、Floyd算法的原理定义:Dk[i,j] 表⽰赋权图中从结点vi出发仅通过v0,v1,┉,vk-1中的某些结点到达vj的最短路径的长度,若从vi到vj没有仅通过v0,v1,┉,vk-1 的路径,则D[i,j]=∝即D-1[i,j] 表⽰赋权图中从结点vi到vj的边的长度,若没有从结点vi到vj的边,则D[i,j]=∝D0[i,j] 表⽰赋权图中从结点vi到vj的”最短”路径的长度, 这条路上除了可能有v0外没有其它结点D1[i,j] 表⽰赋权图中从结点vi到vj的”最短”路径的长度, 这条路上除了可能有v0,v1外没有其它结点┉┉┉根据此定义,D k[i,j]=min{ D k-1[i,j] , D k-1[i,k-1]+D k-1[k-1,j] }定义:path[i,j]表⽰从结点vi到vj的“最短”路径上vi的后继结点四、实验要求要求输出每对结点之间的最短路径长度以及其最短路径五、实验步骤(⼀)算法描述Step 1 初始化有向图的成本邻矩阵D、路径矩阵path若从结点vi到vj有边,则D[i,j]= vi到vj的边的长度,path[i,j]= i;否则D[i,j]=∝,path[i,j]=-1Step 2 刷新D、path 对k=1,2,┉n 重复Step 3和Step 4Step 3 刷新⾏对i=1,2,┉n 重复Step 4Step 4 刷新Mij 对j=1,2,┉n若D k-1[i,k]+D k-1[k,j][结束循环][结束Step 3循环][结束Step 2循环]Step 5 退出(⼆)程序框图参考主程序框图其中,打印最短路径中间结点调⽤递归函数dist(),其框图如下,其中fist,end是当前有向边的起点和终点dist(int first, int end)七、测试⽤例:1、输⼊成本邻接矩阵:D :06380532290141003210∝∝∝∝V V V V V V V V (其中∝可⽤某个⾜够⼤的数据值代替,⽐如100)可得最短路径矩阵:P :131132122211111010103210--------V V V V V V V V以及各顶点之间的最短路径和最短路径长度:从V0到V1的最短路径长度为:1 ;最短路径为:V0→V1 从V0到V2的最短路径长度为:9 ;最短路径为:V0→V1→V3→V2 从V0到V3的最短路径长度为:3 ;最短路径为:V0→V1→V3 从V1到V0的最短路径长度为:11;最短路径为:V1→V3→V2→V0从V1到V2的最短路径长度为:8 ;最短路径为:V1→V3→V2 从V1到V3的最短路径长度为:2 ;最短路径为:V1→V3 从V2到V0的最短路径长度为:3 ;最短路径为:V2→V0 从V2到V1的最短路径长度为:4 ;最短路径为:V2→V0→V1 从V2到V3的最短路径长度为:6 ;最短路径为:V2→V0→V1→V3 从V3到V0的最短路径长度为:9 ;最短路径为:V3→V2→V0 从V3到V1的最短路径长度为:10;最短路径为:V3→V2→V0→V1 从V3到V2的最短路径长度为:6 ;最短路径为:V3→V2 参考程序: #include #define INFINITY 100 #define Max 10int a[Max][Max],P[Max][Max]; main() {void Print_Flod(int d);int i,j,k,D=4;printf("请输⼊成本邻接矩阵:\n");for(i=0;ifor(j=0;j{scanf("%d",&a[i][j]);}for(i=0;ifor(j=0;j{if(a[i][j]>0&& a[i][j]elseP[i][j]=-1;}for(k=0;kfor(i=0;ifor(j=0;jif (a[i][k]+a[k][j]{a[i][j]=a[i][k]+a[k][j];P[i][j]=k;}Print_Flod(D);}void Print_Flod(int d){void dist(int first,int end);int i,j;for(i=0;ifor(j=0;jif(i!=j){ printf("from V%d to V%d: ",i,j); dist(i,j);printf("V%d",j);printf(" (The length is: %d)\n",a[i][j]); }}void dist(int first,int end){ int x;x=P[first][end];if(x!=first){ dist(first,x); dist(x,end); }else printf("V%d->",x);}输出结果:。

弗洛伊德算法c语言

弗洛伊德算法c语言

弗洛伊德算法c语言弗洛伊德算法(Floyd algorithm),又称为插点法,解决的是任意两点之间的最短路径问题,能够处理有向图或负权边的情况。

下面是使用c语言实现弗洛伊德算法的示例代码:```c。

#include <stdio.h>。

#include <stdlib.h>。

#define INF 99999 // 代表不连通。

void floyd(int **adj, int n) 。

int i, j, k;。

//先进行初始化。

for(i = 0; i < n; i++) 。

for(j = 0; j < n; j++) 。

if(adj[i][j] == 0) { // 如果是没有连通的,则初始化为无穷大。

adj[i][j] = INF;。

}。

}。

}。

//进行动态规划。

for(k = 0; k < n; k++) { // 可以理解为依次插入节点。

for(i = 0; i < n; i++) 。

for(j = 0; j < n; j++) 。

if(adj[i][j] > adj[i][k] + adj[k][j]) 。

adj[i][j] = adj[i][k] + adj[k][j];。

}。

}。

}。

}。

}。

int main() 。

int n, m;。

printf("请输入节点的数量:");。

scanf("%d", &n);。

printf("请输入边的数量:");。

scanf("%d", &m);。

printf("请输入每条边的起点、终点、长度:\n");。

int **adj = (int **)malloc(sizeof(int *) * n);。

int i, j;。

for(i = 0; i < n; i++) 。

Floyd算法简单实现(C++)

Floyd算法简单实现(C++)

Floyd算法简单实现(C++)图的最短路径问题主要包括三种算法:(1)(2)(3)Bellman (含有负权边的单源最短路径)本⽂主要讲使⽤C++实现简单的Floyd算法,Floyd算法原理参见Floyd算法简单实现(C++)1 #include<iostream>2using namespace std;34#define MAXVEX 105#define INFINITY 6553567 typedef int Patharc[MAXVEX][MAXVEX];8 typedef int ShortPathTable[MAXVEX][MAXVEX];910 typedef struct {11int vex[MAXVEX];12int arc[MAXVEX][MAXVEX];13int numVertexes;14 } MGraph;1516// 构建图17void CreateMGraph(MGraph *G){18int i, j, k;1920// 初始化图21 G->numVertexes = 9;22for(i = 0; i < G->numVertexes; ++i){23 G->vex[i] = i;24 }25for(i = 0; i < G->numVertexes; ++i){26for(j = 0; j < G->numVertexes; ++j){27if(i == j)28 G->arc[i][j] = 0;29else30 G->arc[i][j] = G->arc[j][i] = INFINITY;31 }32 }3334 G->arc[0][1] = 1;35 G->arc[0][2] = 5;3637 G->arc[1][2] = 3;38 G->arc[1][3] = 7;39 G->arc[1][4] = 5;4041 G->arc[2][4] = 1;42 G->arc[2][5] = 7;4344 G->arc[3][4] = 2;45 G->arc[3][6] = 3;4647 G->arc[4][5] = 3;48 G->arc[4][6] = 6;49 G->arc[4][7] = 9;5051 G->arc[5][7] = 5;5253 G->arc[6][7] = 2;54 G->arc[6][8] = 7;5556 G->arc[7][8] = 4;5758// 设置对称位置元素值59for(i = 0; i < G->numVertexes; ++i){60for(j = i; j < G->numVertexes; ++j){61 G->arc[j][i] = G->arc[i][j];62 }63 }64 }6566// Floyd algorithm67void ShortPath_Floyd(MGraph G, Patharc P, ShortPathTable D){68int i, j, k;69// ⼆重循环,初始化P, D70for(i = 0; i < G.numVertexes; ++i){71for(j = 0; j < G.numVertexes; ++j){72 D[i][j] = G.arc[i][j];73 P[i][j] = j;74 }75 }76// 三重循环, Floyd algorithm77for(k = 0; k < G.numVertexes; ++k){78for(i = 0; i < G.numVertexes; ++i){79for(j = 0; j < G.numVertexes; ++j){80if(D[i][j] > D[i][k]+D[k][j]){81 D[i][j] = D[i][k]+D[k][j];82 P[i][j] = P[i][k];83 }84 }85 }86 }87 }8889// 打印最短路径90void PrintShortPath(MGraph G, Patharc P, ShortPathTable D){91int i, j, k;92 cout<<"各顶点之间的最短路径如下: "<<endl;93for(i = 0; i < G.numVertexes; ++i){94for(j = i+1; j < G.numVertexes; ++j){95 cout<<"v"<<i<<"--"<<"v"<<j<<""<<"weight: "<<D[i][j]<<" Path: "<<i<<" -> ";96 k = P[i][j];97while(k != j){98 cout<<k<<" -> ";99 k = P[k][j];100 }101 cout<<j<<endl;102 }103 cout<<endl;104 }105 }106107int main(int argc, char const *argv[]) {108 MGraph G;109 Patharc P;110 ShortPathTable D;111 CreateMGraph(&G);112 ShortPath_Floyd(G, P, D);113 PrintShortPath(G, P, D);114return0;115 }运⾏结果:各顶点之间的最短路径如下:v0--v1 weight: 1 Path: 0 -> 1v0--v2 weight: 4 Path: 0 -> 1 -> 2v0--v3 weight: 7 Path: 0 -> 1 -> 2 -> 4 -> 3v0--v4 weight: 5 Path: 0 -> 1 -> 2 -> 4v0--v5 weight: 8 Path: 0 -> 1 -> 2 -> 4 -> 5v0--v6 weight: 10 Path: 0 -> 1 -> 2 -> 4 -> 3 -> 6v0--v7 weight: 12 Path: 0 -> 1 -> 2 -> 4 -> 3 -> 6 -> 7v0--v8 weight: 16 Path: 0 -> 1 -> 2 -> 4 -> 3 -> 6 -> 7 -> 8v1--v2 weight: 3 Path: 1 -> 2v1--v3 weight: 6 Path: 1 -> 2 -> 4 -> 3v1--v4 weight: 4 Path: 1 -> 2 -> 4v1--v5 weight: 7 Path: 1 -> 2 -> 4 -> 5v1--v6 weight: 9 Path: 1 -> 2 -> 4 -> 3 -> 6v1--v7 weight: 11 Path: 1 -> 2 -> 4 -> 3 -> 6 -> 7v1--v8 weight: 15 Path: 1 -> 2 -> 4 -> 3 -> 6 -> 7 -> 8v2--v3 weight: 3 Path: 2 -> 4 -> 3v2--v4 weight: 1 Path: 2 -> 4v2--v5 weight: 4 Path: 2 -> 4 -> 5v2--v6 weight: 6 Path: 2 -> 4 -> 3 -> 6v2--v7 weight: 8 Path: 2 -> 4 -> 3 -> 6 -> 7v2--v8 weight: 12 Path: 2 -> 4 -> 3 -> 6 -> 7 -> 8v3--v4 weight: 2 Path: 3 -> 4v3--v5 weight: 5 Path: 3 -> 4 -> 5v3--v6 weight: 3 Path: 3 -> 6v3--v7 weight: 5 Path: 3 -> 6 -> 7v3--v8 weight: 9 Path: 3 -> 6 -> 7 -> 8v4--v5 weight: 3 Path: 4 -> 5v4--v6 weight: 5 Path: 4 -> 3 -> 6v4--v7 weight: 7 Path: 4 -> 3 -> 6 -> 7v4--v8 weight: 11 Path: 4 -> 3 -> 6 -> 7 -> 8 v5--v6 weight: 7 Path: 5 -> 7 -> 6v5--v7 weight: 5 Path: 5 -> 7v5--v8 weight: 9 Path: 5 -> 7 -> 8v6--v7 weight: 2 Path: 6 -> 7v6--v8 weight: 6 Path: 6 -> 7 -> 8v7--v8 weight: 4 Path: 7 -> 8[Finished in1.2s]参考资料:。

Floyd—Warshall算法的C语言实现

Floyd—Warshall算法的C语言实现

0 引 言
最 短 路 是 图 论 研 究 中 的 一 个 经 典 算 法 问题 。 最 短 路 问 题 , 般 来 说 就 是 从 给 定 的 网 络 中 找 出 任 意 一 两 点 之 间 距 离 最 短 的 一 条 路 径 。 这 里 说 的 距 离 是 权 数 的 代 称 , 实 际 的 网 络 中 , 数 可 以是 时 间 、 用 在 权 费
为 与 ,的 距 离 。
Fly o d~ W a s al 法 可 求 每 对 顶 点 之 间 最 短 距 离 ,g中 的 权 可 为 负 值 , 不 可 以 有 带 负 权 的 圈 。 rh l算 ; I 但
Fly o d~ W a s al 法 的 描 述 如 下 : rh l算
20 0 8年 l 月 1
安庆 师 范学 院学报 ( 自然科 学版)
Jun l f n i e cesC l g ( aua S i c d in o ra o qn T a h r ol e N trl c neE io ) A g e e t
NO 2 0 V. 0 8
E , 应 一 个 实 数 叫 称 为 弧 上 的 “ ” 通 常 把 这 种 赋 权 的 图 称 为 赋 权 图 或 网 络 。 对 权 。 定 义 3 对 于 赋 权 有 向 图 D 一 (/ E) 其 中 边 有 权 一¨ 构 造 矩 阵 U 一 ( d , 中 : 、, , r ) 其
定 义 2 在实 际应 用 中 , 定 一个 图 G一 ( , 给 E)或 有 向 图 D 一 ( , , V 中 指 定 两 个 点 , 个 称 V E) 在 一 为 始 点 ( 发 点 ) 记 作 , 一 个 称 为 终 点 ( 收 点 ), 作 , 余 的 点 称 为 中 间 点 。 每 一 条 弧 ( , ) ∈ 或 , , 或 记 其 对

任意顶点之间的最短路径的floyd算法实现

任意顶点之间的最短路径的floyd算法实现

任意顶点之间的最短路径的floyd算法实现以下是一个使用C语言实现的Floyd算法的示例代码,用于计算任意顶点之间的最短路径:```c#include<stdio.h>#include<stdlib.h>#include<math.h>int map[3][3]={0,4,11,6,0,2,3,100000,0};int path[3][3]={{-1,0,0},{1,-1,1},{2,2,-1}};int main(){int n=3;for(int i=0;i<n;i++){for(int j=0;j<n;j++){for(int k=0;k<n;k++){if(map[j][i]+map[i][k]<map[j][k]){map[j][k]=map[j][i]+map[i][k];path[j][k]=i;}}}}printf("每对顶点的最短路径为:\n");for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(path[i][j]!=-1){printf("V%d",j);int temp=path[i][j];while(temp!=-1){printf(" <- V%d",temp);temp=path[i][temp];printf("\t路径长度为%d\n",map[i][j]);}}}}return 0;}```在上述代码中,`map`数组用于存储图的权值信息,`path`数组用于存储顶点之间的最短路径。

外层循环遍历所有顶点,内层循环遍历所有边,每次比较当前边和当前顶点到其他顶点的路径之和,并更新最短路径和权值。

最后输出每对顶点之间的最短路径。

请注意,这只是一个简单的示例代码,实际应用中可能需要根据具体需求进行修改。

Floyd(弗洛伊德)算法(C语言)

Floyd(弗洛伊德)算法(C语言)

Floyd(弗洛伊德)算法(C语⾔)转载:Floyd算法的介绍算法的特点弗洛伊德算法是解决任意两点间的最短路径的⼀种算法,可以正确处理有向图或有向图或负权(但不可存在负权回路)的最短路径问题,同时也被⽤于计算有向图的传递闭包。

算法的思路通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引⼊两个矩阵,矩阵S中的元素a[i][j]表⽰顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

矩阵P中的元素b[i][j],表⽰顶点i到顶点j经过了b[i][j]记录的值所表⽰的顶点。

假设图G中顶点个数为N,则需要对矩阵D和矩阵P进⾏N次更新。

初始时,矩阵D中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞,矩阵P的值为顶点b[i][j]的j的值。

接下来开始,对矩阵D进⾏N次更新。

第1次更新时,如果”a[i][j]的距离” > “a[i][0]+a[0][j]”(a[i] [0]+a[0][j]表⽰”i与j之间经过第1个顶点的距离”),则更新a[i][j]为”a[i][0]+a[0][j]”,更新b[i][j]=b[i][0]。

同理,第k次更新时,如果”a[i][j]的距离” >“a[i][k-1]+a[k-1][j]”,则更新a[i][j]为”a[i][k-1]+a[k-1][j]”,b[i][j]=b[i][k-1]。

更新N次之后,操作完成!补充:以下⾯图为例⼦,b[i][j]中存储的是Vi~Vj之间的中介点,b[i][j]初始值为j,⽐如V0~V3最短路径是V0-->V2-->V1-->v3,在计算最短路径时转换为V0-->V2的距离加上V2-->V3的最短距离,接下来类似于递归,V2-->V3的最短路径就是以V1为中介点,V2-->V1的距离加上V1-->V3的距离。

因此,b[0][3]=2实例说明将整体分为两个步骤1.计算metrixD矩阵(两顶点之间的最短距离)和P矩阵(两顶点的中介点)#include <stdio.h>#include <stdlib.h>void Create_metrixD_P(int** metrixD, int **P ,int VerNum, int EdgNum){int x, y, Weight, edg_count = 0;int i, j, k;for (i = 0; i < VerNum; ++i) {for (j = 0; j < VerNum; ++j) {metrixD[i][j] = INT_MAX;P[i][j] = j;}}while (edg_count < EdgNum) {scanf("%d%d%d", &x, &y, &Weight);metrixD[x - 1][y - 1] = Weight;edg_count++;}}//Floyd algorithmvoid Floyd(int **metirxD, int **P, int VerNum) {int n, x, y, temp = 0;//The triple loop looks for shortest paths and weightsfor (n = 0; n < VerNum; ++n) {for (x = 0; x < VerNum; ++x) {for (y = 0; y < VerNum; ++y) {//The distance between two vertices is compared to the distance through a vertextemp = (metirxD[x][n] == INT_MAX || metirxD[n][y] == INT_MAX) ? INT_MAX : (metirxD[x][n] + metirxD[n][y]);if (temp < metirxD[x][y]) {//Update matrix informationmetirxD[x][y] = temp;P[x][y] = n;}}}}}void Show_metrixD_P(int** metrixD, int **P, int VerNum){int x, y;printf("metrixD:\n");for (x = 0; x < VerNum; ++x) {for (y = 0; y < VerNum; ++y) {if (metrixD[x][y] == INT_MAX) {printf("∞ ");}else {printf("%d ", metrixD[x][y]);}}printf("\n");}printf("P:\n");for (x = 0; x < VerNum; ++x) {for (y = 0; y < VerNum; ++y) {printf("%d ", P[x][y]);}printf("\n");}}int main(void){int VerNum, EdgNum, i;int** metrixD, ** P;printf("Enter the number of vertices and edges:");scanf("%d%d", &VerNum, &EdgNum);metrixD = (int**)malloc(VerNum * sizeof(int));P = (int**)malloc(VerNum * sizeof(int));for (i = 0; i < VerNum; ++i) {metrixD[i] = (int*)malloc(VerNum * sizeof(int));P[i] = (int*)malloc(VerNum * sizeof(int));}printf("Input vertices and weights:");Create_metrixD_P(metrixD, P, VerNum, EdgNum);Floyd(metrixD, P, VerNum);Show_metrixD_P(metrixD, P, VerNum);for (i = 0; i < VerNum; ++i) {free(metrixD[i]);free(P[i]);}free(metrixD);free(P);return0;}2.输出顶点之间的最短距离与路径#include <stdio.h>#include <stdlib.h>#define VEXNUM 5//Adjacency matrix: shows the distance between verticesint metirxD[VEXNUM][VEXNUM] = {INT_MAX,10, 5, INT_MAX,INT_MAX,INT_MAX,INT_MAX,2, 1, INT_MAX,INT_MAX,3, INT_MAX,9, 2,INT_MAX,INT_MAX,INT_MAX,INT_MAX,4,7, INT_MAX,INT_MAX,5, INT_MAX};//Path: passing vertex between two verticesint P[VEXNUM][VEXNUM] = {0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4};//Floyd algorithmvoid Floyd() {int n, x, y, temp = 0;//The triple loop looks for shortest paths and weightsfor (n = 0; n < VEXNUM; ++n) {for (x = 0; x < VEXNUM; ++x) {for (y = 0; y < VEXNUM; ++y) {//The distance between two vertices is compared to the distance through a vertextemp = (metirxD[x][n] == INT_MAX || metirxD[n][y] == INT_MAX) ? INT_MAX : (metirxD[x][n] + metirxD[n][y]);if (temp < metirxD[x][y]) {//Update matrix informationmetirxD[x][y] = temp;P[x][y] = n;}}}}}void Show_Path() {int x, y, temp = 0;//Output the shortest path between two verticesfor (x = 0; x < VEXNUM - 1; ++x) {for (y = x + 1; y < VEXNUM; ++y) {printf("V%d-->V%d weight:%d path:V%d", x, y, metirxD[x][y], x);temp = P[x][y];while (temp != y) {printf("-->V%d", temp);temp = P[temp][y];}printf("-->V%d", y);printf("\n");}}}int main(void){Floyd();Show_Path();return0;}完整代码#include <stdio.h>#include <stdlib.h>void Create_metrixD_P(int** metrixD, int **P ,int VerNum, int EdgNum){int x, y, Weight, edg_count = 0;int i, j, k;for (i = 0; i < VerNum; ++i) {for (j = 0; j < VerNum; ++j) {metrixD[i][j] = INT_MAX;P[i][j] = j;}}while (edg_count < EdgNum) {scanf("%d%d%d", &x, &y, &Weight);metrixD[x - 1][y - 1] = Weight;edg_count++;}}//Floyd algorithmvoid Floyd(int **metirxD, int **P, int VerNum) {int n, x, y, temp = 0;//The triple loop looks for shortest paths and weightsfor (n = 0; n < VerNum; ++n) {for (x = 0; x < VerNum; ++x) {for (y = 0; y < VerNum; ++y) {//The distance between two vertices is compared to the distance through a vertextemp = (metirxD[x][n] == INT_MAX || metirxD[n][y] == INT_MAX) ? INT_MAX : (metirxD[x][n] + metirxD[n][y]);if (temp < metirxD[x][y]) {//Update matrix informationmetirxD[x][y] = temp;P[x][y] = n;}}}}}void Show_metrixD_P(int** metrixD, int **P, int VerNum){int x, y;printf("metrixD:\n");for (x = 0; x < VerNum; ++x) {for (y = 0; y < VerNum; ++y) {if (metrixD[x][y] == INT_MAX) {printf("∞ ");}else {printf("%d ", metrixD[x][y]);}}printf("\n");}printf("P:\n");for (x = 0; x < VerNum; ++x) {for (y = 0; y < VerNum; ++y) {printf("%d ", P[x][y]);}printf("\n");}}void Show_Path(int **metirxD, int **P, int VerNum) {int x, y, temp = 0;//Output the shortest path between two verticesfor (x = 0; x < VerNum - 1; ++x) {for (y = x + 1; y < VerNum; ++y) {printf("V%d-->V%d weight:%d path:V%d", x, y, metirxD[x][y], x); temp = P[x][y];while (temp != y) {printf("-->V%d", temp);temp = P[temp][y];}printf("-->V%d", y);printf("\n");}}}int main(void){int VerNum, EdgNum, i;int** metrixD, ** P;printf("Enter the number of vertices and edges:");scanf("%d%d", &VerNum, &EdgNum);metrixD = (int**)malloc(VerNum * sizeof(int));P = (int**)malloc(VerNum * sizeof(int));for (i = 0; i < VerNum; ++i) {metrixD[i] = (int*)malloc(VerNum * sizeof(int));P[i] = (int*)malloc(VerNum * sizeof(int));}printf("Input vertices and weights:");Create_metrixD_P(metrixD, P, VerNum, EdgNum);Floyd(metrixD, P, VerNum);Show_metrixD_P(metrixD, P, VerNum);Show_Path(metrixD, P, VerNum);for (i = 0; i < VerNum; ++i) {free(metrixD[i]);free(P[i]);}free(metrixD);free(P);return0;}。

c++弗洛伊德算法

c++弗洛伊德算法

c++弗洛伊德算法弗洛伊德算法(Floyd Algorithm)是一种基于动态规划的方法,用于寻找加权图中所有顶点之间的最短路径。

该算法适用于有向图和无向图,但不适用于存在负权值环的图。

弗洛伊德算法的名字来源于其发明者之一、图灵奖获得者罗伯特·弗洛伊德(Robert Floyd)。

以下是使用C++实现弗洛伊德算法的示例代码:```cpp#include <iostream>#include <vector>#include <queue>#include <algorithm>using namespace std;const int INF = 0x3F3F3F3F; // 表示无穷大vector<vector<int>> createGraph(int n, const vector<vector<int>>& edges) {vector<vector<int>> graph(n, vector<int>(n, INF));for (const auto& edge : edges) {int u = edge[0], v = edge[1], w = edge[2];graph[u][v] = w;}return graph;}void floyd(const vector<vector<int>>& graph) {int n = graph.size();vector<vector<int>> dist(n, vector<int>(n, INF));for (int k = 0; k < n; k++) {for (int u = 0; u < n; u++) {for (int v = 0; v < n; v++) {dist[u][v] = min(dist[u][v], graph[u][k] + graph[k][v]);}}}for (int u = 0; u < n; u++) {for (int v = 0; v < n; v++) {cout << "从" << u << "到" << v << "的最短路径长度为:"<< dist[u][v] << endl;}}}int main() {int n = 4;vector<vector<int>> edges = {{0, 1, 10}, {0, 2, 5}, {1, 3, 1}, {2, 3, 10}, {3, 1, 2}, {3, 2, 4}};vector<vector<int>> graph = createGraph(n, edges);floyd(graph);return 0;}```在这个示例中,我们首先创建了一个图,然后调用弗洛伊德算法计算所有顶点之间的最短路径。

Floyd算法实现

Floyd算法实现

//Floyd算法实现#include <cstdio>#include <string>#define INF 1000000 //无穷大#define MAXN 20int n; //顶点个数int Edge[MAXN][MAXN]; //邻接矩阵int A[MAXN][MAXN]; //int path[MAXN][MAXN]; //void Floyd( ) //假定图的邻接矩阵和顶点个数已经读进来了{int i, j, k;for( i=0; i<n; i++ ){for( j=0; j<n; j++ ){A[i][j] = Edge[i][j]; //对a[ ][ ]初始化if( i!=j && A[i][j]<INF ) path[i][j] = i; //i到j有路径else path[i][j] = -1; //从i到j没有直接路径}}//从A(-1)递推到A(0), A(1), ..., A(n-1),//或者理解成依次将v0,v1,...,v(n-1)作为中间顶点for( k=0; k<n; k++ ){for( i=0; i<n; i++ ){for( j=0; j<n; j++ ){if( k==i || k==j ) continue;if( A[i][k] + A[k][j] < A[i][j] ){A[i][j] = A[i][k] + A[k][j] ;path[i][j] = path[k][j];}}}}}int main( ){int i, j; //循环变量int u, v, w; //边的起点和终点及权值scanf( "%d", &n ); //读入顶点个数nfor( i=0; i<n; i++ ) //设置邻接矩阵中每个元素的初始值为INF{for( j=0; j<n; j++ ) Edge[i][j] = INF;}for( i=0; i<n; i++ ) //设置邻接矩阵中对角线上的元素值为0{Edge[i][i] = 0;}while( 1 ){scanf( "%d%d%d", &u, &v, &w ); //读入边的起点和终点if( u==-1 && v==-1 && w==-1 ) break;Edge[u][v] = w; //构造邻接矩阵}Floyd( ); //求各对顶点间的最短路径int shortest[MAXN]; //输出最短路径上的各个顶点时存放各个顶点的序号for( i=0; i<n; i++ ){for( j=0; j<n; j++ ){if( i==j ) continue; //跳过printf( "%d=>%d\t%d\t", i, j, A[i][j] ); //输出顶点i到顶点j的最短路径长度//以下代码用于输出顶点0到顶点i的最短路径memset( shortest, 0, sizeof(shortest) );int k = 0; //k表示shortest数组中最后一个元素的下标shortest[k] = j;while( path[i][ shortest[k] ] != i ){k++; shortest[k] = path[i][ shortest[k-1] ];}k++; shortest[k] = i;for( int t=k; t>0; t-- )printf( "%d→", shortest[t] );printf( "%d\n", shortest[0] );}}return 0;}代码来自。

C语言求所有顶点对之间的最短路径:FLOYD算法

C语言求所有顶点对之间的最短路径:FLOYD算法

C语⾔求所有顶点对之间的最短路径:FLOYD算法所有顶点对之间的最短路径问题是:对于给定的有向⽹络G=(V,E),要对G中任意两个顶点v,w(v不等于w),找出v到w的最短路径。

当然我们可以n次执⾏DIJKSTRA算法,⽤FLOYD则更为直接,两种⽅法的时间复杂度都是⼀样的。

有向⽹络⽤邻接矩阵存储,以下⾯的有向⽹络为例:源程序清单:#include<stdio.h>#define n 5 //结点数⽬#define maxsize 160 //表⽰两点间不可达int path[n][n];//路径矩阵void floyd(int A[][n],int C[][n]); //A是路径长度矩阵,C是有向⽹络G的带权邻接矩阵void main(){printf(" ——所有顶点对之间的最短路径:Floyd算法——\n");printf("(160为⽆穷远,不可达)\n");int A[n][n],C[n][n]={{0,10,maxsize,30,100},{maxsize,0,50,maxsize,maxsize},{maxsize,maxsize,0,maxsize,10},{maxsize,maxsize,20,0,60},{maxsize,maxsize,maxsize,maxsize,0}};floyd(A,C);}void floyd(int A[][n],int C[][n]) //A是路径长度矩阵,C是有向⽹络G的带权邻接矩阵{int i,j,k,next;int max=160;for(i=0;i<n;i++)//设置A和path的初值{for(j=0;j<n;j++){if(C[i][j]!=max)path[i][j]=j; //j是i的后继elsepath[i][j]=0;A[i][j]=C[i][j];}}for(k=0;k<n;k++)//做n次迭代,每次均试图将顶点k扩充到当前求得的从i到j的最短路径Pij上{for(i=0;i<n;i++){for(j=0;j<n;j++){if(A[i][j]>(A[i][k]+A[k][j])){A[i][j]=A[i][k]+A[k][j]; //修改长度path[i][j]=path[i][k]; //修改路径}}}}for(i=0;i<n;i++)//输出所有顶点对i,j之间的最短路径Pij的长度及路径 {for(j=0;j<n;j++){if(i!=j){printf("%d到%d的最短距离为",i+1,j+1);printf("%d\n",A[i][j]); //输出Pij的长度next=path[i][j]; //next为起点i的后继顶点printf("输出路径:\n");if(next==0)printf("%d到%d不可达\n",i+1,j+1);else//Pij存在{printf("%d",i+1);while(next!=j){printf("——>%d",next+1); //打印后继点next=path[next][j]; //继续找下⼀个后继点}printf("——>%d\n",j+1); //打印终点}printf("****************************************************\n");}}}}运⾏结果:——所有顶点对之间的最短路径:Floyd算法——(160为⽆穷远,不可达)1到2的最短距离为10输出路径:1——>2****************************************************1到3的最短距离为50输出路径:1——>4——>3****************************************************1到4的最短距离为30输出路径:1——>4****************************************************1到5的最短距离为60输出路径:1——>4——>3——>5****************************************************2到1的最短距离为160输出路径:2到1不可达****************************************************2到3的最短距离为50输出路径:2——>3****************************************************2到4的最短距离为160输出路径:2到4不可达**************************************************** 2到5的最短距离为60输出路径:2——>3——>5**************************************************** 3到1的最短距离为160输出路径:3到1不可达**************************************************** 3到2的最短距离为160输出路径:3到2不可达**************************************************** 3到4的最短距离为160输出路径:3到4不可达**************************************************** 3到5的最短距离为10输出路径:3——>5**************************************************** 4到1的最短距离为160输出路径:4到1不可达**************************************************** 4到2的最短距离为160输出路径:4到2不可达**************************************************** 4到3的最短距离为20输出路径:4——>3**************************************************** 4到5的最短距离为30输出路径:4——>3——>5**************************************************** 5到1的最短距离为160输出路径:5到1不可达**************************************************** 5到2的最短距离为160输出路径:5到2不可达**************************************************** 5到3的最短距离为160输出路径:5到3不可达**************************************************** 5到4的最短距离为160输出路径:5到4不可达****************************************************请按任意键继续. . .。

c语言实现弗洛伊德算法

c语言实现弗洛伊德算法

c语言实现弗洛伊德算法在计算机科学领域,弗洛伊德算法(Floyd algorithm)是一种用于寻找最短路径的算法。

该算法适用于所有类型的有向加权图,包括负权边,但不能处理带有负权环的图。

实现弗洛伊德算法的基本思路是使用动态规划的方法,利用中间节点来更新两个节点之间的最短路径。

具体步骤如下:1. 初始化邻接矩阵dist,dist[i][j]表示节点i到节点j的最短路径长度,如果节点i和节点j之间没有边,则dist[i][j]=INF (正无穷)。

2. 通过遍历所有中间节点k,更新dist[i][j]的值,更新公式为:dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])。

3. 最后得到的邻接矩阵dist即为所有节点之间的最短路径长度。

下面是使用C语言实现弗洛伊德算法的伪代码:1. 初始化邻接矩阵dist2. for(k=0; k<n; k++)for(i=0; i<n; i++)for(j=0; j<n; j++)dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);其中,n表示节点总数,dist为邻接矩阵,min为求两数中的最小值的函数。

在实际编程中,需要注意以下几点:1. 由于使用了三层循环,时间复杂度为O(n^3),所以当节点数较大时,算法的效率会比较低。

2. 在遍历中间节点k时,需要注意循环顺序,通常采用i->j->k 的循环顺序,可以有效减少不必要的计算。

3. 在使用邻接矩阵表示图时,需要注意边的权重,如果存在负权边,需要特殊处理。

综上所述,弗洛伊德算法是一种用于寻找最短路径的经典算法,具有广泛的应用价值。

在实际编程中,需要根据具体情况综合考虑算法效率和实现复杂度。

Floyd算法(二)之C++详解

Floyd算法(二)之C++详解

Floyd算法(⼆)之C++详解本章是弗洛伊德算法的C++实现。

⽬录1.2.3.4.更多内容:弗洛伊德算法介绍和Dijkstra算法⼀样,弗洛伊德(Floyd)算法也是⼀种⽤于寻找给定的加权图中顶点间最短路径的算法。

该算法名称以创始⼈之⼀、1978年图灵奖获得者、斯坦福⼤学计算机科学系教授罗伯特·弗洛伊德命名。

基本思想通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引⼊⼀个矩阵S,矩阵S中的元素a[i][j]表⽰顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

假设图G中顶点个数为N,则需要对矩阵S进⾏N次更新。

初始时,矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i] [j]=∞。

接下来开始,对矩阵S进⾏N次更新。

第1次更新时,如果"a[i][j]的距离" > "a[i][0]+a[0][j]"(a[i][0]+a[0][j]表⽰"i与j之间经过第1个顶点的距离"),则更新a[i][j]为"a[i][0]+a[0][j]"。

同理,第k次更新时,如果"a[i][j]的距离" > "a[i][k]+a[k][j]",则更新a[i][j]为"a[i][k]+a[k][j]"。

更新N次之后,操作完成!单纯的看上⾯的理论可能⽐较难以理解,下⾯通过实例来对该算法进⾏说明。

弗洛伊德算法图解以上图G4为例,来对弗洛伊德进⾏算法演⽰。

初始状态:S是记录各个顶点间最短路径的矩阵。

第1步:初始化S。

矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。

实际上,就是将图的原始矩阵复制到S中。

注:a[i][j]表⽰矩阵S中顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

floyd算法C++实现

floyd算法C++实现

#include <iostream>#include <iomanip>using namespace std;#define MAXV 100#define INF 32767typedef int InfoType;typedef int Vertex;typedef struct{ int no;InfoType info;} VertexType; //顶点类型typedef struct{ int edges[MAXV][MAXV];int n,e;VertexType vexs[MAXV];} MGraph; //图类型void Ppath(int path[][MAXV], int i, int j){ int k;k=path[i][j];if (k==-1) return; //递归出口Ppath(path,i,k);cout<<k<< " "; //输出kPpath(path,k,j);}void Dispath(int A[][MAXV],int path[][MAXV],int n) { int i,j;for (i=0;i<n;i++)for (j=0;j<n;j++)if (A[i][j]==INF){ if(i!=j) cout<< "从" <<i<< "到"<<j<< "不存在路径\n";}else{ cout<< "从" <<i<< " 到" <<j<< " 的路径为: "<< i <<" ";Ppath(path, i, j);cout<<j;cout<< " \t\t 路径长度为:"<<A[i][j]<<endl;}}void Floyd(MGraph g){ int A[MAXV][MAXV],path[MAXV][MAXV];int i,j,k;for (i=0;i<g.n;i++)for (j=0;j<g.n;j++){A[i][j]=g.edges[i][j];path[i][j]=-1;}for (k=0;k<g.n;k++)for (i=0;i<g.n;i++)for (j=0;j<g.n;j++)if (A[i][j]>(A[i][k]+A[k][j])){A[i][j]=A[i][k]+A[k][j];path[i][j]=k;}Dispath(A,path,g.n); //输出最短路径}void DispMat(MGraph g){int i,j;for(i=0;i<g.n;i++){for(j=0;j<g.n;j++)if(g.edges[i][j]==INF)cout <<setw(3)<<" ∞";else cout<<setw(3)<<g.edges[i][j];cout<<endl;}}void Floyd(MGraph g);void Ppath(int path[][MAXV], int i, int j) ;void Dispath(int A[][MAXV],int path[][MAXV],int n); void DispMat(MGraph g);void main(){int i,j;MGraph g;cout<<"输入邻接矩阵g总顶点数g.n和总边数g.e:"; cin>>g.n>>g.e;cout<<"输入邻接矩阵g的元素值:\n";for(i=0;i<g.n;i++){cout<<"第"<<i<<"行:";for(j=0;j<g.n;j++)cin>>g.edges[i][j];}cout<<"输出邻接矩阵g:\n";DispMat(g);cout<<"输出每对顶点之间的最短路径:\n";Floyd(g);cout<<endl;}C++语言:#include<fstream>#define Maxm 501using namespace std;ifstream fin; ofstream fout("APSP.out");int p,q,k,m; int Vertex,Line[Maxm];int Path[Maxm][Maxm],Dist[Maxm][Maxm];void Root(int p,int q){ if (Path[p][q]>0){ Root(p,Path[p][q]); Root(Path[p][q],q); }else { Line[k]=q; k++; } }int main(){ memset(Path,0,sizeof(Path));memset(Dist,0,sizeof(Dist));fin >> Vertex;for(p=1;p<=Vertex;p++)for(q=1;q<=Vertex;q++)fin >> Dist[p][q];for(k=1;k<=Vertex;k++)for(p=1;p<=Vertex;p++)if (Dist[p][k]>0) for(q=1;q<=Vertex;q++) if (Dist[k][q]>0){ if (((Dist[p][q]>Dist[p][k]+Dist[k][q])||(Dist[p][q]==0))&&(p!=q)) { Dist[p][q]=Dist[p][k]+Dist[k][q]; Path[p][q]=k; }} for(p=1;p<=Vertex;p++){ for(q=p+1;q<=Vertex;q++){ fout << "\n==========================\n";fout << "Source:" << p << '\n' << "Target " << q << '\n';fout << "Distance:" << Dist[p][q] << '\n';fout << "Path:" << p; k=2; Root(p,q);for(m=2;m<=k-1;m++) fout << "-->" << Line[m];fout << '\n'; fout << "==========================\n"; } } fin.close(); fout.close(); return 0; }注解:无法连通的两个点之间距离为0;Sample Input 7 00 20 50 30 00 00 00 20 00 25 00 00 70 00 50 25 00 40 25 50 00 30 00 40 00 55 00 00 00 00 25 55 00 10 70 00 70 50 00 10 00 50 00 00 00 00 70 50 00 Sample Output ========================== Source:1 Target 2 Distance:20 Path:1-->2 ========================== ========================== Source:1 Target 3 Distance:45 Path:1-->2-->3 ========================== ========================== Source:1 Target 4 Distance:30 Path:1-->4 ========================== ========================== Source:1 Target 5 Distance:70 Path:1-->2-->3-->5 ========================== ========================== Source:1 Target 6 Distance:80 Path:1-->2-->3-->5-->6 ========================== ========================== Source:1 Target 7 Distance:130 Path:1-->2-->3-->5-->6-->7 ========================== ========================== Source:2 Target 3 Distance:25 Path:2-->3 ========================== ========================== Source:2 Target 4 Distance:50 Path:2-->1-->4 ========================== ========================== Source:2 Target 5 Distance:50 Path:2-->3-->5 ==================================================== Source:2 Target 6 Distance:60 Path:2-->3-->5-->6 ========================== ========================== Source:2 Target 7 Distance:110 Path:2-->3-->5-->6-->7 ========================== ========================== Source:3 Target 4 Distance:40 Path:3-->4 ========================== ========================== Source:3 Target 5 Distance:25 Path:3-->5 ========================== ========================== Source:3 Target 6 Distance:35 Path:3-->5-->6 ========================== ========================== Source:3 Target 7 Distance:85 Path:3-->5-->6-->7 ========================== ========================== Source:4 Target 5 Distance:55 Path:4-->5 ========================== ========================== Source:4 Target 6 Distance:65 Path:4-->5-->6 ========================== ========================== Source:4 Target 7 Distance:115 Path:4-->5-->6-->7 ========================== ========================== Source:5 Target 6 Distance:10 Path:5-->6 ========================== ========================== Source:5 Target 7 Distance:60 Path:5-->6-->7 ========================== ========================== Source:6 Target 7 Distance:50 Path:6-->7 ==========================Matlab源代码为%floyd算法通用程序,输入a为赋权邻接矩阵%输出为距离矩阵D,和最短路径矩阵pathfunction [D,path]=floyd(a)n=size(a,1); D=a;path=zeros(n,n);for i=1:nfor j=1:nif D(i,j)~=inf path(i,j)=j;end end endfor k=1:n for i=1:n for j=1:nif D(i,k)+D(k,j)<D(i,j) D(i,j)=D(i,k)+D(k,j); path(i,j)=path(i,k); end end end end%配合floyd算法的后续程序,s为源点,t为宿点%L为长度,R为路由function [L,R]=router(D,path,s,t)L=zeros(0,0); R=s;while 1 if s==t L=fliplr(L); L=[0,L]; L=L(end);return end L=[L,D(s,t)]; R=[R,path(s,t)]; s=path(s,t); if s==0 return end end在M文件中建立。

《算法》C++代码Floyd

《算法》C++代码Floyd

《算法》C++代码Floyd今天写写最短路径的Floyd算法(有翻译叫弗洛伊德,不过这奇葩翻译⽤来读读就好……)。

这个算法的实质,⼴义来讲,其实是DP(动态规划)。

其实按说,算法应该先说说什么贪⼼、搜索、DP、⼆分之类的基本算法的,但我觉得太⼴的东西对没有基础的⼈来说讲起来不清楚,还是先写写⽐较典型的⼀些算法⽐较好。

⽽且这个系列是C++代码,并⾮过于详细的分析描述,那些以后有时间再写。

Floyd,求⼀个图中任意两点间的最短路径。

图中有N个点,则算法复杂度是O(N³),空间复杂度是O(N²),编程复杂度极低。

先说下其中的基本操作,若i->j的当前路径不如i->k->j短,则更新最短路。

这个操作叫做“松弛操作”,是最短路径算法中很基础的操作,就像排序中的“交换操作”⼀样基础,Floyd、Dijkstra、SPFA都是基于这个操作的。

写成代码就是: if(d[i][j]<d[i][k]+d[k][j]) d[i][j]=d[i][k]+d[k][j];Floyd算法的思想是,以每个点分别为中间结点(上式中的k),去更新所有路径。

例如对于u->v来说,最短路径是u->k1->k2->k3->k4->v,假设k1<k3<k2<k4,那么实际过程就是: 0、算法初始化,定义⼀个d数组,存的是初始任意两点间距离,若存在边u->v,则d[u][v] = u->v;若不存在边u->v,则d[u][v] = ∞(其实就相当于图的邻接矩阵,只不过没有的边补成了∞) 1、不妨设原本d[u][v] = ∞ 2、在k=k1时,d[u][k2] = d[u][k1]+d[k1][k2] = u->k1->k2; 3、在k=k3时,d[k2][k4] = d[k2][k3]+d[k3][k4] = k2->k3->k4; 4、在k=k2时,d[u][k4] = d[u][k2]+d[k2][k4] = u->k1->k2->k3->k4; 5、在k=k4时,d[u][v] = d[u][k4]+d[k4][v] = u->k1->k2->k3->k4->v; 6、算法结束,d[u][v]中所存为最终最短路径,所有点对皆是如此,所以全部过程完结之后,任意两点的最短路径就都求出来了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//Floyd算法
//求网G(用邻接矩阵表示)中任意两点间最短路径
//D[][]是最短路径长度矩阵,path[][]最短路径标志矩阵
void Floyd(MGraph * G,int path[][MAX_VERTEX_NUM],int D[][MAX_VERTEX_NUM],int n){
int i,j,k;
{
prev[i] = 0;
}
else
{
prev[i] = v;
}
}
dist[v] = 0;
s[v] = 1;//源节点作为最初的s子集
for (i = 1; i < n; i++)
{
int temp = maxint;
int u = v;
//加入具有最小代价的邻居节点到s子集
for (j = 1; j <= n; j++)
MGraph G;
int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//v到各顶点的最短路径向量
int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//v到各顶点最短路径长度向量
//初始化
AdjType a[MAX_VERTEX_NUM][MAX_VERTEX_NUM]={
int *dist;//最短路径代价
int *prev;//前一跳节点空间
printf("please input the node number: ");
scanf("%d",&n);
printf("please input the cost status:\n");
cost=(int **)malloc(sizeof(int)*(n+1));
{
int newdist = dist[u] + cost[u][j];
if (newdist < dist[j])
{
dist[j] = newdist;
prev[j] = u;
}
}
}
}
}
//主函数,主要做输入输出工作
void main()
{
int i,j,t;
int n,v,u;
int **cost;//代价矩阵
printf("%d\t",D[i][j]);//输出Vi到Vj的最短路径长度
k=path[i][j];//取路径上Vi的后续Vk
if(k==-1){
printf("There is no path between V%d and V%d\n",i,j);//路径不存在
}else{
printf("最短路径为:");
}
{
if ((!s[j]) && (dist[j] < temp))
{
u = j;
temp = dist[j];
}
}
s[u] = 1;
//计算加入新的节点后,更新路径使得其产生代价最短
for (j = 1; j <= n; j++)
{
if ((!s[j]) && (cost[u][j] < maxint))
}
dist = (int *)malloc(sizeof(int)*n);
prev = (int *)malloc(sizeof(int)*n);
printf("please input the source node: ");
scanf("%d",&v);
//调用dijkstra算法
Dijkstra(n, v, dist, prev, cost);
int *s ;//定义具有最短路径的节点子集s
s = (int *)malloc(sizeof(int) * n);
//初始化最小路径代价和前一跳节点值
for (i = 1; i <= n; i++)
{
dist[i] = cost[v][i];
s[i] = 0;
if (dist[i] == maxint)
{0,12,18,MAX_INT,17,MAX_INT},
{12,0,10,3,MAX_INT,5},
{18,10,0,MAX_INT,21,11},
{MAX_INT,3,MAX_INT,0,MAX_INT,8},
{17,MAX_INT,21,MAX_INT,0,16},
{MAX_INT,5,11,8,16,0}
for (i = 1; i <= n; i++)
{
cost[i]=(int *)malloc(sizeof(int)*(n+1));
}
//输入代价矩阵
for (j = 1; j <= n; j++)
{
for (t = 1; t <= n; t++)
{
scanf("%d",&cost[j][t]);
}
for(i=0;i<n;i++){//初始化
for(j=0;j<n;j++){
if(G->A[i][j]<MAX_INT){
path[i][j]=j;
}else{
path[i][j]=-1;
}
D[i][j]=G->A[i][j];
}
}
for(k=0;k<n;k++){//进行n次试探
for(i=0;i<n;i++){
};
for(i=0;i<n;i++){
for(j=0;j<n;j++){
G.A[i][j]=a[i][j];
}
}
Floyd(&G,path,D,6);
for(i=0;i<n;i++){//输出每对顶点间最短路径长度及最短路径
for(j=0;j<n;j++){
printf("V%d到V%d的最短长度:",i,j);
for(j=0;j<n;j++){
if(D[i][j]>D[i][k]+D[k][j])
{
D[i][j]=D[i][k]+D[k][j];//取小者
path[i][j]=path[i][k];//改Vi的后继
}
}
}
}
}
int main(){
int i,j,k,v=0,n=6;//v为起点,n为顶点个数
return 0;
}
//Dijkstra算法实现函数
#i nclude<stdio.h>
#i nclude <stdlib.h>
void Dijkstra(int n,int v,int dist[],int prev[],int **cost)
{
int i;
int j;
int maxint = 65535"(V%d",i);//输出Vi的序号i
while(k!=j){//k不等于路径终点j时
printf(",V%d",k);//输出k
k=path[k][j];//求路径上下一顶点序号
}
printf(",V%d)\n",j);//输出路径终点序号
}
printf("\n");
}
}
system("pause");
相关文档
最新文档