图的最短路径Dijkstra+Floyed算法

来源:互联网 发布:好又便宜的淘宝男装店 编辑:程序博客网 时间:2024/05/16 00:45

/* *2014-5-22 *摘自http://blog.csdn.net/jnu_simba/article/details/8871794 **/#include<iostream>using namespace std;#define MAXEDGE 20#define MAXVEX 20#define INFINITY 65535typedef struct{    int vexs[MAXVEX];    int arc[MAXVEX][MAXVEX];    int numVertexes, numEdges;} MGraph;typedef int PathArc[MAXVEX];typedef int ShortPathTable[MAXVEX];/* 构建图 */void CreateMGraph(MGraph *G){    int i, j;    /* printf("请输入边数和顶点数:"); */    G->numEdges = 16;    G->numVertexes = 9;    for (i = 0; i < G->numVertexes; i++)/* 初始化图 */        G->vexs[i] = i;    for (i = 0; i < G->numVertexes; i++){/* 初始化图 */        for ( j = 0; j < G->numVertexes; j++){            if (i == j)                G->arc[i][j] = 0;            else                G->arc[i][j] = G->arc[j][i] = INFINITY;        }    }    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(i = 0; i < G->numVertexes; i++)        for(j = i; j < G->numVertexes; j++)            G->arc[j][i] = G->arc[i][j];}/*  Dijkstra算法,求有向网G的pos顶点到其余顶点v的最短路径P[v]及带权长度D[v] *//*  P[v]的值为前驱顶点下标,D[v]表示pos到v的最短路径长度和 *//*  pos 取值 0~MG.numVertexs-1 */void ShortestPath_Dijkstra(MGraph MG, int pos, PathArc P, ShortPathTable D){    int v, w, k, min;    int final[MAXVEX];/* final[w]=1表示求得顶点pos至w的最短路径 *//*初始化*/    for (v = 0; v < MG.numVertexes; v++){        final[v] = 0;/* 全部顶点初始化为未知最短路径状态 */        D[v] = MG.arc[pos][v];/* 将与pos点有连线的顶点加上权值 */        P[v] = 0;/* 初始化路径数组P为0  */    }    D[pos] = 0; /*说明源点pos自身的长度为0 */    P[pos] = -1; /* -1表示自身无前驱顶点*/    final[pos] = 1;/* pos至pos不需要求路径 */    /* 开始主循环,每次求得pos到某个v顶点的最短路径 */    for (v = 1; v < MG.numVertexes; v++){        min = INFINITY;/* 当前所知离pos顶点的最近距离 */        for (w = 0; w < MG.numVertexes; w++){/* 寻找剩余未确认路径的节点中,离pos最近的顶点 */            if (final[w]==0 && D[w] < min){                k = w;                min = D[w];/* w顶点离pos顶点更近 */            }        }        final[k] = 1;/* 将目前找到的最近的顶点置为1 */        for (w = 0; w < MG.numVertexes; w++){/* 修正当前最短路径及距离 若D(pos->k->w)<D(w),则更新*/            if (!final[w] && (min + MG.arc[k][w] < D[w])){                /*  说明找到了更短的路径,修改D[w]和P[w] */                D[w] = min + MG.arc[k][w];/* 修改当前路径长度 */                P[w] = k;            }        }    }    /* 结束循环,若P[w] = pos;说明顶点w的前驱为pos */}int main(void){    MGraph MG;    PathArc P;    ShortPathTable D;    int i, j, pos = 0;    CreateMGraph(&MG);    ShortestPath_Dijkstra(MG, pos, P, D);    cout << "逆序最短路径如下:" << endl;    for (i = 8; i >= 0; i--)    {        j = i;        while (P[j] != -1 && P[j] != 0)        {            cout << "v" << j << "<-" << "v" << P[j] << "  ";            j = P[j];        }        cout << "v" << j << "<-" << "v" << pos << "  ";        cout << endl;    }    cout << endl;    return 0;}/*逆序最短路径如下:v8->v7  v7->v6  v6->v3  v3->v4  v4->v2  v2->v1  v1->v0v7->v6  v6->v3  v3->v4  v4->v2  v2->v1  v1->v0v6->v3  v3->v4  v4->v2  v2->v1  v1->v0v5->v4  v4->v2  v2->v1  v1->v0v4->v2  v2->v1  v1->v0v3->v4  v4->v2  v2->v1  v1->v0v2->v1  v1->v0v1->v0v0->v0*/


