導航:首頁 > 源碼編譯 > 弗洛伊德演算法c

弗洛伊德演算法c

發布時間:2025-01-26 15:34:54

㈠ Floyd演算法是什麼

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來記錄兩點間的最短路徑。
採用的是(鬆弛技術),對在i和j之間的所有其他點進行一次鬆弛。所以時間復雜度為O(n^3); 其狀態轉移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]} map[i,j]表示i到j的最短距離 K是窮舉i,j的斷點 map[n,n]初值應該為0,或者按照題目意思來做。
當然,如果這條路沒有通的話,還必須特殊處理,比如沒有map[i,k]這條路

㈡ C++編程實現醫院選址問題

醫院選址
1.
代碼如下

#include <iostream>
using namespace std;
#define MAXV 50
#define INF 32767
typedef int InfoType;
//鄰接矩陣存儲方法
typedef struct
{
int no;
InfoType info;
} VertexType;
typedef struct
{
int edges[MAXV][MAXV];
int n,e;
VertexType vexs[MAXV];
} MGraph;
//狄克斯特拉演算法
void Ppath(int path[],int i,int v)
{
int k;
k=path[i];
if(k==v) return;
Ppath(path,k,v);
cout<<k;
}
int biaoji1=0,biaoji2=0;
void Dispath(int dist[],int path[],int s[],int n,int v)
{
int i;
for(i=0;i<n;i++)
{
if(i==v) continue;
if(s[i]==1)
{
cout<<"從"<<v<<"到"<<i<<"的最短路徑為:"<<dist[i]<<" ";
cout<<v;
Ppath(path,i,v);
cout<<i<<endl;
if(biaoji1!=5)
{biaoji2+=dist[i];biaoji1++;}
else
{
cout<<"和為:"<<" "<<biaoji2;
biaoji1=0;biaoji2=0;
}
}
else
cout<<"從"<<v<<"到"<<i<<"不存在的路徑"<<endl;
}
}
void Dijkstra(MGraph g,int v)
{
int dist[MAXV],path[MAXV];
int s[MAXV];
int mindis,i,j,u;
for(i=0;i<g.n;i++)
{
dist[i]=g.edges[v][i];
s[i]=0;
if(g.edges[v][i]<INF) path[i]=v;
else path[i]=-1;
}
s[v]=1;path[v]=0;
for(i=0;i<g.n;i++)
{
mindis=INF;
for(j=0;j<g.n;j++)
{
if(s[j]==0&&dist[j]<mindis)
{
u=j;
mindis=dist[j];
}
}
s[u]=1;
for(j=0;j<g.n;j++)
{
if(s[j]==0)
{
if(g.edges[u][j]<INF&&dist[u]+g.edges[u][j]<dist[j])
{
dist[j]=dist[u]+g.edges[u][j];
path[j]=u;
}
}
}
}
Dispath(dist,path,s,g.n,v);
}
//弗洛伊德演算法
void Ppath1(int path[][MAXV],int i,int j)
{
int k;
k=path[i][j];
if(k==-1) return;
Ppath1(path,i,k);
cout<<k;
Ppath1(path,k,j);
}
void Dispath1(int A[][MAXV],int path[][MAXV],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(i==j) continue;
if(A[i][j]==INF)
{
if(i!=j)
cout<<"從"<<i<<"到"<<j<<"不存在路徑"<<endl;
}
else
{
cout<<"從"<<i<<"到"<<j<<"的最短路徑長度為:"<<A[i][j]<<" ";
cout<<i;
Ppath1(path,i,j);
cout<<j<<endl;
}
}
}
}
void Floyd(MGraph g)
{
int A[MAXV][MAXV],path[MAXV][MAXV];
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;
}
}
}
}
Dispath1(A,path,g.n);
}

//主函數
int main()
{
int i,j,n;
MGraph g;
cout<<"請輸入帶權有向圖的頂點個數:";//6
while(scanf("%d",&n)!=EOF/*cin>>n,n!=EOF*/)
{
cout<<"請輸入帶權有向圖的鄰接矩陣:"<<endl;
/*
0 5 32767 7 32767 32767
32767 0 4 32767 32767 32767
8 32767 0 32767 32767 9
32767 32767 5 0 32767 6
32767 32767 32767 5 0 32767
3 32767 32767 32767 1 0
*/

for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
//scanf("%d",&g.edges[i][j]);
cin>>g.edges[i][j];
}
}
g.n=n;
cout<<"採用狄克斯特拉演算法得到的最短路徑為:"<<endl;
for(i=0;i<n;i++) Dijkstra(g,i);
cout<<endl;
cout<<"採用弗洛伊德演算法得到的最短路徑為:"<<endl;
Floyd(g);
cout<<endl;
cout<<"請輸入帶權無向圖的頂點個數:";
}
return 0;
}

2.代碼如下

