比如,要尋找從V5到V1的路徑。根據D,假如D(5,1)=3則說明從V5到V1經過V3,路徑為{V5,V3,V1},如果D(5,3)=3,說明V5與V3直接相連,如果D(3,1)=1,說明V3與V1直接相連。
function Floyd(w,router_direction,MAX)
%w為此圖的距離矩陣
%router_direction為路由類型:0為前向路由;非0為回溯路由
%MAX是數據輸入時的∞的實際值
len=length(w);
flag=zeros(1,len);
%根據路由類型初始化路由表
R=zeros(len,len);
for i=1:len
if router_direction==0%前向路由
R(:,i)=ones(len,1)*i;
else %回溯路由
R(i,:)=ones(len,1)*i;
end
R(i,i)=0;
end
disp('');
disp('w(0)');
dispit(w,0);
disp('R(0)');
dispit(R,1);
%處理端點有權的問題
for i=1:len
tmp=w(i,i)/2;
if tmp~=0
w(i,:)=w(i,:)+tmp;
w(:,i)=w(:,i)+tmp;
flag(i)=1;
w(i,i)=0;
end
end
%Floyd算法具體實現過程
for i=1:len
for j=1:len
if j==i || w(j,i)==MAX
continue;
end
for k=1:len
if k==i || w(j,i)==MAX
continue;
end
if w(j,i)+w(i,k)<w(j,k) %Floyd算法核心代碼
w(j,k)=w(j,i)+w(i,k);
if router_direction==0%前向路由
R(j,k)=R(j,i);
else %回溯路由
R(j,k)=R(i,k);
end
end
end
end
%顯示每次的計算結果
disp(['w(',num2str(i),')'])
dispit(w,0);
disp(['R(',num2str(i),')'])
dispit(R,1);
end
%中心和中點的確定
[Center,index]=min(max(w'));
disp(['中心是V',num2str(index)]);
[Middle,index]=min(sum(w'));
disp(['中點是V',num2str(index)]);
end
function dispit(x,flag)
%x:需要顯示的矩陣
%flag:為0時表示顯示w矩陣,非0時表示顯示R矩陣
len=length(x);
s=[];
for j=1:len
if flag==0
s=[s sprintf('%5.2f\t',x(j,:))];
else
s=[s sprintf('%d\t',x(j,:))];
end
s=[s sprintf('\n')];
end
disp(s);
disp('---------------------------------------------------');
end
% 選擇後按Ctrl+t取消注釋號%
%
% 示例:
% a=[
% 0,100,100,1.2,9.2,100,0.5;
% 100,0,100,5,100,3.1,2;
% 100,100,0,100,100,4,1.5;
% 1.2,5,100,0,6.7,100,100;
% 9.2,100,100,6.7,0,15.6,100;
% 100,3.1,4,100,15.6,0,100;
% 0.5,2,1.5,100,100,100,0
% ];
%
% b=[
% 0,9.2,1.1,3.5,100,100;
% 1.3,0,4.7,100,7.2,100;
% 2.5,100,0,100,1.8,100;
% 100,100,5.3,0,2.4,7.5;
% 100,6.4,2.2,8.9,0,5.1;
% 7.7,100,2.7,100,2.1,0
% ];
%
% Floyd(a,1,100)
% Floyd(b,1,100)
//以無向圖G為入口,得出任意兩點之間的路徑長度length[i][j],路徑path[i][j][k],
//途中無連線得點距離用0表示,點自身也用0表示
public class FLOYD {
int[][] length = null;// 任意兩點之間路徑長度
int[][][] path = null;// 任意兩點之間的路徑
public FLOYD(int[][] G) {
int MAX = 100;int row = G.length;// 圖G的行數
int[][] spot = new int[row][row];// 定義任意兩點之間經過的點
int[] onePath = new int[row];// 記錄一條路徑
length = new int[row][row];
path = new int[row][row][];
for (int i = 0; i < row; i++)// 處理圖兩點之間的路徑
for (int j = 0; j < row; j++) {
if (G[i][j] == 0)G[i][j] = MAX;// 沒有路徑的兩個點之間的路徑為默認最大
if (i == j)G[i][j] = 0;// 本身的路徑長度為0
}
for (int i = 0; i < row; i++)// 初始化為任意兩點之間沒有路徑
for (int j = 0; j < row; j++)
spot[i][j] = -1;
for (int i = 0; i < row; i++)// 假設任意兩點之間的沒有路徑
onePath[i] = -1;
for (int v = 0; v < row; ++v)
for (int w = 0; w < row; ++w)
length[v][w] = G[v][w];
for (int u = 0; u < row; ++u)
for (int v = 0; v < row; ++v)
for (int w = 0; w < row; ++w)
if (length[v][w] > length[v][u] + length[u][w]) {
length[v][w] = length[v][u] + length[u][w];// 如果存在更短路徑則取更短路徑
spot[v][w] = u;// 把經過的點加入
}
for (int i = 0; i < row; i++) {// 求出所有的路徑
int[] point = new int[1];
for (int j = 0; j < row; j++) {
point[0] = 0;
onePath[point[0]++] = i;
outputPath(spot, i, j, onePath, point);
path[i][j] = new int[point[0]];
for (int s = 0; s < point[0]; s++)
path[i][j][s] = onePath[s];
}
}
}
void outputPath(int[][] spot, int i, int j, int[] onePath, int[] point) {// 輸出i// 到j// 的路徑的實際代碼,point[]記錄一條路徑的長度
if (i == j)return;
if (spot[i][j] == -1)
onePath[point[0]++] = j;
// System.out.print(" "+j+" ");
else {
outputPath(spot, i, spot[i][j], onePath, point);
outputPath(spot, spot[i][j], j, onePath, point);
}
}
public static void main(String[] args) {
int data[][] = {
{ 0, 27, 44, 17, 11, 27, 42, 0, 0, 0, 20, 25, 21, 21, 18, 27, 0 },// x1
{ 27, 0, 31, 27, 49, 0, 0, 0, 0, 0, 0, 0, 52, 21, 41, 0, 0 },// 1
{ 44, 31, 0, 19, 0, 27, 32, 0, 0, 0, 47, 0, 0, 0, 32, 0, 0 },// 2
{ 17, 27, 19, 0, 14, 0, 0, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0 },// 3
{ 11, 49, 0, 14, 0, 13, 20, 0, 0, 28, 15, 0, 0, 0, 15, 25, 30 },// 4
{ 27, 0, 27, 0, 13, 0, 9, 21, 0, 26, 26, 0, 0, 0, 28, 29, 0 },// 5
{ 42, 0, 32, 0, 20, 9, 0, 13, 0, 32, 0, 0, 0, 0, 0, 33, 0 },// 6
{ 0, 0, 0, 0, 0, 21, 13, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0 },// 7
{ 0, 0, 0, 0, 0, 0, 0, 19, 0, 11, 20, 0, 0, 0, 0, 33, 21 },// 8
{ 0, 0, 0, 0, 28, 26, 32, 0, 11, 0, 10, 20, 0, 0, 29, 14, 13 },// 9
{ 20, 0, 47, 30, 15, 26, 0, 0, 20, 10, 0, 18, 0, 0, 14, 9, 20 },// 10
{ 25, 0, 0, 0, 0, 0, 0, 0, 0, 20, 18, 0, 23, 0, 0, 14, 0 },// 11
{ 21, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 27, 22, 0, 0 },// 12
{ 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0 },// 13
{ 18, 41, 32, 31, 15, 28, 0, 0, 0, 29, 14, 0, 22, 0, 0, 11, 0 },// 14
{ 27, 0, 0, 0, 25, 29, 33, 0, 33, 14, 9, 14, 0, 0, 11, 0, 9 },// 15
{ 0, 0, 0, 0, 30, 0, 0, 0, 21, 13, 20, 0, 0, 0, 0, 9, 0 } // 16
};
for (int i = 0; i < data.length; i++)
for (int j = i; j < data.length; j++)
if (data[i][j] != data[j][i])return;
FLOYD test=new FLOYD(data);
for (int i = 0; i < data.length; i++)
for (int j = i; j < data[i].length; j++) {
System.out.println();
System.out.print("From " + i + " to " + j + " path is: ");
for (int k = 0; k < test.path[i][j].length; k++)
System.out.print(test.path[i][j][k] + " ");
System.out.println();
System.out.println("From " + i + " to " + j + " length :"+ test.length[i][j]);
}
}
}