public class TestTravel {
public static void travel(int[][] distance){
int b=(int)Math.pow(2,distance.length-1);
int n = distance.length;
int[][] F = new int[n][b]; //n行b列的二维数组,存放阶段最优值,即最短距离
int[][] M = new int[n][b]; //存放最优策略
for(int i=0;i<b;i++){
for(int j=0;j<n;j++)
{
F[j][i] = -1;
M[j][i] = -1;
}
}
//给F的第0列赋初值
for(int i=0;i<n;i++){
F[i][0] = distance[i][0];
}
//遍历并填
//遍历并填表
for(int i=1;i<b-1;i++)//最后一列不在循环里计算
for(int j=1;j<n;j++)
{
if( ((int)Math.pow(2,j-1) & i) == 0)//结点j不在i表示的集合中
{
int min=65535;
for(int k=1;k<n;k++)
if(((int)Math.pow(2,k-1) & i )!=0)//非零表示结点k在集合中
{
int temp = distance[j][k] + F[k][i-(int)Math.pow(2,k-1)];
if(temp < min)
{
min = temp;
F[j][i] = min;//保存阶段最优值
M[j][i] = k;//保存最优决策
}
}
}
}
//最后一列,即总最优值的计算
int min=65535;
for(int k=1;k<n;k++)
{
//b-1的二进制全1,表示集合{1,2,3,4,5},从中去掉k结点即将k对应的二进制位置0
int temp = distance[0][k] + F[k][b-1 - (int)Math.pow(2,k-1)];
if(temp < min)
{
min = temp;
F[0][b-1] = min;//总最优解
M[0][b-1] = k;
}
}
System.out.println(F[0][b-1]);
System.out.println("最短路径编号");
System.out.print(0);
for(int i=b-1,j=0;i>0; )//i的二进制是5个1,表示集合{1,2,3,4,5}
{
j = M[j][i];//下一步去往哪个结点
i = i - (int)Math.pow(2,j-1);//从i中去掉j结点
System.out.print("->"+j);
}
System.out.print("->"+0);
}
public static void main(String[] args) {
int[][] distance = { //各个节点之间路径长度的二维数组
{0, 2, 1, 3, 4, 5, 5, 6},
{1, 0, 4, 4, 2, 5, 5, 6},
{5, 4, 0, 2, 2, 6, 5, 6},
{5, 2, 2, 0, 3, 2, 5, 6},
{4, 2, 4, 2, 0, 3, 5, 6},
{4, 2, 4, 2, 3, 0, 5, 6},
{4, 2, 4, 2, 4, 3, 0, 6},
{4, 2, 4, 2, 8, 3, 5, 0}};
int[][] C = {
{0,3,6,7},
{5,0,2,3},
{6,4,0,2},
{3,7,5,0}
};
travel(C);
}
}
转载自https://blog.csdn.net/masibuaa/article/details/8236074 C++版