《算法竞赛》学习记录之状态压缩dp旅行商TSP问题

旅行商问题

问题:有n个城市,已知任何两个城市之间的距离(或者费用),一个旅行商从某城市出发,经过每一个城市并且只经过一次,最后回到出发的城市,输出最短(或者费用最少)的线路。
背景:旅行商问题是一个经典的NP问题,不存在多项式时间内的解,使用暴力法时间复杂度将达到n!,但是可以使用动态规划来解,时间复杂度为2^n×(n×n)。(模板的TSP问题应该可以使用模拟退火算法解决,但是还没有写)。
思路
对于暴力法,每次选择一个城市进行选择,然后枚举下一个城市,第一次选择次数为n,第二次选择次数为n-1,直到第n次为1个选择,时间为n*(n-1)…1=n!。
动态规划设计如下:
由于一个城市只有两种状态,即走或者不走,所以使用二进制来表示将节省大量,我们设dp[S][v]表示此时已走过的城市(或待走的城市)状态为S,其中S的二进制中第i为1则表示已走(或未走),为0则未走(或已走);其值为到达这种状态(即此时走过城市状态为S,目前在v号城市这种状态)所需的最少花费;例如此时有四个城市,S=6=二进制下的0100,此时已走过了三号城市,还未走一号二号四号城市。目的状态为dp[(1< 状态转移方程如下:
dp[0][0]=0;//表示目前一个城市也没有走,且当前在初始城市,此时花费为0
dp[S][v]=min(dp[S][v],dp[S-(1<v得到;其中S’为S-{u}。
代码如下

import java.util.Arrays;
import java.util.Scanner;

public class Main2 {
	static int[][] dis;
	static int[][] dp;
	static int n;
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Scanner sc=new Scanner(System.in);
		System.out.println("输入多少个城市 多少条道路:");
		n=sc.nextInt();
		dp=new int[1<>u&1)!=0)	//之前一步必须为走过的城市,当前城市却可以是走过也可以是没走过
						dp[s][v]=Math.min(dp[s][v],dp[s-(1<

PS:其中v的选择既可以是走过的城市或者是未走过的城市,因为最后我们需要求dp[(1<

你可能感兴趣的:(《算法竞赛》学习记录之状态压缩dp旅行商TSP问题)