贪心算法求解旅行商问题(java实现)

输入为城市距离的文件,文件格式如下:

1 2066 2333
2 935 1304
3 1270 200
4 1389 700
5 984 2810
6 2253 478
7 949 3025
8 87 2483
9 3094 1883
10 2706 3130

这是个10城市的距离文件,一共3列,第1列代表序号,第2列代表x坐标,第三列代表y坐标。

输出为城市距离的序列、求到的最短距离以及程序运行的时间。


java源代码如下:

package tsp_problem;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/*
 * 贪心算法求解TSP问题
 * 按照贪心算法的思想每次选取距离当前城市距离最近的城市,直到所有城市选取完毕
 */
public class GreedyAlgorithm {
	double s=0;//总距离值
	private int citynumbers;//城市数目
	private double[][] distance;//距离矩阵,距离为欧式空间距离
	int[] visited;//确定是否访问过
	int[] path;//存放路径,路径的值从1开始
	
	public GreedyAlgorithm(int n) {
		citynumbers=n;
	}
	
	//读取数据,计算距离矩阵
	public void readData(String filename) throws IOException  {
		int[] x=new int[citynumbers];//存放x坐标的数组
		int[] y=new int[citynumbers];//存放y坐标的数组
		distance=new double[citynumbers][citynumbers];//距离矩阵
		String a;
		BufferedReader in=new BufferedReader(new InputStreamReader(
				new FileInputStream(filename)));
		for(int i=0;i<citynumbers;i++) {
			a=in.readLine();//读入一行数据
			String[] b=a.split(" ");//分隔出每个值
			x[i]=Integer.valueOf(b[1]);//x坐标数组
			y[i]=Integer.valueOf(b[2]);//y坐标数组
		}
		in.close();
		//计算距离矩阵
		for(int i=0;i<citynumbers;i++) {
			for(int j=0;j<citynumbers;j++) {
				distance[i][j]=Math.sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));//计算欧式距离
			}
		}
	}
	
	public void solve() {
		visited=new int[citynumbers];//确定是否访问过
		path=new int[citynumbers];
		for(int i=0;i<citynumbers;i++) {
			visited[i]=0;//0代表未被访问过,1代表访问过
		}
		path[0]=1;//从城市1开始
		visited[0]=1;//城市1访问置1
		int k=0; //k代表当前的城市,0代表城市1
		int next=k+1;//next表示下一个访问城市,每次开始先确定为k+1
		double min=Double.MAX_VALUE;//min代表最小距离,设置为这个数,必然会被更新
		int count=1;//计数
		while( count<citynumbers) {
			for(int j=0;j<citynumbers;j++) {
				if(visited[j]==0) {//未被访问
					if(distance[k][j]<min) {//找到更小的距离值,则更新距离最小值
						min=distance[k][j];
						next=j;
					}
				}
			}
			s=s+min;//累加距离
			path[count]=next+1;//存放找到下一个城市
			visited[next]=1;//置访问标记为1
			k=next;//更新当前城市
			count++;
			min=Double.MAX_VALUE;//更新最小值
			next=k+1;
		}
	}
	
	public void print() {
		s=s+distance[path[citynumbers-1]-1][0];//加上最后一个城市到最开始城市的距离
		for(int i=0;i<citynumbers;i++) {
			System.out.print(path[i]+" ");//打印城市,缺少最开始的城市号在下面打印
		}
		System.out.println(path[0]);
		System.out.println(s);//打印距离
		
	}
	
	public static void main(String[] args)throws IOException {
		long a=System.currentTimeMillis();
		GreedyAlgorithm tsp=new GreedyAlgorithm(10);//建立对象,根据需要初始化10,25或100
		tsp.readData("D://TSP10cities.tsp");//读取数据
		tsp.solve();
		tsp.print();//打印
		long b=System.currentTimeMillis();
		long c=b-a;
		System.out.println("运行时间为:"+c);//输出运行时间
	}
}


输出如下:

1 10 9 6 4 3 2 8 5 7 1
10464.183486532447
运行时间为:4


 
 


猜你喜欢

转载自blog.csdn.net/qq_39233184/article/details/80904747