动态规划解决旅行商问题(TSP)的递归实现(Java)

动态规划(Dynamic Programming)是一种解决优化问题的常用方法,而旅行商问题(Traveling Salesman Problem,TSP)则是其中一种经典的优化问题。在本篇文章中,我们将探讨如何使用递归的方式实现动态规划解决TSP问题的算法,并给出相应的Java源代码。

TSP问题描述:
给定一组城市和它们之间的距离,旅行商问题要求在经过每个城市一次且只能经过一次的情况下,找到一条最短的路径,使得旅行商能够回到起始城市。这是一个NP-hard问题,因此使用动态规划来解决是一种有效的方法。

算法思路:

  1. 创建一个二维数组dp,其中dp[i][mask]表示从起始城市出发,经过mask表示的城市集合,最后到达城市i的最短路径长度。
  2. 初始化dp数组,将所有元素设置为无穷大(表示路径不存在)。
  3. 定义递归函数tsp,函数参数为当前城市cur和已经经过的城市集合mask。
  4. 如果mask表示的城市集合包含所有城市(即mask的二进制表示的每一位都为1),则返回从当前城市cur回到起始城市的距离作为结果。
  5. 如果dp[cur][mask]已经计算过(不为无穷大),则直接返回该值。
  6. 对于每个未经过的城市i,计算从cur到i的距离,并更新dp[cur][mask]为dp[cur][mask]和tsp(i, mask | (1 << i)) + distance[cur][i]的较小值。
  7. 返回dp[cur][mask]作为结果。
  8. 调用tsp函数,传入起始城市和初始的城市集合mask = 1(表示起始城市已经被经过),得到最短路径长度。

下面是Java代码实现:

import java.util.Arrays;

public class TSP {

    private static int[][] distance; // 城市之间的距离
    private static int[][] dp; // 动态规划数组

    public static int tsp(int cur, int mask) {
        if (mask == (1 << distance.length) - 1) {
            return distance[cur][0]; // 返回从当前城市回到起始城市的距离
        }

        if (dp[cur][mask] != -1) {
            return dp[cur][mask]; // 已经计算过,直接返回结果
        }

        int minDistance = Integer.MAX_VALUE;

        for (int i = 0; i < distance.length; i++) {
            if ((mask & (1 << i)) == 0) { // 未经过的城市
                int newDistance = distance[cur][i] + tsp(i, mask | (1 << i));
                minDistance = Math.min(minDistance, newDistance);
            }
        }

        dp[cur][mask] = minDistance; // 缓存结果
        return minDistance;
    }

    public static void main(String[] args) {
        distance = new int[][]{{0, 2, 9, 10}, {1, 0, 6, 4}, {15, 7, 0, 8}, {6, 3, 12, 0}};
        dp = new int[distance.length][1 << distance.length];
        for (int i = 0; i < dp.length; i++) {
            Arrays.fill(dp[i], -1);
        }

        int shortestDistance = tsp(0, 1); // 从城市0开始,初始城市集合为1(起始城市已经被经过)
        System.out.println("最短路径长度: " + shortestDistance);
    }
}

在上述代码中,我们通过递归的方式实现了动态规划解决TSP问题的算法。通过使用缓存数组dp,我们避免了重复计算子问题动态规划解决旅行商问题(TSP)的递归实现(Java)

动态规划(Dynamic Programming)是一种解决优化问题的常用方法,而旅行商问题(Traveling Salesman Problem,TSP)则是其中一种经典的优化问题。在本篇文章中,我们将探讨如何使用递归的方式实现动态规划解决TSP问题的算法,并给出相应的Java源代码。

TSP问题描述:
给定一组城市和它们之间的距离,旅行商问题要求在经过每个城市一次且只能经过一次的情况下,找到一条最短的路径,使得旅行商能够回到起始城市。这是一个NP-hard问题,因此使用动态规划来解决是一种有效的方法。

