用回溯算法解决TSP问题

10 篇文章 0 订阅
6 篇文章 0 订阅

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

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

jar包下载地址:Apache Download Mirrors

程序中使用的数据:下载地址:TSPLIB数据:att48_蚁群算法TSP问题-Java文档类资源-CSDN下载

项目导入:

3.实验主要源代码

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

package TSP;
 
public class city {
    private int name;
    private double X;
    private double Y;
    public city(int name, double x, double y) {
        super();
        this.name = name-1;
        X = x;
        Y = y;
    }
    
    public int getName() {
        return name;
    }
    
    public void setName(int name) {
        this.name = name;
    }
    
    public double getX() {
        return X;
    }
    
    public void setX(double x) {
        X = x;
    }
    
    public double getY() {
        return Y;
    }
    
    public void setY(double y) {
        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;
 
 
public class inputData {
 
    @SuppressWarnings("resource")
    public  static 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");
        int rows = sheet.getPhysicalNumberOfRows();
        for(int i=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!");
    }
        return cityList;
    }
}

backtrack.Java//核心代码

package TSP;

import java.io.File;
import java.util.List;
import java.util.Scanner;


public class backtrack {

    static double INF = Double.MAX_VALUE;
    static double[][] DT = null;
    static int[] mark = null;
    static int[] bestPath = null;
    static int[] curPath = null;
    static double bestPathLength = INF;
    static double curPathLength = 0;
    static int n = 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];
        mark = new int[n];
        bestPath = new int[n+1];
        curPath = new int[n+1];
        bestPathLength = INF;
        curPathLength = 0;
        for(int i=0; i<n; i++) {
            for(int j=i; j<n; j++) {
                if(i==j) DT[i][j] = 0;
                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(int i) {
        if(i >= n) {
            if(DT[curPath[i-1]][0]<INF && (curPathLength+DT[curPath[i-1]][0]<bestPathLength)) {
                bestPathLength = curPathLength+DT[curPath[i-1]][0];
                for(int j=0; j<n; j++) {
                    bestPath[j] = curPath[j];
                }
            }
        }
        else {
            for(int j=0; j<n; j++) {
                if(mark[j]==0 && DT[curPath[i-1]][j]<INF && curPathLength+DT[curPath[i-1]][j]<bestPathLength) {
                    curPath[i] = j;
                    curPathLength += DT[curPath[i-1]][j];
                    mark[j] = 1;
                    solve(i+1);
                    curPathLength -= DT[curPath[i-1]][j];
                    mark[j] = 0;
                }
            }
        }
    }

    @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();
            curPath[0] = 0;
            mark[0] = 1;
            solve(1);
            System.out.println("旅行路线:");
            System.out.print(bestPath[0]);
            for(int i=1; i<=n; i++) {
                System.out.print("->");
                System.out.print(bestPath[i]);
            }
            System.out.println();
            System.out.print("路线长度:");
            System.out.println(bestPathLength);
        }
    }


}

输入输出:

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值