# Bitonic Travelling Salesman Problem

Given a 2D array, arr[][] denoting a list of coordinates of N vertices on 2D space that is already sorted by x-coordinates and y-coordinates, the task is to find the minimum distance of a tour that starts from the leftmost vertex, and strictly goes to the right, and then upon reaching the rightmost vertex, the tour goes strictly from right to left-back to the starting vertex.

Examples:

Input: N = 7, arr[][] = {{0, 6}, {1 0}, {2 3}, {5 4}, {6 1}, {7 5}, {8 2}}
Output: 25.582
Explanation:

The TSP tour: 0-3-5-6-4-1-2-0 is not a Bitonic TSP tour because although the tour initially goes from left to right (0-3-5-6) and then goes back from right to left (6-4-1), it then makes another left to right (1-2) and then right to left (2-0) steps.
The tour: 0-2-3-5-6-4-1-0 is a valid Bitonic TSP tour because it can be decomposed into two paths: 0-2-3-5-6 that goes from left to right and 6-4-1-0 that goes back from right to left.

Input: N = 3, arr[][] = {{1, 1}, {2, 3}, {3, 1}}
Output: 6.47

Approach: The above problem can be solved using Dynamic Programming. For the sake of understanding, the problem can be changed into two people. Both should start from the leftmost point at the same time. Walk along two different paths, and finally reach the rightmost point, except for the starting point and the endpoint.

• Every point happens to be passed by one person. Here, dp[i][j] represents how far the first person walks to i and the second person walks to j.
• In the solution, dp[i][j] means that 1 to max(i, j) have all been walked, and the current positions of the two people are i and j respectively, and how far they need to go.
• Also, it can be inferred that dp[i][j] is equal to dp[j][i], so from now on it is stipulated that i is always greater than j i.e. i>j in the state.
• In this way, no matter that person, the next step can only go to i+1, i+2,… these points.
• So, the state dp[i][j] can only be transferred to dp[i+1][j] or dp[i][i+1].

Follow the steps below to solve the problem:

• Create a 2D array, dp[][] of size N*N.
• Iterate the last row of the table, dp, and update dp[N-1][i] to the sum of distance(N-1, N) and distance(i, N), where distance(x, y) represents the Euclidean distance between xth and yth points of arr.
• Create a recursive function findTour(i, j) to fill all other cells
• Update dp[i][j] to minimum of findTour(i+1, j)+distance(i, i+1) and findTour(i+1, i)+distance(j, i+1).

Below is the implementation of the above approach:

## 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 Euclidean 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);``}`

## Java

 `import` `java.util.Arrays;` `public` `class` `Main {``    ``// Size of the array a[]``    ``private` `static` `final` `int` `mxN = ``1005``;` `    ``// Structure to store the x and``    ``// y coordinates of a point``    ``private` `static` `class` `Coordinates {``        ``double` `x, y;``    ``}` `    ``private` `static` `Coordinates[] a = ``new` `Coordinates[mxN];` `    ``// Declare a 2-D dp array``    ``private` `static` `float``[][] dp = ``new` `float``[mxN][mxN];` `    ``// Function to calculate the``    ``// distance between two points``    ``// in a Euclidean plane``    ``private` `static` `float` `distance(``int` `i, ``int` `j)``    ``{``        ``// Return the distance``        ``return` `(``float``)Math.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``    ``private` `static` `float` `findTourDistance(``int` `i, ``int` `j)``    ``{``        ``// Memoization``        ``if` `(dp[i][j] > ``0``) {``            ``return` `dp[i][j];``        ``}` `        ``// Update dp[i][j]``        ``dp[i][j] = Math.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``    ``private` `static` `void` `bitonicTSP(``int` `N)``    ``{``        ``// Initialize the dp array``        ``for` `(``float``[] row : dp) {``            ``Arrays.fill(row, ``0``);``        ``}` `        ``// Base Case``        ``for` `(``int` `j = ``1``; j < N - ``1``; j++) {``            ``dp[N - ``1``][j]``                ``= distance(N - ``1``, N) + distance(j, N);``        ``}` `        ``// Print the answer``        ``System.out.printf(``"%.2f\n"``, findTourDistance(``1``, ``1``));``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``// Given Input``        ``int` `N = ``3``;``        ``a[``1``] = ``new` `Coordinates();``        ``a[``1``].x = ``1``;``        ``a[``1``].y = ``1``;``        ``a[``2``] = ``new` `Coordinates();``        ``a[``2``].x = ``2``;``        ``a[``2``].y = ``3``;``        ``a[``3``] = ``new` `Coordinates();``        ``a[``3``].x = ``3``;``        ``a[``3``].y = ``1``;` `        ``// Function Call``        ``bitonicTSP(N);``    ``}``}`

