.用貪心演算法解決TSP問題
旅行商問題,即TSP問題(Traveling Salesman Problem)又譯為旅行推銷員問題、貨郎擔問題,是數學領域中著名問題之一。假設有一個旅行商人要拜訪n個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而且最後要回到原來出發的城市。路徑的選擇目標是要求得的路徑路程為所有路徑之中的最小值。
環境:程式使用語言java,jdk版本1.8,程式中用到的jar包:poi-3.17
專案匯入:
3.實驗主要原始碼
City.java//城市類,結構體
package TSP;
publicclass city {
privateintname;
privatedoubleX;
privatedouble
public city(intname, doublex, doubley) {
super();
this.name = name-1;
X = x;
Y = y;
}
publicint getName() {
returnname;
}
publicvoid setName(intname) {
this.name = name;
}
publicdouble getX() {
returnX;
}
publicvoid setX(doublex) {
X = x;
}
publicdouble getY() {
returnY;
}
publicvoid setY(doubley) {
Y = y;
}
@Override
public String toString() {
return"city [name=" + name + ",X=" + X + ", Y=" + Y + "]";
}
}
inputData.Java//匯入資料類
package TSP;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
publicclass inputData {
@SuppressWarnings("resource")
publicstatic List<city> input_att48(File file){
List<city> cityList = new ArrayList<city>();
try {
HSSFWorkbook wookbook = new HSSFWorkbook(new FileInputStream(file));
HSSFSheet sheet = wookbook.getSheet("Sheet1");
introws = sheet.getPhysicalNumberOfRows();
for(inti=1; i<rows; i++){
HSSFRow row = sheet.getRow(i);
if(row!=null){
city cy = new city(i, row.getCell(1).getNumericCellValue(), row.getCell(2).getNumericCellValue());
cityList.add(cy);
}
}
} catch (FileNotFoundException e) {
System.out.println("File not fount!");
} catch (IOException e) {
System.out.println("IO exception!");
}
returncityList;
}
}
Greedy.Java//核心程式碼
package TSP;
import java.io.File;
import java.util.List;
import java.util.Scanner;
publicclass greedy {
staticdoubleINF = Double.MAX_VALUE;
staticdouble[][] DT = null;
staticint[] mark = null;
staticint[] path = null;
staticdouble solve(intn) {
doublepathLenght = 0;
File file = new File("E:\\Java\\arithmetic\\src\\resource\\att48.xls");
List<city> cityList = inputData.input_att48(file);
System.out.println("city [城市編號城市X座標城市Y座標]");
for(inti=0; i<n; i++) {
System.out.println(cityList.get(i).toString());
}
DT = newdouble[n][n];
mark = newint[n];
path = newint[n+1];
for(inti=0; i<n; i++) {
for(intj=i; j<n; j++) {
if(i==j) DT[i][j] = 0;
else {
doubledertX = cityList.get(i).getX()-cityList.get(j).getX();
doubledertY = cityList.get(i).getY()-cityList.get(j).getY();
DT[i][j] = Math.sqrt(dertX*dertX + dertY*dertY);
DT[j][i] = DT[i][j];
}
}
}
ints = 0;//s起點
intv = s;//v當前點
mark[v] = 1;
path[0] = v;//第一個城市
intcnt = 1;
while(cnt<n) {
doublemin = INF;
for(inti=1; i<n; i++) {
if(mark[i]==0) {
if(DT[v][i] < min) {
min = DT[v][i];
path[cnt] = i;
}
}
}
pathLenght += min;
v = path[cnt++];//先複製後cnt++
mark[v] = 1;
}
pathLenght += DT[path[v]][s];
path[cnt] = s;
returnpathLenght;
}
@SuppressWarnings("resource")
publicstaticvoid main(String[] args) {
System.out.println("----------------貪心演算法解決TSP問題----------------");
Scanner in = new Scanner(System.in);
while(true) {
System.out.println();
System.out.println("請輸入城市數:");
intn = in.nextInt();
if(n>48) {
System.out.println("樣例有限,城市數不能超過48!");
return;
}
doublepathLength = solve(n);
System.out.println("旅行路線:");
System.out.print(path[0]);
for(inti=1; i<=n; i++) {
System.out.print("->");
System.out.print(path[i]);
}
System.out.println();
System.out.print("路線長度:");
System.out.println(pathLength);
}
}
}
輸入輸出: