📜  双音旅行商问题

📅  最后修改于: 2021-09-17 06:58:56             🧑  作者: Mango

给定一个二维数组, arr[][]表示二维空间上N个顶点的坐标列表,该列表已经按 x 坐标和 y 坐标排序,任务是找到从最左边开始的游览的最小距离顶点,严格地向右走,然后在到达最右边的顶点时,游览严格地从右到左回到起始顶点。

例子:

方法:上述问题可以使用动态规划解决。为了便于理解,问题可以改成两个人。两者都应该同时从最左边的点开始。沿着两条不同的路径走,最后到达最右边的点,除了起点和终点。

  • 每一点碰巧被一个人通过。这里, dp[i][j]表示第一个人走到i和第二个人走到j 的距离。
  • 解中dp[i][j]表示1max(i,j)都走了,两人当前的位置分别是ij ,需要走多远。
  • 另外,可以推论dp[i][j]等于dp[j][i] ,所以从现在开始规定i总是大于j,i>j状态。
  • 这样,不管那个人,下一步只能去到i+1、i+2、……这些点。
  • 因此,状态dp[i][j]只能转移到dp[i+1][j]dp[i][i+1]。

请按照以下步骤解决问题:

  • 创建一个大小为N*N的二维数组dp[][] 
  • 迭代表的最后一行dp ,并将dp[N-1][i]更新为distance(N-1, N)distance(i, N) 之和,其中distance(x, y)表示arr 的xthyth点之间的欧几里德距离。
  • 创建一个递归函数findTour(i, j)来填充所有其他单元格
    • dp[i][j]更新为findTour(i+1, j)+distance(i, i+1)findTour(i+1, i)+distance(j, i+1) 的最小值

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Size of the array a[]
const int mxN = 1005;
 
// Structure to store the x and
// y coordinates of a point
struct Coordinates {
    double x, y;
} a[mxN];
 
// Declare a 2-D dp array
float dp[mxN][mxN];
 
// Function to calculate the
// distance between two points
// in a Euclidian plane
float distance(int i, int j)
{
    // Return the distance
    return sqrt(
      (a[i].x - a[j].x) * (a[i].x - a[j].x)
    + (a[i].y - a[j].y) * (a[i].y - a[j].y));
}
 
// Utility recursive function to find
// the bitonic tour distance
float findTourDistance(int i, int j)
{
    // Memoization
    if (dp[i][j] > 0)
        return dp[i][j];
 
    // Update dp[i][j]
    dp[i][j] = min(
    findTourDistance(i + 1, j) + distance(i, i + 1),
    findTourDistance(i + 1, i) + distance(j, i + 1));
 
    return dp[i][j];
}
 
// Function to find the
// bitonic tour distance
void bitonicTSP(int N)
{
    // Initialize the dp array
    memset(dp, 0, sizeof(dp));
 
    // Base Case
    for (int j = 1; j < N - 1; j++)
        dp[N - 1][j] = distance(N - 1, N)
              + distance(j, N);
 
    // Print the answer
    printf("%.2f\n", findTourDistance(1, 1));
}
 
// Driver Code
int main()
{
    // Given Input
    int N = 3;
    a[1].x = 1, a[1].y = 1;
    a[2].x = 2, a[2].y = 3;
    a[3].x = 3, a[3].y = 1;
 
    // Function Call
    bitonicTSP(N);
}


输出
6.47

时间复杂度: O(N 2 )
辅助空间: O(N 2 )