如果对任意数目的n个城市,分别用1~n的数字编号表示。则这个问题归结为在有向赋权图G=
中,寻找一条路径最短的哈密尔顿回路问题。其中,V={1,2,...,n}表示城市顶点;边(i,j)E表示城市i到城市j的距离,i,j=1,2,...,n。这样可用邻接矩阵C来表示各个城市之间的距离,计费用矩阵。如果(i,j)E,则c_ij>0;否则,c_ij=。
令d(i,)表示从顶点i出发,经中各个顶点一次,最终回到初始出发点的最短路径的长度。开始时 = V-{i}。于是,可以定义下面的动态规划函数:
d(i,V-{i}) = d(i,) = min {c_ik + d(k,-{k})}(k)
d(k,) = C_ki ki
d(1,{2,3,4}) = min{c_12+d(2,{3,4}),c_13+d(3,{2,4}),c_14+d(4,{2,3})}
d(2,{3,4}) = min{c_23+d(3,{4}),c_24+d(4,{3})};
d(3,{2,4}) = min{c_32+d(2,{4}),c_34+d(4,{2})};
d(4,{2,3}) = min{c_42+d(2,{3}),c_43+d(3,{2})};
依次类推;
源码:
package com.wyj.cargoCarrier;
import java.util.Scanner;
public class cargoCarrier {
private static int n; //城市个数
private static int[][] cost; //费用矩阵
private static int start; //起始位置
private static int[] path; //最优路径
private static int sum = 0; //最优路径权值和
private static boolean[]flag; //0未访问,1已被访问
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.print("请输入城市个数 n=");
n = sc.nextInt();
System.out.println("请输入城市之间的权值代价(注:城市自己到自己记为0意为无穷的意思)");
cost = new int[n][n];
flag = new boolean[n];
for(int i=0;i
cost[i][j] = sc.nextInt();
}
}
printFun();
while(true) {
System.out.print("输入起始位置start=");
start = sc.nextInt();
if((start>=1&&start<=n)) {
break;
}
}
initFun();
System.out.println("最小费用"+workFun(n,start-1));
}
/**
* 这里先来了解一下算法思路:
* 1:由上面树状图我们不难解除此算法需要两层循环
* 2:每次循环遍历的节点总是剔除了所有的父辈节点,比如当你是d(2,{3,4})的时候就不用访问节点1,当你是d(3,{4})的时候就不用访问节点1,2
* 3:由2不难看出需要一个以为数组判断当前节点是否已被访问记flag[n]
*/
public static int workFun(int num,int spot) {
if(num==1) {//极限情况,当只剩最后一个节点则返回该节点到起点的距离,这里是一个回路所以返回的是cost[spot][start],如果只是遍历所有点不用返回起始则直接返回0
return cost[spot][start-1];
}
int mincost = Integer.MAX_VALUE;
for(int i=0;i
if(mincost <= cost[spot][i]+cost[i][start]){
continue; //其作用为结束本次循环。即跳出循环体中下面尚未执行的语句。区别于break
}
flag[i] = true;//递归调用时,防止重复调用
int value = cost[spot][i]+workFun(num-1, i);
if(value
}
flag[i] = false;//本次递归调用完毕,让下次递归调用
}
}
return mincost;
}
//答应费用矩阵
public static void printFun() {
for(int i=0;i
}
System.out.println();
}
}
//初始化flag,所有节点未访问
private static void initFun() {
for(int i=0;i
}
}
}