用分枝限界算法解决TSP问题

旅行商问题,即TSP问题(Traveling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。

环境:程序使用语言java,jdk版本1.8,程序中用到的jar包:poi-3.17

jar包下载地址:https://www.apache.org/dyn/closer.lua/poi/release/bin/poi-bin-3.17-20170915.tar.gz

《用分枝限界算法解决TSP问题》

程序中使用的数据:下载地址:https://download.csdn.net/download/qq_35685675/10487174

《用分枝限界算法解决TSP问题》

项目导入:

《用分枝限界算法解决TSP问题》

3.实验主要源代码

City.java//城市类,结构体

package TSP;

publicclass city {

   privateintname;

   privatedoubleX;

   privatedoubleY;

   public city(intnamedoublexdoubley) {

      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<rowsi++){

             HSSFRow row = sheet.getRow(i);

             if(row!=null){

                city cy = new city(irow.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;

   }

}

 

BABM.Java//核心代码

package TSP;

import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

public class BABM {

static double INF = Double.MAX_VALUE;
static double[][] DT = null;
static double U = INF;
static double L = 0;
static int n = 0;
static int bestPathLength = 0;
static class point implements Cloneable{
int name = 0;
double length;
double g;
double h;
double f;
int count;
int[] mark = new int[n];
int[] path = new int[n+1];

public point(double length, double g, double h, double f, int count) {
super();
this.length = length;
this.g = g;
this.h = h;
this.f = f;
this.count = count;
}

@Override
public String toString() {
return “point [name=” + name + “, length=” + length + “, g=” + g + “, h=” + h + “, f=” + f + “, count=”
+ count + “, mark=” + Arrays.toString(mark) + “, path=” + Arrays.toString(path) + “]”;
}

public Object clone(){
point nd = null;
try {
nd = (point) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

nd.mark = new int[n];
for(int r=0; r<n; r++){
nd.mark[r] = this.mark[r];
}

nd.path = new int[n+1];
for(int r=0; r<=n; r++){
nd.path[r] = this.path[r];
}
return nd;
}
}

static Comparator<point> cmp = new Comparator<point>() {

@Override
public int compare(point o1, point o2) {
// TODO Auto-generated method stub
return o1.f < o2.f ? -1 : 1;
}
};

static point ans = new point(0, 0, 0, 0, 0);

static void init() {
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(int i=0; i<n; i++) {
System.out.println(cityList.get(i).toString());
}
DT = new double[n][n];
for(int i=0; i<n; i++) {
for(int j=i; j<n; j++) {
if(i==j) DT[i][j] = INF;
else {
double dertX = cityList.get(i).getX()-cityList.get(j).getX();
double dertY = cityList.get(i).getY()-cityList.get(j).getY();
DT[i][j] = Math.sqrt(dertX*dertX + dertY*dertY);
DT[j][i] = DT[i][j];
}
}
}
}

static void solve() {
Queue<point> q = new PriorityQueue<point>(cmp);
point cur = new point(0, 0, 0, 0, 0);
cur.mark[0] = 1;
q.add(cur);
while(!q.isEmpty()) {
cur = (point) q.poll().clone();
int count = 0;
for(int i=0; i<n; i++) {
count += cur.mark[i];
}
if(count==n) {
double t = cur.length+DT[cur.path[n-1]][0];
if(t < U) {
ans = (point) cur.clone();
U = t;
}
// return cur;
}
if(cur.length>U) continue;
for(int i=0; i<n; i++) {
if(cur.mark[i]!=0) continue;
// point next = new point(i, cur.length+DT[cur.name][i], 0, 0, cur.f+DT[cur.name][i]-1, j+1, temp);
point next = (point) cur.clone();
next.name = i;
next.length = cur.length+DT[cur.name][i];
next.f = cur.f + DT[cur.name][i] – 1;
int j=0;
for(j=1; j<=n; j++) {//将上一个点的路径复制到下一个点
if(cur.path[j]==0) break;
next.path[j] = cur.path[j];
}
next.path[j] = i;
next.mark[i] = 1;
q.add((point) next.clone());
}
}
return ;
}
@SuppressWarnings(“resource”)
public static void main(String[] args) {

// TODO Auto-generated method stub
System.out.println(“—————-分支界限算法解决TSP问题—————-“);
Scanner in = new Scanner(System.in);
while(true) {
System.out.println();
System.out.println(“请输入城市数:”);
n = in.nextInt();
if(n>48) {
System.out.println(“样例有限,城市数不能超过48!”);
return;
}
init();
solve();
System.out.println(“旅行路线:”);
System.out.print(ans.path[0]);
for(int i=1; i<=n; i++) {
System.out.print(“->”);
System.out.print(ans.path[i]);
}
System.out.println();
System.out.print(“路线长度:”);
System.out.println(ans.length+DT[ans.path[n-1]][0]);
}
}

}

输入输出

《用分枝限界算法解决TSP问题》

    原文作者:分支限界法
    原文地址: https://blog.csdn.net/qq_35685675/article/details/80740591
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