[图算法]Floyd算法改进之打印路径.

[图算法]Floyd算法改进之打印路径.

Floyd算法虽然形式上简单,但功能强大,除了可以求出图中任意两点间的最短路径外

(: http://blog.csdn.net/EmilMatthew/archive/ 2005/08/10/450051.aspx)

 

还能再稍加修改的情况下,通过一个信息矩阵来得出任意两点间最短路径的中结点的信息.

具体的算法如下:

Step1:

1)      准备原带权矩阵wArr及结点信息矩阵wAns.wAns中的元素wAns[i][j]表示的是从结点i到结点j的最短路径中,位于结点j前的那个结点;在原图权值矩阵wArr,如果两个结点这之前在起始图中没有直接相连的路径,则用一个大整数表示它们间的权值.      

2)      For i<-1 to len

3)              For j<-1 to len

4)               If  mapArr[i][j]<IntLimit then

5)                 ansArr[i][j]=i;//如果原图中两个结点I,j连通,则在j结点前的最近结点为i

6)           End if

7)          Next j

8)      Next i

Step2:

1)      Floy最短路径算法中加入对结点信息矩阵wAns相关的处理信信息,其实就多加了一句.

2)      For k<-0 to len

3)                     For i<-0 to len

4)                            For j<-0 to len

5)                                   newLen<-mapAr)[i][k]+mapArr[k][j]

6)                                   If (newLen<mapArr[i][j]) then

7)                                          mapArr[i][j]<-newLen;

8)                     ansArr[i][j]<-ansArr[k][j];//在找到最短路径后,更新结点信息矩阵wAns,使ansArr[i][j]始终表示的是从结点i到结点j的最短路径中,位于结点j前的那个结点

9)                                   End if

10)                         Next j

11)           Next i

12)   Next k

至此,伴随着Floyd算法进行,最短路径的结点信息矩阵wAns构造也完成了.

 

 

 

Step2:

ansArr中内容的读取

由于ansArr[i][j]表示的是从结点i到结点j的最短路径中,位于结点j前的那个结点,所以,如果要获得由Ij的最短路径上的各个结点的信息,可以通过从j一直寻访到I的方式来做,将果存放在一个栈中,最后,将栈中内容弹出,即得由Ij的最短

路径上各结点的信息.

具体的算法如下:

1) 给出初结点startNodeId和终止结点endNodeId

2) 初始结点压栈myStack.push(endNodeId)

3) 得到中介结点midNode=wAns[startNodeId][endNodeId]

4) 中介点压栈myStack.push(midNode);

5)                                                                while(midNode!=startNodeId)

//如果中介点不是起始点,则进入循环,直到找起始点为止.

                                   {

6)                                       midNode=wAns[startNodeId][midNode];

7)                                       myStack.push(midNode);

                                   }

8)                  while(!myStack.isEmpty())//输出栈中的信息,即得最路径上各结点的信息.

9)                                       print myStack.pop()

算法结束.

下面给出本算法的实现,在这里,除了输出两个结点的信息外,还输了图中所有结点间最短路径的信息.

/*The floyd2 algorithm ,with could trace out the shortest path node’s information

Made by EmilMatthew 05/8/13*/

/*A very simple stack */

#include <stdlib.h>

#ifndef SIMPLESTACK_H

       #define SIMPLESTACK_H

       #define StackDataType long

       class SimpleStack

       {

              public:

                     SimpleStack()

                     {

                            mLen=100;

                            mData=new StackDataType[mLen];

                            nextSlot=0;

                     }

                     SimpleStack(int len)

                     {

                            mLen=len;

                            mData=new StackDataType[mLen];

                            nextSlot=0;

                     }

                     ~SimpleStack()

                     {

                            mLen=100;

                            delete []mData;

                            nextSlot=0;

                     }

                     void deleteAllValues()

                     {    

                            delete []mData;

                            nextSlot=0;

                     }

                     void push(StackDataType inVal);

                     StackDataType pop();

                     StackDataType top();

                     bool isEmpty()

                     {

                            return nextSlot==0;

                     }

              private:

                     StackDataType* mData;

                     int mLen;

                     int nextSlot;

       };

#endif

 

 

 

/*SimpleStack.cpp*/

#include "SimpleStack.h"

#include "MyAssert.h"

#include <stdio.h>

 

 

 

 

 

 

void SimpleStack::push(StackDataType inVal)

