(回溯法)解旅行售货员问题又称tsp问题

目录

1、问题描述

2、思想分析

3、代码实现


1、问题描述

 

2、思想分析

根据所得题目来进行分析:

然后进行以下步骤直观化,接着根据思路实现。i代表层数 cc存放当前权值。bestc存放最优权值 

x[]存放当前解路径,bestx[]存放最优路径。然后思想步骤实现如下图所示,下面进行代码实现。

        

3、代码实现

package com.xxxy.javase.tsp;
/*
售货员从城市1出发,到其他3个城市售货,最后返回城市1,给定各城市间路费消耗,求总消耗最小的花费以及路径。



输出示例:

最少花费:25.0

1->3->2->4
 */

public class Bttsp {
    static int n;  //图G的顶点数
    static int[]x; //当前解
    static int[] bestx; //当前最优解
    static float bestc;//当前最优值
    static float cc;  //当前费用
    static float[][] a; //图G的邻接矩阵

    public static void main(String[] args) {
        n = 4;
        float m = Float.MAX_VALUE;
        //初始化 图的邻接矩阵
        a = new float[][]{{0,0,0,0,0},
                {0,m,30,6,4},
                {0,30,m,5,10},
                {0,6,5,m,20},
                {0,4,10,20,m}};
        int[] v = new int[5];
        float bestc = tsp(v);//返回最少的花费值 同时在tsp方法中将最优路径赋给了 v数组
        System.out.println("最少花费:" + bestc);

        //打印路径
        for(int i = 1; i < v.length; i++)
        {
            if( i + 1 == v.length)
            {
                System.out.print(v[i]);
                break;
            }
            System.out.print(v[i] + "-->");//当数组中存放的每个路径
        }
    }

    public static float tsp(int[] v){
        //x为单位的全排列
        x = new int[n+1];
        for (int i = 1; i <= n; i++)
        {
            x[i] = i;
        }
        bestc = Float.MAX_VALUE;
        bestx = v;
        cc = 0;
        //搜索 x[2:n]的全排列
        backtrack(2);
        return bestc;
    }

    public static void backtrack(int i) {
        if( i == n)
        {
            if(a[x[n-1]][x[n]] < Float.MAX_VALUE &&
                    a[x[n]][1] < Float.MAX_VALUE &&
                    (bestc == Float.MAX_VALUE || cc + a[x[n-1]][x[n]] + a[x[n]][1] < bestc))
            {
                for(int j = 1; j <= n; j++)
                {
                    bestx[j] = x[j];
                }
                bestc = cc + a[x[n-1]][x[n]] + a[x[n]][1];
            }
        }
        else
        {
            for(int j = i; j <= n; j++)
            {
                //是否可以进入x[i]子树
                if(a[x[i-1]][x[j]] < Float.MAX_VALUE &&
                        (bestc == Float.MAX_VALUE || cc + a[x[i-1]][x[j]] < bestc))
                {
                    //搜索子树
                    MyMath.swap(x, i, j);
                    cc += a[x[i-1]][x[i]];
                    backtrack(i+1);
                    cc -= a[x[i-1]][x[i]];
                    MyMath.swap(x,i,j);
                }
            }
        }
    }

}


class MyMath{
    public static void swap(int[] x, int i, int j){
        int temp = x[i];
        x[i] = x[j];
        x[j] = temp;
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用伪代码实现回溯旅行售货员问题的示例: ``` function TSP(graph): n = len(graph) visited = [False] * n path = [] minDist = float('inf') def backtrack(curr, dist): nonlocal visited, path, minDist # 如果当前路径长度已经大于等于当前最小长度,则可以直接返回 if dist >= minDist: return # 如果已经访问了所有节点,则更新最小路径长度和最短路径 if all(visited): minDist = dist path = path[:] # 遍历当前节点的所有邻居节点 for neighbor in range(n): # 如果邻居节点还没有访问过,则可以将其加入路径中 if not visited[neighbor]: visited[neighbor] = True path.append(neighbor) backtrack(neighbor, dist + graph[curr][neighbor]) path.pop() visited[neighbor] = False # 从第一个节点开始回溯 visited[0] = True path.append(0) backtrack(0, 0) return path, minDist ``` 其中,`graph` 是一个二维列表,表示完全图的邻接矩阵。函数的返回值是一个元组,表示最短路径和最小路径长度。在回溯过程中,使用一个 `visited` 列表来记录每个节点是否已经访问过,使用一个 `path` 列表来记录当前路径。在每次回溯时,遍历当前节点的所有邻居节点,如果邻居节点还没有访问过,则可以将其加入路径中。如果已经访问了所有节点,则更新最小路径长度和最短路径。如果当前路径长度已经大于等于当前最小长度,则可以直接返回。最后,从第一个节点开始回溯,返回最短路径和最小路径长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值