算法思路:

  1. 创建一个二维数组dp,其中dp[i][mask]表示从起始城市出发,经过mask表示的城市集合,最后到达城市i的最短路径长度。
  2. 初始化dp数组,将所有元素设置为无穷大(表示路径不存在)。
  3. 定义递归函数tsp,函数参数为当前城市cur和已经经过的城市集合mask。
  4. 如果mask表示的城市集合包含所有城市(即mask的二进制表示的每一位都为1),则返回从当前城市cur回到起始城市的距离作为结果。
  5. 如果dp[cur][mask]已经计算过(不为无穷大),则直接返回该值。
  6. 对于每个未经过的城市i,计算从cur到i的距离,并更新dp[cur][mask]为dp[cur][mask]和tsp(i, mask | (1 << i)) + distance[cur][i]的较小值。
  7. 返回dp[cur][mask]作为结果。
  8. 调用tsp函数,传入起始城市和初始的城市集合mask = 1(表示起始城市已经被经过),得到最短路径长度。

下面是Java代码实现:

import java.util.Arrays;

public class TSP {

    private static int[][] distance; // 城市之间的距离
    private static int[][] dp; // 动态规划数组

    public static int tsp(int cur, int mask) {
        if (mask == (1 << distance.length) - 1) {
            return distance[cur][0]; // 返回从当前城市回到起始城市的距离
        }

        if (dp[cur][mask] != -1) {
            return dp[cur][mask]; // 已经计算过,直接返回结果
        }

        int minDistance = Integer.MAX_VALUE;

        for (int i = 0; i < distance.length; i++) {
            if ((mask & (1 << i)) == 0) { // 未经过的城市
                int newDistance = distance[cur][i] + tsp(i, mask | (1 << i));
                minDistance = Math.min(minDistance, newDistance);
            }
        }

        dp[cur][mask] = minDistance; // 缓存结果
        return minDistance;
    }

    public static void main(String[] args) {
        distance = new int[][]{{0, 2, 9, 10}, {1, 0, 6, 4}, {15, 7, 0, 8}, {6, 3, 12, 0}};
        dp = new int[distance.length][1 << distance.length];
        for (int i = 0; i < dp.length; i++) {
            Arrays.fill(dp[i], -1);
        }

        int shortestDistance = tsp(0, 1); // 从城市0开始,初始城市集合为1(起始城市已经被经过)
        System.out.println("最短路径长度: " + shortestDistance);
    }
}

在上述代码中,我们通过递归的方式实现了动态规划解决TSP问题的算法。通过使用缓存数组dp,我们避免了重复计算子问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
旅行商问题TSP)是一个经典的优化问题,目标是在访问所有城市一次的情况下找到最短路径。动态规划解决TSP问题的一种常见方法。以下是使用动态规划解决TSP问题的C语言代码示例: ```c #include <stdio.h> #include <limits.h> #define N 4 // N为城市数 #define INF INT_MAX // 无穷大 int tsp(int graph[][N], int mask, int pos, int dp[][1<<N]) { if(mask == (1 << N) - 1) // 如果所有城市都已经访问 return graph[pos][0]; // 返回从当前城市到起点的距离(即回到起点) if(dp[pos][mask] != -1) // 如果已经计算过,则直接返回 return dp[pos][mask]; int ans = INF; for(int city = 0; city < N; city++) // 枚举下一个城市 { if((mask & (1 << city)) == 0) // 如果该城市没有被访问过 { int newAns = graph[pos][city] + tsp(graph, mask | (1 << city), city, dp); // 计算到该城市的距离,并递归计算下一个城市 ans = ans < newAns ? ans : newAns; // 取最小值 } } return dp[pos][mask] = ans; // 缓存结果并返回 } int main() { int graph[N][N] = { {0, 10, 15, 20}, {10, 0, 35, 25}, {15, 35, 0, 30}, {20, 25, 30, 0} }; int dp[N][1<<N]; for(int i=0; i<N; i++) for(int j=0; j<(1<<N); j++) dp[i][j] = -1; // 初始化缓存数组 printf("最短路径长度为 %d\n", tsp(graph, 1, 0, dp)); // 从第一个城市开始访问 return 0; } ``` 该代码使用了一个二维数组`dp[pos][mask]`来缓存每个子问题的结果。其中,`pos`表示当前所在的城市,`mask`表示已经访问过的城市的集合。如果某个子问题已经计算过,则直接从缓存中取出结果。否则,递归地计算下一个城市的最短路径,并取最小值。在递归结束时,将结果缓存起来以备后续使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值