• Floyd-Warshall算法,简称Floyd算法


    Floyd-Warshall算法,简称Floyd算法,用于求解任意两点间的最短距离,时间复杂度为O(n^3)。

    使用条件&范围
    通常可以在任何图中使用,包括有向图、带负权边的图。

    Floyd-Warshall 算法用来找出每对点之间的最短距离。它需要用邻接矩阵来储存边,这个算法通过考虑最佳子路径来得到最佳路径。

    1.注意单独一条边的路径也不一定是最佳路径。
    2.从任意一条单边路径开始。所有两点之间的距离是边的权,或者无穷大,如果两点之间没有边相连。
    对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。
    3.不可思议的是,只要按排适当,就能得到结果。
    伪代码:

    // dist(i,j) 为从节点i到节点j的最短距离
    For i←1 to n do
       For j←1 to n do
          dist(i,j) = weight(i,j) 
     
    For k←1 to n do // k为“媒介节点”
       For i←1 to n do
          For j←1 to n do
             if (dist(i,k) + dist(k,j) < dist(i,j)) then // 是否是更短的路径?
                dist(i,j) = dist(i,k) + dist(k,j)


    我们平时所见的Floyd算法的一般形式如下:

    void Floyd(){
         int i,j,k;
         for(k=1;k<=n;k++)
             for(i=1;i<=n;i++)
                 for(j=1;j<=n;j++)
                     if(dist[i][k]+dist[k][j]<dist[i][j])
                         dist[i][j]=dist[i][k]+dist[k][j];
    }



    注意下第6行这个地方,如果dist[i][k]或者dist[k][j]不存在,程序中用一个很大的数代替。最好写成if(dist[i] [k]!=INF && dist[k][j]!=INF && dist[i][k]+dist[k][j]<dist[i][j]),从而防止溢出所造成的错误。< p="">

    Floyd算法的实现以及输出最短路径和最短路径长度。

    代码说明几点:

    1、A[][]数组初始化为各顶点间的原本距离,最后存储各顶点间的最短距离。

    2、path[][]数组保存最短路径,与当前迭代的次数有关。初始化都为-1,表示没有中间顶点。在求A[i][j]过程中,path[i][j]存放从顶点vi到顶点vj的中间顶点编号不大于k的最短路径上前一个结点的编号。在算法结束时,由二维数组path的值回溯,可以得到从顶点vi到顶点vj的最短路径。

    完整代码如下:

    #include <iostream>
    #include <string>   
    #include <stdio.h>   
    using namespace std;   
    #define MaxVertexNum 100   
    #define INF 32767   
    typedef struct  
    {   
        char vertex[MaxVertexNum];   
        int edges[MaxVertexNum][MaxVertexNum];   
        int n,e;   
    }MGraph;   
     
    void CreateMGraph(MGraph &G)   
    {   
        int i,j,k,p;   
        cout<<"请输入顶点数和边数:";   
        cin>>G.n>>G.e;   
        cout<<"请输入顶点元素:";   
        for (i=0;i<G.n;i++)   
        {   
            cin>>G.vertex[i];   
        }   
        for (i=0;i<G.n;i++)   
        {   
            for (j=0;j<G.n;j++)   
            {   
                G.edges[i][j]=INF;   
                if (i==j)   
                {   
                    G.edges[i][j]=0;   
                }   
            }   
        }      
        for (k=0;k<G.e;k++)   
        {   
            cout<<"请输入第"<<k+1<<"条弧头弧尾序号和相应的权值:";   
            cin>>i>>j>>p;   
            G.edges[i][j]=p;   
        }   
    }   
    void Dispath(int A[][MaxVertexNum],int path[][MaxVertexNum],int n);
     
    void Floyd(MGraph G)
    {
    	int A[MaxVertexNum][MaxVertexNum],path[MaxVertexNum][MaxVertexNum];
    	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 Ppath(int path[][MaxVertexNum],int i,int j)
    {
    	int k;
    	k=path[i][j];
    	if (k==-1)
    	{
    		return;
    	}
    	Ppath(path,i,k);
    	printf("%d,",k);
    	Ppath(path,k,j);
    }
     
    void Dispath(int A[][MaxVertexNum],int path[][MaxVertexNum],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)
    				{
    					printf("从%d到%d没有路径
    ",i,j);
    				}
    			}
    			else
    			{
    				printf("  从%d到%d=>路径长度:%d路径:",i,j,A[i][j]);
    				printf("%d,",i);
    				Ppath(path,i,j);
    				printf("%d
    ",j);
    			}
    		}
    	}
    }
     
    int main()
    {
    	freopen("input2.txt", "r", stdin);
    	MGraph G;
    	CreateMGraph(G);
    	Floyd(G);
    	return 0;
    }


  • 相关阅读:
    不常用的cmd命令
    js获取宽度
    Marshaling Data with Platform Invoke 概览
    Calling a DLL Function 之三 How to: Implement Callback Functions
    Marshaling Data with Platform Invoke 之四 Marshaling Arrays of Types
    Marshaling Data with Platform Invoke 之一 Platform Invoke Data Types
    Marshaling Data with Platform Invoke 之三 Marshaling Classes, Structures, and Unions(用时查阅)
    Calling a DLL Function 之二 Callback Functions
    WCF 引论
    Marshaling Data with Platform Invoke 之二 Marshaling Strings (用时查阅)
  • 原文地址:https://www.cnblogs.com/wt869054461/p/3679203.html
Copyright © 2020-2023  润新知