多源最短路径——floyd-Warshall算法的拓展

来源:互联网 发布:mac海马模拟器怎么用 编辑:程序博客网 时间:2024/06/06 01:28

多源最短路径——floyd-Warshall算法的拓展

关于多源最短路径算法,我看了一下别人的博客——gooddeep的博客
总之核心代码就是五行。
这里写图片描述

for(int k=1;k<5;k++)    for(int i=1;i<5;i++)        for(int j=1;j<5;j++)            if(infor[i][j]>infor[i][k]+infor[k][j])            infor[i][j]=infor[i][k]+infor[k][j]);

实际上,这个算法遍历整个矩阵,不断地将两地之间可以缩小的距离计算出来,并不断更新,且每一次的更新都是建立在前一次更新的基础上。
例:
对于本次更新的数据:infor[i][j]将更新为infor[i][k] + infor[k][j]
infor[i][k] 与 infor[k][j]又是在上一次的更新中而来。
如此一来,我们最后得到的数据就是遍历了全图后,得到的最短路径的长度。
但是同样,问题来了,我们虽然得到了最短路径的长度,但我们还是不知道路该怎么走。

  • 实际上,最短路径就是将我们经过的节点都记录下来,即多加一行代码,将节点k记录下来。
  • 另外,我们注意到路径每一次更新都是建立在前一次路径更新的基础上的,所以我们需要给矩阵的每一个格都建立一个独立的容器,记录其经过的节点。像这样,所有的容器汇集在一起就好像形成了一个新的矩阵,我们称其为road[][] 路径矩阵。显然这个矩阵会随着infor[][]长度矩阵的更新而更新,最终我们将得到最短路径的所有节点。
  • 路径每一次更新都是建立在前一次路径更新的基础上的,所以有一般情况
    road[i][j]=road[i][k]+k+road[k][j];

    我用的是c++标准库里面的vector容器,实际上用字符串string可能会更简单。
    首先建立一个4*4的指针矩阵,类型为vector。每一个指针都指向一个容器对应一个格的路径。
    对于road[i][j]=road[i][k]+k+road[k][j];的操作即将road[i][k]与k与road[k][j]的对应的容器数据,顺序连接起来,并赋给road[i][j]对应的容器。
    另外在创建一个函数,用于实现road[i][j]=road[i][k]+k+road[k][j];
    注:elc为vector的指针类型的别名

void chear(elc a,elc b,int z,elc c) {      *a=*b;    a->push_back(z);    int csize=c->size();    for(int i=0;i<csize;i++)    {        a->push_back(c->at(i));     } }
实际代码如下
#include<iostream>#include<vector> using namespace std; typedef vector<int>* elc;  //为vector<int>的指针类型取个别名elc#define wx 10000void printRoad(elc x){    for(int i=0;i<x->size();i++)    cout<<x->at(i)<<"->";}//路径的输出函数 void chear(elc a,elc b,int z,elc c) {      *a=*b;    a->push_back(z);    int csize=c->size();    for(int i=0;i<csize;i++)    {        a->push_back(c->at(i));     } }//road[i][j]=road[i][k]+k+road[k][j];的实现方式void print(int *a){    for(int i=1;i<5;i++)    {        for(int j=1;j<5;j++)        {                cout<<*(a+i*5+j)<<"  ";        }           cout<<endl;    }    return;}//输出infor数组int main(){    vector<int> *road[5][5];//建立road路径数组,road[0][*]与road[*][0]舍弃不用    for(int i=1;i<5;i++)    {        for(int j=1;j<5;j++)        {            road[i][j]=new vector<int>;        }    }//为每一个指针开辟一个容器空间,初始为空    int infor[5][5]={        0,0,0,0,0,        0,0,2,6,4,        0,wx,0,3,wx,        0,7,wx,0,1,        0,5,wx,12,0    };初始infor矩阵    cout<<"============First=========="<<endl;    print(infor[0]);    for(int k=1;k<5;k++)    {        for(int i=1;i<5;i++)        {            for(int j=1;j<5;j++)            {                if(infor[i][j]>infor[i][k]+infor[k][j])                {                    infor[i][j]=infor[i][k]+infor[k][j];//更新infor数组                    chear(road[i][j],road[i][k],k,road[k][j]);//更新路径容器                }            }        }    }    cout<<"==========next========"<<endl;    print(infor[0]);    for(int i=1;i<5;i++)//将所有路径输出    {        for(int j=1;j<5;j++)        {                cout<<"==========="<<i<<"->"<<j<<"========"<<endl;                cout<<"It needs "<<infor[i][j]<<endl;                cout<<i<<"->";                    printRoad(road[i][j]);                    cout<<j<<endl;        }       }    return 0;}

运行结果:
这里写图片描述这里写图片描述

阅读全文
1 0
原创粉丝点击