算法描述:

  Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法。从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。

核心思路:通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。

算法过程:

  把图用邻接距阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。定义一个距阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。    在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。比如,要寻找从V5到V1的路径。根据D,假如D(5,1)=3则说明从V5到V1经过V3,路径为{V5,V3,V1},如果D(5,3)=3,说明V5与V3直接相连,如果D(3,1)=1,说明V3与V1直接相连。

优缺点分析: 
  Floyd算法适用于APSP(All Pairs Shortest Paths),稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法。  
  优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单;  
  缺点:时间复杂度为O(n3),比较高,不适合计算大量数据。

代码实现:

#include <stdio.h>
#include <stdlib.h>
#define MAXVERTEX 8
#define INF 65535
typedef char VertexType;
typedef int EdgeType;
typedef struct MGraph
{
VertexType vertex[MAXVERTEX];
EdgeType edge[MAXVERTEX][MAXVERTEX];
int numvex;
int numedge;
}MGraph; static int D[MAXVERTEX][MAXVERTEX];
static int P[MAXVERTEX][MAXVERTEX]; void CreateMGraph(MGraph *G)
{
int i = 0,j = 0,k = 0,w = 0;
VertexType c;
printf("请输入顶点数和边数:\n");
scanf("%d,%d",&G->numvex,&G->numedge);
for(i = 0;i < G->numvex;i++)
{
for(j = 0;j < G->numvex;j++)
{
if(i == j)
{
G->edge[i][j] = 0;
}
else
{
G->edge[i][j] = INF;
}
}
}
printf("请输入顶点的值:\n");
fflush(stdin);
scanf("%c",&c);
while(i < G->numvex)
{
if(c == '\n')
break;
else
{
G->vertex[i] = c;
i++;
scanf("%c",&c);
}
}
fflush(stdin);
for(k = 0;k < G->numedge;k++)
{
printf("请输入边vi-vj所依附的顶点下标 i 和 j,以及权重w:\n");
scanf("%d,%d,%d",&i,&j,&w);
G->edge[i][j] = w;
G->edge[j][i] = G->edge[i][j];
}
} void Floyd(MGraph *G)
{
int i,j,k;
//初始化
for(i = 0;i < G->numvex;i++)
{
for(j = 0;j < G->numvex;j++)
{
D[i][j] = G->edge[i][j];
P[i][j] = j;
}
}
for(k = 0;k < G->numvex;k++)
{
for(i = 0;i < G->numvex;i++)
{
for(j = 0;j < G->numvex;j++)
{
if(D[i][j] > D[i][k] + D[k][j])
{
D[i][j] = D[i][k] + D[k][j];
P[i][j] = P[i][k];
}
}
}
}
printf("\n P矩阵为:\n");
for(i = 0;i < G->numvex;i++)
{
for(j = 0;j < G->numvex;j++)
{
printf("%d ",P[i][j]);
}
printf("\n");
}
}
void PrintPath(MGraph *G)
{
int i,j,k;
for(i = 0;i < G->numvex;i++)
{
for(j = i+1;j < G->numvex;j++)
{
printf("V%d-V%d minimum weight:%d ",i,j,D[i][j]);
k = P[i][j];
printf("Path: V%d",i);
while(k != j)
{
printf("-->V%d",k);
k = P[k][j];
}
printf("-->V%d\n",j);
}
printf("\n");
}
} int main()
{
MGraph G;
CreateMGraph(&G);
Floyd(&G);
PrintPath(&G);
return 0;
}

  

Floyd算法(弗洛伊德算法)的更多相关文章

  1. Floyd算法(弗洛伊德算法) 百度百科

    核心代码 for(int k=1; k<=NODE; ++k)//对于每一个中转点 for(int i=0; i<=NODE; ++i)//枚举源点 for(int j=0; j<= ...

  2. 经典问题----最短路径(Floyd弗洛伊德算法)(HDU2066)

    问题简介: 给定T条路,S个起点,D个终点,求最短的起点到终点的距离. 思路简介: 弗洛伊德算法即先以a作为中转点,再以a.b作为中转点,直到所有的点都做过中转点,求得所有点到其他点的最短路径,Flo ...

  3. 弗洛伊德算法(Floyd算法)

    原博来自http://www.cnblogs.com/skywang12345/ 弗洛伊德算法介绍 和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的 ...

  4. 弗洛伊德算法(Floyd )

    package com.rao.graph; /** * @author Srao * @className Floyd * @date 2019/12/11 18:43 * @package com ...

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

    转载:https://blog.csdn.net/qq_35644234/article/details/60875818 Floyd算法的介绍 算法的特点 弗洛伊德算法是解决任意两点间的最短路径的一 ...

  6. 数据结构与算法——弗洛伊德(Floyd)算法

    介绍 和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特 ...

  7. Floyd最短路算法

    Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...

  8. 数据结构C语言版 弗洛伊德算法实现

    /* 数据结构C语言版 弗洛伊德算法  P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...

  9. 【啊哈!算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

随机推荐

  1. oracle 经典语句集合

    1.一列转多行 方法一: select a.id,  substr(','||a.name||',',instr(','||a.name,',',1,b.rn)+1,    instr(a.name| ...

  2. /调整button的title的位置

    [bottomButton setTitleEdgeInsets:UIEdgeInsetsMake(10, -190, 10, 44)];  //上左下右            ||button.co ...

  3. java一点东西(3)

    运算符的优先级:()优先级最高 ! ++ -- 单目运算符 * / % + - > < <= >= == != && || 赋值符号 面向对象设计步骤:1.发现 ...

  4. dropdownlist绑定和选中

    最近在使用dropdownlist控件,对于这个控件,目前我知道的会使用两种方式去绑定数据,现在将这两种方式分享给大家: 现在是后台数据绑定 protected void BindCarID() { ...

  5. Bootstrap 静态分页 和 jquery_pagination插件 动态分页

    第一种Bootstrap 实例 - 默认的分页 <!DOCTYPE html> <html> <head> <title>Bootstrap 实例 - ...

  6. https://github.com/aptana/studio3/releases aptana

    https://github.com/aptana/studio3/releases  aptana

  7. Python中def的用法

    def定义了一个模块的变量,或者说是类的变量.它本身是一个函数对象.属于对象的函数,就是对象的属性. def func():    return 2print func() # 1func = 5pr ...

  8. C语言基础10

    栈区间:在函数内部声明的变量都存放在栈区间,比如int char 数组 结构体 指针,只管申请,系统会自动帮我们回收,收回的时间是作用域结束之后,遵循的原则是"先进后出". int ...

  9. ExtJs Model之convert的使用

    convert: function(value,record){} value:为当前属性的值,record.get('属性')用来获取其他属性的值. 以下案例是:将年龄减去2. Ext.define ...

  10. 手机天猫nba项目总结

    页面逻辑: 技术统计 比赛竞猜 猜你喜欢 进入页面时,获取服务器的当前时间.然后进行页面上的每秒递增.1.每隔n秒向后台发送请求,获取最新比分信息,球队图像,球员信息.然后更改页面.2.每隔n秒向后台 ...