## Python3

 `import` `math` `N ``=` `3` `# Structure to store the x and y coordinates of a point``a ``=` `[{``"x"``: ``0``, ``"y"``: ``0``} ``for` `_ ``in` `range``(N``+``1``)]` `# Declare a 2-D dp array``dp ``=` `[[``0` `for` `_ ``in` `range``(N``+``1``)] ``for` `_ ``in` `range``(N``+``1``)]` `# Given Input``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 to calculate the distance between two points in a Euclidean plane`  `def` `distance(i, j):``    ``return` `math.sqrt((a[i][``'x'``] ``-` `a[j][``'x'``]) ``*``*` `2` `+` `(a[i][``'y'``] ``-` `a[j][``'y'``]) ``*``*` `2``)` `# Utility recursive function to find the bitonic tour distance`  `def` `findTourDistance(i, 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`  `def` `bitonicTSP(N):``    ``# Initialize the dp array``    ``for` `i ``in` `range``(N``+``1``):``        ``for` `j ``in` `range``(N``+``1``):``            ``dp[i][j] ``=` `0` `    ``# Base Case``    ``for` `j ``in` `range``(``1``, N``-``1``):``        ``dp[N``-``1``][j] ``=` `distance(N``-``1``, N) ``+` `distance(j, N)` `    ``# Print the answer``    ``print``(``"%.2f"` `%` `findTourDistance(``1``, ``1``))`  `# Function Call``bitonicTSP(N)`

## C#

 `using` `System;``using` `System.Linq;` `class` `MainClass``{``  ` `  ``// Size of the array a[]``  ``private` `static` `readonly` `int` `mxN = 1005;` `  ``// Structure to store the x and``  ``// y coordinates of a point``  ``private` `struct` `Coordinates { ``public` `double` `x, y; }` `  ``private` `static` `Coordinates[] a = ``new` `Coordinates[mxN];` `  ``// Declare a 2-D dp array``  ``private` `static` `float``[, ] dp = ``new` `float``[mxN, mxN];` `  ``// Function to calculate the``  ``// distance between two points``  ``// in a Euclidean plane``  ``private` `static` `float` `distance(``int` `i, ``int` `j)``  ``{``    ``// Return the distance``    ``return` `(``float``)Math.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``  ``private` `static` `float` `findTourDistance(``int` `i, ``int` `j)``  ``{``    ` `    ``// Memoization``    ``if` `(dp[i, j] > 0) {``      ``return` `dp[i, j];``    ``}` `    ``// Update dp[i][j]``    ``dp[i, j] = Math.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``  ``public` `static` `void` `bitonicTSP(``int` `N)``  ``{``    ``// Initialize the dp array``    ``for` `(``int` `i = 0; i < mxN; i++) {``      ``for` `(``int` `j = 0; j < mxN; j++) {``        ``dp[i, j] = 0;``      ``}``    ``}` `    ``// Base Case``    ``for` `(``int` `j = 1; j < N - 1; j++) {``      ``dp[N - 1, j]``        ``= distance(N - 1, N) + distance(j, N);``    ``}` `    ``// Print the answer``    ``Console.WriteLine(``"{0:0.00}"``,``                      ``findTourDistance(1, 1));``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main(String[] args)``  ``{``    ` `    ``// Given Input``    ``int` `N = 3;``    ``a[1] = ``new` `Coordinates();``    ``a[1].x = 1;``    ``a[1].y = 1;``    ``a[2] = ``new` `Coordinates();``    ``a[2].x = 2;``    ``a[2].y = 3;``    ``a[3] = ``new` `Coordinates();``    ``a[3].x = 3;``    ``a[3].y = 1;` `    ``// Function Call``    ``bitonicTSP(N);``  ``}``}` `// This code is contributed by divya_p123.`