{

       /*to enlarge the capacity of the arr*/

if(nextSlot>=mLen)

       {

              int i=0;

              StackDataType* tmpArr;

              /*memroy apply*/

              tmpArr=new StackDataType[nextSlot];

              assertF(tmpArr!=NULL,"in StackDataType SimpleStack::pop tmpArr is NULL/n"); 

                     /*copy from mData to tmpArr*/

                     for(i=0;i<nextSlot;i++)

                            tmpArr[i]=mData[i];

                     /*free the space before apply new space*/

                     delete []mData;

              mLen+=100;/*stack length be bigger*/

 

 

 

              mData=new StackDataType[mLen];/*memory apply*/

                     for(i=0;i<nextSlot;i++)

                            mData[i]=tmpArr[i];

              delete []tmpArr;/*free the space of the tmp pointer*/

       }

       mData[nextSlot++]=inVal;

}

 

 

 

StackDataType SimpleStack::pop()

{

       assertF(!isEmpty(),"in StackDataType SimpleStack::pop the stack is Empty./n");

       return mData[--nextSlot];

}

 

 

 

StackDataType SimpleStack::top()

{

       assertF(!isEmpty(),"in StackDataType SimpleStack::top the stack is Empty./n");

       return mData[nextSlot-1];    

}

 /*Floy2 updated algorithm,the ansArr will return the node infomation*/
void Floyd2(Type*** mapArr,Type*** ansArr,int len)
 {
  int i,j,k;/*iterator index*/
  Type newLen;/*tmp shortest len*/
  assertF(*mapArr!=NULL,"in Floyd2 *mapArr is NULL");
     assertF(*ansArr!=NULL,"in Floyd2 *ansArr is NULL");
 
  /*Algorithm Core Reason*/
  /*Mk+1[i,j]=1 <-> Mk[i,k+1]=1&&Mk[k+1,j]=1*/
  for(i=0;i<len;i++)
   for(j=0;j<len;j++)
     if((*mapArr)[i][j]<IntLimit)
      (*ansArr)[i][j]=i;
  
  for(k=0;k<len;k++)
   for(i=0;i<len;i++)
    for(j=0;j<len;j++)
    {
     newLen=(*mapArr)[i][k]+(*mapArr)[k][j];
     if(newLen<(*mapArr)[i][j])
     {
      (*mapArr)[i][j]=newLen;
      (*ansArr)[i][j]=(*ansArr)[k][j];
     }
    }
 }

 /*Floy2 updated algorithm,the ansArr will return the node infomation*/
void Floyd2(Type*** mapArr,Type*** ansArr,int len)
 {
  int i,j,k;/*iterator index*/
  Type newLen;/*tmp shortest len*/
  assertF(*mapArr!=NULL,"in Floyd2 *mapArr is NULL");
     assertF(*ansArr!=NULL,"in Floyd2 *ansArr is NULL");
 
  /*Algorithm Core Reason*/
  /*Mk+1[i,j]=1 <-> Mk[i,k+1]=1&&Mk[k+1,j]=1*/
  for(i=0;i<len;i++)
   for(j=0;j<len;j++)
     if((*mapArr)[i][j]<IntLimit)
      (*ansArr)[i][j]=i;
  
  for(k=0;k<len;k++)
   for(i=0;i<len;i++)
    for(j=0;j<len;j++)
    {
     newLen=(*mapArr)[i][k]+(*mapArr)[k][j];
     if(newLen<(*mapArr)[i][j])
     {
      (*mapArr)[i][j]=newLen;
      (*ansArr)[i][j]=(*ansArr)[k][j];
     }
    }
 }

 

#include "SimpleStack.h"

#include "MyAssert.h"

#include "Global.h"

#include "Ulti.h"

#include "GraphAlgorithm.h"

#include <iostream.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

 

 

 

char *inFileName="inputData.txt";

/*

       input data specification

       row,col

       wArr

       {

              , , , ,     

              , , , ,

              , , , ,

       }

*/

char *outFileName="outputData.txt";

#define DEBUG 1

 

 

 

void main(int argc,char* argv[])

