输入为城市距离的文件,文件格式如下:
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