## Javascript

 `// Javascript program for the above approach` `// Size of the array a[]``const mxN = 1005;` `// Structure to store the x and``// y coordinates of a point``class Coordinates {``    ``constructor(x,y)``    ``{``        ``this``.x=x;``        ``this``.y=y;``    ``}``}` `// Declare a 2-D dp array``let dp=``new` `Array(mxN);``for``(let i=0; i 0)``        ``return` `dp[i][j];` `    ``// Update dp[i][j]``    ``dp[i][j] = Math.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``function` `bitonicTSP( N)``{``    ``// Initialize the dp array``    ``for``(let i=0; i

Output
`6.47`

Time Complexity: O(N2)
Auxiliary Space: O(N2)

Efficient Approach: Using the DP Tabulation method(Iterative Approach) – The approach to solve this problem is the same but DP tabulation(bottom-up) method is better than the Dp + memoization(top-down) because the memoization method needs extra stack space of recursion calls.

Steps to solve this problem:

Follow the steps below to solve the problem:

• Create a 2D array, dp[][] of size N*N.
• Iterate the last row of the table, dp, and update dp[N-1][i] to the sum of distance(N-1, N) and distance(i, N), where distance(x, y) represents the Euclidean distance between xth and yth points of arr.
• Create a recursive function findTour(i, j) to fill all other cells
• Update dp[i][j] to minimum of findTour(i+1, j)+distance(i, i+1) and findTour(i+1, i)+distance(j, i+1).
• Create a DP to store the solution of the subproblems and initialize it with 0.
• Initialize the DP with base cases
• Now Iterate over subproblems to get the value of the current problem from the previous computation of subproblems as dp[i + 1][j] + distance(i, i+1) and dp[i + 1][i] + distance(j, i+1) and stored in the DP table.
• The value of dp[1][1] gives the resultant value.

Below is the implementation of the above approach:

## 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 Euclidean 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));``}` `// Function to find the``// bitonic tour distance``void` `bitonicTSP(``int` `N) {``    ``// Initialize the dp array``    ``memset``(dp, 0, ``sizeof``(dp));``    ` `    ``// Initialize the dp array``    ``for` `(``int` `j = 1; j < N - 1; j++)``        ``dp[N - 1][j] = distance(N - 1, N) + distance(j, N);` `    ``// Calculate dp values in a bottom-up manner``    ``for` `(``int` `i = N - 2; i >= 1; i--) {``        ``for` `(``int` `j = i; j >= 1; j--) {``            ``dp[i][j] = min(dp[i + 1][j] + distance(i, i + 1),``                           ``dp[i + 1][i] + distance(j, i + 1));``        ``}``    ``}``    ` `    ``// Print the answer``    ``printf``(``"%.2f\n"``, dp[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);``    ``return` `0;``}` `// --- by bhardwajji`

