使用贪心策略实现TSP
数据集为att48
package com.TSP;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class MyTSP {
private double[][] dArray; //距离矩阵
MyTSP(){
}
MyTSP(double[][] first, int start){
Double cost =0.0;
List<Integer> alreadypass = new LinkedList<Integer>();
alreadypass.add(start);
while(alreadypass.size()<first.length){
int i = ((LinkedList<Integer>) alreadypass).getLast();
//System.out.println("i"+i);
double minLength = -1;
int nextcity =-1;
for(int k =0;k<first.length;k++){
if(minLength<first[i][k]){
minLength = first[i][k];
}
}
for(int j = 0;j<first.length;j++){
if(first[i][j] != 0 ) {
if(first[i][j] < minLength){
// System.out.println(first[i][j]);
if(alreadypass.contains(j)){
}else{
minLength = first[i][j];
nextcity = j;
}
}
}
}
if(nextcity == -1 && !alreadypass.contains(i+1)){
alreadypass.add(i+1);
}else if (nextcity != -1){
alreadypass.add(nextcity);
cost = cost+first[start][nextcity];
}
}
System.out.println("路径"+alreadypass);
cost = cost+ first[((LinkedList<Integer>) alreadypass).getLast()][start];
System.out.println("cost"+cost );
}
public static void main(String[] args) {
double[][] first =
{
{0, 2, 1, 3, 4, 5, 5, 6},
{2, 0, 4, 4, 2, 5, 5, 6},
{1, 4, 0, 2, 2, 6, 5, 6},
{3, 4, 2, 0, 3, 2, 5, 6},
{4, 2, 2, 3, 0, 3, 5, 6},
{5, 5, 6, 2, 3, 0, 5, 6},
{5, 5, 5, 5, 5, 5, 0, 6},
{6, 6, 6, 6, 6, 6, 6, 0}
};
/* double[][] first =
{
{0, 2},
{2, 0}
};*/
long start = System.currentTimeMillis();
//起点序号
int mystart = 0;
long start1 = System.currentTimeMillis();
MyTSP ff = new MyTSP(first,mystart);
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1 + "毫秒");
double[][] distance;
try {
distance = ff.init("/Users/pathplanning/TSPatt48.xml");
new MyTSP(distance,mystart);
} catch (IOException e) {
e.printStackTrace();
}
}
//att48.xml 处理程序
// http://elib.zib.de/pub/mp-testdata/tsp/tsplib/tsp/att48.tsp
private double[][] init(String filename) throws IOException {
// private int cityNum; // 城市数量
double[][] distance; // 距离矩阵
double[] colable;//代表列,也表示是否走过,走过置0
double[] row;//代表行,选过置0
int cityNum = 48;
// 读取数据
int[] x;
int[] y;
String strbuff;
BufferedReader data = new BufferedReader(new InputStreamReader(
new FileInputStream(filename)));
distance = new double[cityNum][cityNum];
x = new int[cityNum];
y = new int[cityNum];
for (int i = 0; i < cityNum; i++) {
// 读取一行数据,数据格式1 6734 1453
strbuff = data.readLine();
// 字符分割
String[] strcol = strbuff.split(" ");
x[i] = Integer.valueOf(strcol[1]);// x坐标
y[i] = Integer.valueOf(strcol[2]);// y坐标
}
data.close();
// 计算距离矩阵
// ,针对具体问题,距离计算方法也不一样,此处用的是att48作为案例,它有48个城市,距离计算方法为伪欧氏距离,最优值为10628
for (int i = 0; i < cityNum - 1; i++) {
distance[i][i] = 0; // 对角线为0
for (int j = i + 1; j < cityNum; j++) {
double rij = Math
.sqrt(((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j])
* (y[i] - y[j])) / 10.0);
// 四舍五入,取整
int tij = (int) Math.round(rij);
if (tij < rij) {
distance[i][j] = tij + 1;
distance[j][i] = distance[i][j];
} else {
distance[i][j] = tij;
distance[j][i] = distance[i][j];
}
}
}
distance[cityNum - 1][cityNum - 1] = 0;
colable = new double[cityNum];
colable[0] = 0;
for (int i = 1; i < cityNum; i++) {
colable[i] = 1;
}
row = new double[cityNum];
for (int i = 0; i < cityNum; i++) {
row[i] = 1;
}
return distance;
}
}
使用att48数据集
http://elib.zib.de/pub/mp-testdata/tsp/tsplib/tsp/att48.tsp
使用att48数据集后发现代价太大超过4w
该数据集平均代价应该为1w2左右
贪心策略并不适合求解TSP的全局最优解
未完待续