qjh2375580241的gravatar头像
qjh23755802412020-04-02 22:47:10

使用java写出旅行商问题,很难很难,求大佬们帮帮忙!

现在需要做一个TSP问题的解法,表示遇到了无奈的情况

问题描述:旅行商问题,已知N个城市的坐标或者距离邻接矩阵(int类型),从一个城市出发固定0城市或者固定1城市出发,经过且仅经过其余N-1个城市一次,回到出发城市。求最短距离,并且需要知道最短距离的途径路径。

测试样例:已知坐标的,最大有52个城市
                    已知距离邻接矩阵的,最大有58个城市

0、暴力法:城市顺序全排列,找到最短距离(纯属开玩笑,跑两天不知道行不行···
1、回溯法:运行了1个小时才能得到结果而且只是,表示未免也太慢了点吧。
2、分支定界法:空间消耗太大了,运行时间也难以保证。
3、动态规划法:空间复杂度要求太高了,城市稍微比较多的样例程序就会崩···,数量比较少的样例倒是没问题,自己写出来了
4、模拟退火算法,遗传算法,蚁群算法,看了半天的算法介绍,表示自己学不会怎么破···
5、其他算法:禁忌搜索?(其实这个觉得能写,但算法有点不理解····

想问问大神们,有什么好的方法可以过了那17个样例。真心感谢啊······

所有回答列表(2)
lzj1239825268的gravatar头像
lzj1239825268 LV24月3日

就用tsp 算法啊,TSP还不简单么,给你个案例

package book;

import java.util.Scanner;

public class TSP {
static int n,m;//n城市数量,m边数量
static int grh[][];//地图
static int curentlength,bestlength;//当前距离,最短距离
static int curent[],best[];//当前路线,最好的路线
static int Max=Integer.MAX_VALUE;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		grh=new int[n+1][n+1];
		curent=new int[n+1];
		best=new int[n+1];
		curentlength=0;
		bestlength=-1;
		for(int i=1;i<=n;i++) {
			curent[i]=i;
			for(int j=1;j<=n;j++) {
				grh[i][j]=Max;//初始化地图,每个点之间的距离都是无穷大
		   }
		}
		for(int i=1;i<=m;i++) {
			int start = sc.nextInt();
			int end = sc.nextInt();
			int length = sc.nextInt();
		    
		    	grh[start][end]=length;
		    	grh[end][start]=length;//把所有的边存储起来
		    
		}
		backtrace(2);
		if(bestlength!=-1) {
		for(int i=1;i<=n;i++) {
			System.out.print(best[i]+" ");
		}
		System.out.println("1");
		
		System.out.println(bestlength);
	}else {
		System.out.println("-1");
	}
		
	}

	
	private static void backtrace(int t) {
		if(t==n) {
			if(grh[curent[n-1]][curent[n]]!=Max&&grh[curent[n]][1]!=Max&&
					(curentlength+grh[curent[n-1]][curent[n]]+grh[curent[n]][1]<bestlength||bestlength==-1)) {
				//1.当到准备去第n个城市的时候,首先要判断当前售货员与第n个点有没有路线,没有路线就剪掉
				//2.要判断第n个点与起点1有没有路线,没有也要剪掉
				//3.判断走完这条路线,回到原点的总距离是不是小于已经知道的最短距离,如果大于也剪掉
				//如果都符合,就要做更新操作
				for(int i=1;i<=n;i++) {
					best[i]=curent[i];
				}
				bestlength=curentlength+grh[curent[n-1]][curent[n]]+grh[curent[n]][1];
			}
		}else {
			for(int i=t;i<=n;i++) {
				if(grh[curent[t-1]][curent[i]]<Max&&(curentlength+grh[curent[t-1]][curent[i]]<bestlength||bestlength==-1)) {
					//上面的剪枝条件是,t-1表示现在售货员所在的城市,i表示他现在要准备去的城市,两者之间必须要有边
					//bestlength=-1表示第一次走
					//符合条件我们就需要交换
					swap(t,i);
					curentlength=curentlength+grh[curent[t-1]][curent[t]];
					backtrace(t+1);
					curentlength=curentlength-grh[curent[t-1]][curent[t]];
				    swap(t,i);
				    
				}
			}
		}
		
	}
	private static void swap(int t, int i) {
		int temp=0;
		temp=curent[t];
		curent[t]=curent[i];
		curent[i]=temp;
	}

}


 

评论(0)最佳答案
ZH0001的gravatar头像
ZH0001 LV25月28日

看你需要得到结果的精确度了,如果只是要一个满意解,可以考虑蚁群算法、遗传算法,tsp本身是一个NP难问题,随着城市数量的增多,解空间也会指数级的增大,是不可能穷举尽的。

顶部客服微信二维码底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友