D算法是求所有节点到指定节点的方法,下面的Floyed算法是求任一节点到其他所有节点的最短路径问题,问题稍微复杂点,但代码却出奇的简洁。


#include <stdio.h>#define MAXVEX 20#define INFINITY 65535typedef struct{int vexs[MAXVEX];int arc[MAXVEX][MAXVEX];int numVertexes, numEdges;}MGraph;/* 构造图 */void CreateMGraph(MGraph *G){int i, j;/* printf("请输入边数和顶点数:"); */G->numEdges=16;G->numVertexes=9;for (i = 0; i < G->numVertexes; i++)/* 初始化图 */{G->vexs[i]=i;}for (i = 0; i < G->numVertexes; i++)/* 初始化图 */{for ( j = 0; j < G->numVertexes; j++){if (i==j)G->arc[i][j]=0;elseG->arc[i][j] = G->arc[j][i] = INFINITY;}}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(i = 0; i < G->numVertexes; i++){for(j = i; j < G->numVertexes; j++){G->arc[j][i] =G->arc[i][j];}}}/* Floyd算法,求网图G中各顶点v到其余顶点w的最短路径P[v][w]及带权长度D[v][w]。 */    void ShortestPath_Floyd(MGraph G, int P[][MAXVEX], int D[][MAXVEX]){    int v,w,k;    for(v=0; v<G.numVertexes; ++v) /* 初始化D与P */  {        for(w=0; w<G.numVertexes; ++w)  {D[v][w]=G.arc[v][w];/* D[v][w]值即为对应点间的权值 */P[v][w]=w;/* 初始化P */}}for(k=0; k<G.numVertexes; ++k)   {for(v=0; v<G.numVertexes; ++v)  {        for(w=0; w<G.numVertexes; ++w)    {if (D[v][w]>D[v][k]+D[k][w]){/* 如果经过下标为k顶点路径比原两点间路径更短 */D[v][w]=D[v][k]+D[k][w];/* 将当前两点间权值设为更小的一个 */P[v][w]=P[v][k];/* 路径设置为经过下标为k的顶点 */}}}}}int main(void){    int v,w,k;  MGraph G;    int P[MAXVEX][MAXVEX];    int D[MAXVEX][MAXVEX]; /* 求某点到其余各点的最短路径 */   CreateMGraph(&G);ShortestPath_Floyd(G,P,D);  printf("各顶点间最短路径如下:\n");    for(v=0; v<G.numVertexes; ++v)   {        for(w=v+1; w<G.numVertexes; w++)  {printf("v%d-v%d weight: %d ",v,w,D[v][w]);k=P[v][w];/* 获得第一个路径顶点下标 */printf(" path: %d",v);/* 打印源点 */while(k!=w)/* 如果路径顶点下标不是终点 */{printf(" -> %d",k);/* 打印路径顶点 */k=P[k][w];/* 获得下一个路径顶点下标 */}printf(" -> %d\n",w);/* 打印终点 */}printf("\n");}printf("最短路径D\n");for(v=0; v<G.numVertexes; ++v)  {        for(w=0; w<G.numVertexes; ++w)    {printf("%d\t",D[v][w]);}printf("\n");}printf("最短路径P\n");for(v=0; v<G.numVertexes; ++v)  {        for(w=0; w<G.numVertexes; ++w)    {printf("%d ",P[v][w]);}printf("\n");}return 0;}



0 0
原创粉丝点击