## Python3

 `import` `math` `# Size of the array a[]``mxN ``=` `1005` `# Structure to store the x and y coordinates of a point``class` `Coordinates:``    ``def` `__init__(``self``, x, y):``        ``self``.x ``=` `x``        ``self``.y ``=` `y` `a ``=` `[Coordinates(``0``, ``0``) ``for` `i ``in` `range``(mxN)]` `# Declare a 2-D dp array``dp ``=` `[[``0` `for` `j ``in` `range``(mxN)] ``for` `i ``in` `range``(mxN)]` `# Function to calculate the``# distance between two points``# in a Euclidean plane``def` `distance(i, j):``    ``# Return the distance``    ``return` `math.sqrt((a[i].x ``-` `a[j].x) ``*``*` `2``              ``+` `(a[i].y ``-` `a[j].y) ``*``*` `2``)` `# Function to find the``# bitonic tour distance``def` `bitonicTSP(N):``    ``# Initialize the dp array``    ``for` `i ``in` `range``(N``+``1``):``        ``for` `j ``in` `range``(N``+``1``):``            ``dp[i][j] ``=` `0``    ` `    ``# Initialize the dp array``    ``for` `j ``in` `range``(``1``, N ``-` `1``):``        ``dp[N ``-` `1``][j] ``=` `distance(N ``-` `1``, N) ``+` `distance(j, N)` `    ``# Calculate dp values in a bottom-up manner``    ``for` `i ``in` `range``(N ``-` `2``, ``0``, ``-``1``):``        ``for` `j ``in` `range``(i, ``0``, ``-``1``):``            ``dp[i][j] ``=` `min``(dp[i ``+` `1``][j] ``+` `distance(i, i ``+` `1``),``                           ``dp[i ``+` `1``][i] ``+` `distance(j, i ``+` `1``))``    ` `    ``# Print the answer``    ``print``(``"{:.2f}"``.``format``(dp[``1``][``1``]))` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``# Given Input``    ``N ``=` `3``    ``a[``1``].x, a[``1``].y ``=` `1``, ``1``    ``a[``2``].x, a[``2``].y ``=` `2``, ``3``    ``a[``3``].x, a[``3``].y ``=` `3``, ``1``    ` `    ``# Function Call``    ``bitonicTSP(N)`

## Java

 `import` `java.util.Arrays;` `public` `class` `Main {` `    ``// Size of the array a[]``    ``static` `final` `int` `mxN = ``1005``;` `    ``// Structure to store the x and``    ``// y coordinates of a point``    ``static` `class` `Coordinates {``        ``double` `x, y;` `        ``Coordinates(``double` `x, ``double` `y) {``            ``this``.x = x;``            ``this``.y = y;``        ``}``    ``}` `    ``static` `Coordinates[] a = ``new` `Coordinates[mxN];` `    ``// Declare a 2-D dp array``    ``static` `float``[][] dp = ``new` `float``[mxN][mxN];` `    ``// Function to calculate the``    ``// distance between two points``    ``// in a Euclidean plane``    ``static` `float` `distance(``int` `i, ``int` `j) {` `        ``// Return the distance``        ``return` `(``float``) Math.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));``    ``}` `    ``// Function to find the``    ``// bitonic tour distance``    ``static` `void` `bitonicTSP(``int` `N) {``        ``// Initialize the dp array``        ``for` `(``int` `i = ``0``; i < mxN; i++) {``            ``Arrays.fill(dp[i], Float.MAX_VALUE);``        ``}` `        ``// Initialize the dp array``        ``for` `(``int` `j = ``1``; j < N - ``1``; j++)``            ``dp[N - ``1``][j] = distance(N - ``1``, N) + distance(j, N);` `        ``// Calculate dp values in a bottom-up manner``        ``for` `(``int` `i = N - ``2``; i >= ``1``; i--) {``            ``for` `(``int` `j = i; j >= ``1``; j--) {``                ``dp[i][j] = Math.min(dp[i + ``1``][j] + distance(i, i + ``1``),``                        ``dp[i + ``1``][i] + distance(j, i + ``1``));``            ``}``        ``}` `        ``// Print the answer``        ``System.out.printf(``"%.2f\n"``, dp[``1``][``1``]);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args) {` `        ``// Given Input``        ``int` `N = ``3``;``        ``a[``1``] = ``new` `Coordinates(``1``, ``1``);``        ``a[``2``] = ``new` `Coordinates(``2``, ``3``);``        ``a[``3``] = ``new` `Coordinates(``3``, ``1``);` `        ``// Function Call``        ``bitonicTSP(N);``    ``}``}`

Output

`6.47`

Time Complexity: O(N2)
Auxiliary Space: O(N2)

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Previous
Next