{

       FILE *inputFile;/*input file*/

       FILE *outputFile;/*output file*/

 

 

 

       double startTime,endTime,tweenTime;/*time callopsed info*/

      

       int row,col;

      

       int startNodeId=0,endNodeId=0;

 

 

 

       int i,j;/*iterator index*/

       int n;/*arr deminision for squre matrix*/

       SimpleStack myStack;

       Type** wArr;

       Type** wAns;

       Type midNode;

 

 

 

       /*input file open*/

       if(argc>1)strcpy(inFileName,argv[1]);

       assertF((inputFile=fopen(inFileName,"rb"))!=NULL,"input file error");

       printf("input file open success/n");

      

       /*outpout file open*/

       if(argc>2)strcpy(outFileName,argv[2]);

       assertF((outputFile=fopen(outFileName,"wb"))!=NULL,"output file error");

       printf("output file open success/n");

      

      

       fscanf(inputFile,"%d,%d,",&row,&col);

       /*Memory apply*/

       wArr=(Type**)malloc(sizeof(Type*)*row);

       for(i=0;i<row;i++)

              wArr[i]=(Type*)malloc(sizeof(Type)*col);

      

       wAns=(Type**)malloc(sizeof(Type*)*row);

       for(i=0;i<row;i++)

              wAns[i]=(Type*)malloc(sizeof(Type)*col);

             

       /*Read 2d arr data*/

       for(i=0;i<row;i++)

       {

              for(j=0;j<col-1;j++)

                     fscanf(inputFile,"%d,",&wArr[i][j]);

              fscanf(inputFile,"%d;",&wArr[i][j]);           

       }    

       /*big length adjust*/

       for(i=0;i<row;i++)

              for(j=0;j<col;j++)

                     if(wArr[i][j]==-1)wArr[i][j]=IntLimit; 

      

       show2DArrInt(wArr,row,col);

      

       fscanf(inputFile,"%d,%d,",&startNodeId,&endNodeId);

       printf("start:%d,end:%d.",startNodeId,endNodeId);

#if  DEBUG

       printf("/n*******start of test program******/n");

       printf("now is runnig,please wait.../n");

       startTime=(double)clock()/(double)CLOCKS_PER_SEC;

       /******************Core program code*************/

              /*argu prepare*/

              assertF(col==row,"in test col!=row");

              n=row;/*get the size of square matrix*/

             

              Floyd2(&wArr,&wAns,n);

      

              fprintf(outputFile,"===Output the node info matrix.===/r/n");   

              output2DArrInt(wAns,row,col,outputFile);

              fprintf(outputFile,"===End of output the node info matrix.===/r/n");

                    

              assertF(startNodeId>=0&&endNodeId>=0&&startNodeId<n&&endNodeId<n,"in test,start and end id is illegal/n");

             

            

              /*Trace out all the shortest  path node information*/

              for(i=0;i<row;i++)

              {

                     for(j=0;j<col;j++)

                     {

                                   startNodeId=i;

                                   endNodeId=j;

                                   myStack.push(endNodeId);

                                   midNode=wAns[startNodeId][endNodeId];

                                   myStack.push(midNode);

                                   while(midNode!=startNodeId)

                                   {

                                          midNode=wAns[startNodeId][midNode];

                                          myStack.push(midNode);

                                   }

                                   while(!myStack.isEmpty())

                                          fprintf(outputFile,"%d,",myStack.pop());

                                   fprintf(outputFile,"*");

                     }

                     fprintf(outputFile,"/r/n");

              }

 

 

 

 

 

 

       /******************End of Core program**********/

       endTime=(double)clock()/(double)CLOCKS_PER_SEC;

       tweenTime=endTime-startTime;/*Get the time collapsed*/

       /*Time collapsed output*/

       printf("the collapsed time in this algorithm implement is:%f/n",tweenTime);

       fprintf(outputFile,"the collapsed time in this algorithm implement is:%f/r/n",tweenTime); 

       printf("/n*******end of test program******/n");

#endif

 

 

 

              for(i=0;i<row;i++)

                            free(wArr[i]);

              free(wArr);

      

       printf("program end successfully,/n you have to preess any key to clean the buffer area to output,otherwise,you wiil not get the total answer./n");

       getchar();/*Screen Delay Control*/

       return;

}

测试结果:

输入文件:

4,4,
0,1,1,-1;
1,0,-1,2;
1,-1,0,1;
-1,2,1,0;

输出文件:

===Output the node info matrix.===
0,0,0,2;
1,1,0,1;
2,0,2,2;
2,3,3,3;
===End of output the node info matrix.===
0,0,*0,1,*0,2,*0,2,3,*
1,0,*1,1,*1,0,2,*1,3,*
2,0,*2,0,1,*2,2,*2,3,*
3,2,0,*3,1,*3,2,*3,3,*

你可能感兴趣的:([图算法]Floyd算法改进之打印路径.)