#include <iostream>
using namespace std;
int INFTY=32767;
template<class T>
class Graph
{
public:
virtual void Insert(int u,int v,T& w)=0;
virtual void Remove(int u,int v)=0;
virtual bool Exist(int u,int v)=0;
virtual int Vertices()const {return n;}
protected:
int n,e;

};
template <class T>
class MGraph:public Graph<T>//鄰接矩陣存儲圖
{
public:
MGraph();
~MGraph();
void Build_Graph();
void Insert(int u,int v,T& w);
void Remove(int u,int v);
bool Exist(int u,int v);
void Floyd(T**&d,int**&path);
int num;
protected:
T**a;
T noEdge;
};
template <class T>
void MGraph<T>::Build_Graph()//建圖
{
cout<<"請輸入頂點的個數:"<<endl;
int C_num;
cin>>C_num;
num=n=C_num;e=0;noEdge=INFTY;
a=new T*[n];
for(int k=0;k<n;k++){
a[k]=new T [n];
for(int j=0;j<n;j++)a[k][j]=noEdge;
a[k][k]=0;
}
cout<<"建立村莊編號為1--"<<C_num<<"的圖"<<endl;
for(int i=0;i!=C_num;i++)
for(int j=i+1;j!=C_num;j++)
{
int w;
cout<<"請輸入村莊"<<i+1<<"與村莊"<<j+1<<"之間的權值:";
cin>>w;
Insert(i,j,w); //向圖中添加權值為W的邊
cout<<i<<"--->"<<j<<":"<<a[i][j]<<endl;
}
cout<<"*********************************************************************"<<endl;
cout<<"已建立村莊編號為1--"<<C_num<<"的圖:"<<endl;
cout<<"**********************************"<<endl;
cout<<" \t\t";
for(int b=1;b<=C_num;b++){

cout<<b<<"\t";
}
cout<<endl;
}

template <class T>
MGraph<T>::MGraph()
{
Build_Graph();
}

template <class T>
MGraph<T>::~MGraph()
{
for(int i=0;i<n;i++)delete[]a[i];
delete[]a;
}

template <class T>
bool MGraph<T>::Exist(int u,int v)
{
if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]==noEdge) return false;
return true;
}
template <class T>
void MGraph<T>::Insert(int u,int v,T &w)
{
a[u][v]=w;a[v][u]=w;e++;
}
template <class T>
void MGraph<T>::Remove(int u,int v)
{
a[u][v]=noEdge;e--;
}

template <class T>
void MGraph<T>::Floyd(T**&d,int**&path)//所有頂點之間的最短路徑
{
int i,j,k;
d=new T*[n];path=new int*[n];
for(i=0;i<n;i++){
d[i]=new T[n];path[i]=new int[n];
for(j=0;j<n;j++){
d[i][j]=a[i][j];
if(i!=j&& a[i][j]<INFTY)path[i][j]=i;
else path[i][j]=-1;
}
}
for(k=0;k<n;k++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(d[i][k]+d[k][j]<a[i][j]){
d[i][j]=d[i][k]+d[k][j];
path[i][j]=path[k][j];
}
}
int main()
{
MGraph<int> Hospital;
int **d,**path;
int i,j,n;
n=Hospital.num;
Hospital.Floyd(d,path);
int *sum=new int[n];
cout<<endl;
for(i=0;i!=n;i++)//輸出矩陣
{
cout<<i+1<<"\t\t";
sum[i]=0;
for(j=0;j!=n;j++)
{
sum[i]+=d[i][j];
cout<<d[i][j]<<"\t";
}
cout<<endl;
}
cout<<"*********************************************************************"<<endl;
int min=0;
for(i=0;i!=n;i++)
{
cout<<i+1<<"村莊:"<<sum[i]<<endl;
if(sum[min]>sum[i])//判斷最短路徑
min=i;
}
cout<<"醫院應在編號為"<<min+1<<"的村莊"<<endl;
for(i=0;i<n;i++)
{
delete[]d[i];
delete[]path[i];
}
delete[]d;
delete[]path;
return 0;
}

㈢ 求計算機求解關系R的傳遞閉包 C語言演算法

傳遞閉包,最簡單的技術是採用 【弗洛伊德演算法】

Floyd-Warshall演算法(Floyd-Warshall algorithm)是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或負權的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。

Floyd-Warshall演算法的時間復雜度為O(N3),空間復雜度為O(N2)。

Floyd-Warshall演算法的原理是動態規劃。

設Di,j,k為從i到j的只以(1..k)集合中的節點為中間節點的最短路徑的長度。

1.若最短路徑經過點k,則Di,j,k = Di,k,k − 1 + Dk,j,k − 1;
2.若最短路徑不經過點k,則Di,j,k = Di,j,k − 1。
因此,Di,j,k = min(Di,k,k − 1 + Dk,j,k − 1,Di,j,k − 1)。
在實際演算法中,為了節約空間,可以直接在原來空間上進行迭代,這樣空間可降至二維。

代碼請見:

閱讀全文

與弗洛伊德演算法c相關的資料

熱點內容
163郵箱伺服器的ip地址 瀏覽:48
伺服器跟域是什麼 瀏覽:126
rails啟動命令 瀏覽:463
logistic命令怎麼用 瀏覽:736
c語言點滴pdf 瀏覽:745
linuxrtc編程 瀏覽:256
linux打包並壓縮命令 瀏覽:642
aes加密的證書格式 瀏覽:97
oracledbcalinux 瀏覽:842
酬勤任務app怎麼被特邀 瀏覽:197
android應用文件夾 瀏覽:1000
平面設計法則pdf 瀏覽:337
3d圓角命令怎麼用 瀏覽:567
程序員買意外險還是重疾險 瀏覽:619
遼寧的dns伺服器地址雲空間 瀏覽:446
我的世界伺服器斷開後怎麼連接 瀏覽:413
htmltopdfpython 瀏覽:75
如何預覽網站源碼文件 瀏覽:35
怎麼修改後台源碼 瀏覽:28
bat編程入門 瀏覽:853