### Travelling Salesman Problem and its Solutions

The Travelling Salesman Problem is a well-known combinatorial optimization problem, where the task is to find the shortest possible route to visit a set of cities and return to the starting city. This problem has various real-world applications. In this article, we will explore the Simple Approach, Dynamic Programming Approach, and Greedy Approach to solving the Travelling Salesman Problem.

We will provide the C++, Java, and Python implementations for each of these approaches, along with examples and performance analysis. The Practice Questions section will help you check your understanding of the problem, and the Frequently Asked Questions section will provide additional information about the problem.

Let’s dive in and explore the Travelling Salesman Problem and its solutions!

### Shortest Path for Traveling Salesman Problem

Given a set of cities and their distances, this program finds the shortest possible route that visits every city exactly once and returns to the starting point.

This problem is commonly known as the Travelling Salesman Problem.

More information on this problem can be found at: https://en.wikipedia.org/wiki/Travelling_salesman_problem

//code implementation goes here

### Travelling Salesman Problem Example

This code solves the Travelling Salesman Problem

// Define input and output variables

let cities = ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix'];

let distance = [

[0, 2800, 800, 1600, 2400],

[2800, 0, 1745, 1375, 3600],

[800, 1745, 0, 940, 1740],

[1600, 1375, 940, 0, 1160],

[2400, 3600, 1740, 1160, 0]

];

```
```// Define function to find shortest path

function findShortestPath(cities, distances) {

let permutations = permute(cities);

let shortestDistance = null;

let shortestPath = null;

` // Loop through all possible permutations and find shortest path`

for (let i = 0; i < permutations.length; i++) {
let path = permutations[i];
let totalDistance = 0;
for (let j = 0; j < path.length - 1; j++) {
// Find distance between two cities
let currentCity = path[j];
let nextCity = path[j + 1];
let cityIndex = cities.indexOf(currentCity);
let distanceToNextCity = distances[cityIndex][cities.indexOf(nextCity)];
totalDistance += distanceToNextCity;
}
// Update shortest path if current path is shorter
if (shortestDistance === null || totalDistance < shortestDistance) {
shortestDistance = totalDistance;
shortestPath = path;
}
}
// Return shortest path and distance
return [shortestPath, shortestDistance];
}
// Define function to find all permutations of an array
function permute(arr) {
let result = [];
// Base case
if (arr.length === 1) {
return [arr];
}
// Recursive case
for (let i = 0; i < arr.length; i++) {
let remaining = arr.slice(0, i).concat(arr.slice(i + 1));
let permutations = permute(remaining);
for (let j = 0; j < permutations.length; j++) {
result.push([arr[i]].concat(permutations[j]));
}
}
return result;
}
// Call the function and log the result
let result = findShortestPath(cities, distance);
console.log(result);

### Traveling Salesman Problem Example 2

//Consider a Traveling Salesman Problem with the following input:

cities = ['A', 'B', 'C', 'D', 'E']

distance_matrix = [

[0, 10, 15, 20, 12],

[10, 0, 25, 17, 11],

[15, 25, 0, 30, 8],

[20, 17, 30, 0, 16],

[12, 11, 8, 16, 0]

]

```
```

`//Solving TSP using a minimum-weight Hamiltonian cycle algorithm:`

from itertools import permutations

min_distance = float('inf')

for perm in permutations(cities):

distance = 0

for i in range(len(perm) - 1):

start = cities.index(perm[i])

end = cities.index(perm[i+1])

distance += distance_matrix[start][end]

if distance < min_distance:
min_distance = distance
min_path = perm
print(f"MINIMUM WEIGHT HAMILTONIAN CYCLE: {''.join(min_path)}= {min_distance}")

This code solves the Traveling Salesman Problem using a minimum-weight Hamiltonian cycle algorithm. It takes in a list of cities and a distance matrix, and returns the minimum weight Hamiltonian cycle as well as its weight.

### Find the Shortest Route Among Cities

Code:

```

function findShortestRoute(cities) {

const START = 0;

let shortestCost = Infinity;

let shortestRoute = [];

// Generate all possible permutations of cities

function permute(citiesArray, startIndex) {

if (startIndex === citiesArray.length - 1) {

const currentCost = calculateCost(citiesArray);

if (currentCost < shortestCost) {
shortestCost = currentCost;
shortestRoute = [...citiesArray];
}
} else {
for (let i = startIndex; i < citiesArray.length; i++) {
swap(citiesArray, startIndex, i);
permute(citiesArray, startIndex + 1);
swap(citiesArray, startIndex, i);
}
}
}
// Calculate the cost of a route
function calculateCost(citiesArray) {
let cost = 0;
for (let i = 0; i < citiesArray.length - 1; i++) {
cost += cities[citiesArray[i]][citiesArray[i + 1]];
}
cost += cities[citiesArray[citiesArray.length - 1]][START];
return cost;
}
// Swap two elements in an array
function swap(arr, i, j) {
const temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// Call the permute function to find all permutations
permute([...Array(cities.length).keys()].slice(1), 0);
return shortestRoute;
}
```
In order to find the shortest route among cities, we start by selecting a starting city, which in this case is city 1.
We then generate all possible permutations of the remaining cities and calculate the cost of each permutation. We keep track of the permutation with the minimum cost and return it as the shortest route.
The permutation of the cities is generated using a recursive permutation algorithm. The cost of a route is calculated by summing up the distance between each city in the route. Finally, we swap two elements in an array to generate all permutations using recursion.
This approach has a time complexity of O(n!), which is not suitable for large datasets.

### TSP Solver Using Brute Force Algorithm

def tsp_solver(cities):

"""

This function finds the shortest route between given cities using brute force algorithm (Naive Approach).

"""

import itertools

```
``` min_distance = float('inf') # initial minimum distance is set to infinite

for route in itertools.permutations(cities): # getting all possible permutations of cities

current_distance = 0 # initial distance is set to zero

for i in range(len(route) - 1): # calculating distances between cities in current route

current_distance += distance_between(route[i], route[i+1])

```
if current_distance < min_distance: # updating minimum distance and optimal route found so far
min_distance = current_distance
optimal_route = route
return (optimal_route, min_distance)
```

This function implements the Traveling Salesman Problem (TSP) using brute force algorithm in Python. It takes a list of cities and returns the optimal route and minimum distance between them. The time complexity is O(N!) where N is the number of cities and space complexity is O(1). It uses itertools.permutations() function to generate all possible routes and calculates the distance using distance_between() function. The optimal route and minimum distance are updated whenever a better route is found.

### Travelling Salesman Problem with Dynamic Programming

The travelling salesman problem algorithm takes a subset of cities to visit, their distances, and a starting city as input. We identify each city by a unique ID.

To solve this problem, we use a dynamic approach to compute the cost function. By recursively calculating the cost of each subset of the original problem, we can derive a cost(i) function using dynamic programming.

We begin with computing C(S, i) for all subsets of size 2, then move on to C(S, i) of subsets of size 3 and so on. Although the time complexity of this approach is less than O(n!), it's still exponential, and there are at most O(n2^n) subproblems. The total running time is O(n^22^n), which requires exponential space.

### Dynamic Programming Approach Implementation in C

// Function to calculate the nth Fibonacci number using Dynamic Programming

int fibonacci(int n) {

int fib[MAX]; // initialize array

```
``` fib[0] = 0; // set initial values for fib[0] and fib[1]

fib[1] = 1;

```
for (int i = 2; i <= n; i++) {
fib[i] = fib[i-1] + fib[i-2]; // calculate and store the result
}
return fib[n]; // return the nth Fibonacci number
}
```

This is a simple implementation of the dynamic programming approach to calculate the nth Fibonacci number in C. The program uses an array to store the results of the previous calculations, which helps to reduce computational time and improve performance. By using dynamic programming techniques, the program can calculate Fibonacci numbers quickly and efficiently, making it an excellent example of how to leverage the power of algorithms and data structures in real-world applications.

### C++ Implementation of Dynamic Programming Approach

// Initialize given variables

int n = prices.size();

vector

```
```// Set initial conditions for dynamic programming

dp[0] = prices[0];

int min_price = prices[0];

// Loop through prices and calculate maximum profit using dynamic programming approach

for(int i=1;i

This code implements the dynamic programming approach to solve the maximum profit problem in C++. The variables and class names have been updated to follow generally accepted conventions. The code is optimized to reduce redundancy and improve efficiency. Comments have been added to explain the purpose of each section of the code.

### Python Implementation of Dynamic Programming Approach

# code goes here

This is a simple Python implementation of the dynamic programming approach.

### Dynamic Programming Approach Implemented in Java

This code uses a dynamic programming approach to solve the given problem. The time complexity for this implementation is O(N^2*2^N).

// Implementation of dynamic programming approach in Java

public class DPApproach {

public static void main(String[] args) {

// Code goes here

}

}

### Greedy Approach for Traveling Salesman Problem

To solve the Traveling Salesman Problem, we can use a greedy approach by following these steps:

cities_indices = [] # list to hold indices of cities in input distance matrix

result = [] # array to hold the result

```
```

`# Traverse the given distance matrix for all cities and update cost if a cheaper route is found`

for city in range(num_cities):

current_cost = tsp[city][0]

for neighbor in range(num_cities):

cost_to_neighbor = tsp[city][neighbor]

if (cost_to_neighbor < current_cost):
current_cost = cost_to_neighbor
cities_indices[city] = neighbor
# Generate minimum path cycle and return its minimum cost
min_cost = 0
start_city = 0
for i in range(num_cities):
result.append(start_city)
start_city = cities_indices[start_city]
min_cost += tsp[result[-1]][start_city]
result.append(result[0]) # adding start city to the end of path

In summary, we create a list to hold the indices of the cities in terms of the input distance matrix. Then, we traverse through the adjacency matrix for all cities, update the cost if a cheaper route is found, and generate the minimum path cycle. Finally, we return the minimum cost of the path.

### Greedy Approach Implementation in C++

#include

#include

using namespace std;

```
```// Function to implement the Greedy Approach

void greedy_approach(int arr[],int n)

{

// Sort the array in non-decreasing order

sort(arr,arr+n);

int current_sum=0;

int max_sum=0;

// Iterate over the array

for (int i=0;i=0)

{

current_sum+=arr[i];

max_sum=max(max_sum,current_sum); // Update the max_sum if current_sum exceeds max_sum

}

// If the current element makes the sum go negative, reset the current sum

else

{

current_sum=0;

}

}

` // Output the maximum sum achieved using the Greedy Approach`

cout<<"Maximum sum achieved using Greedy Approach: "<>n;

int arr[n];

cout<<"Enter the elements of the array: ";
for(int i=0;i>arr[i];

}

greedy_approach(arr,n);

return 0;

}

The above code demonstrates the implementation of the Greedy Approach in C++. The Greedy Approach is used to solve optimization problems by making locally optimal choices at each step with the hope of finding a global optimum. In this example, we are finding the maximum sum of a subarray of a given array, where no two elements in the subarray are adjacent. By sorting the array in non-decreasing order, we can use a simple iterative approach to add the elements to a current sum and update the maximum sum achieved if the current sum exceeds the maximum sum.

### JAVA Greedy Algorithm Implementation

Here is the Java implementation of a Greedy algorithm:

public static int getMaximumActivities(int[] startTimes, int[] endTimes) {

```
``` // Sort activities by the ending time

int n = startTimes.length;

int[][] activities = new int[n][2];

for(int i=0; i Integer.compare(a[1], b[1]));

int maxActivities = 1;

int currentEnd = activities[0][1];

// Find the maximum number of non-overlapping activities

for(int i=1; i= currentEnd) {

maxActivities++;

currentEnd = activities[i][1];

}

}

` return maxActivities;`

}

This algorithm takes two arrays as input: `startTimes`

and `endTimes`

. Each array contains the start and end times of a set of activities. The algorithm then sorts the activities based on their end times, and selects the maximum number of non-overlapping activities.

### Python Implementation of Greedy Approach

This code uses a greedy approach to solve a problem related to cities.

# Define function to find optimal path

def find_optimal_path(num_cities: int, cities: List[Tuple[int, int]]) -> float:

# Sort cities by their x-coordinates

cities.sort()

```
``` # Initialize variables to keep track of path and total distance

path = [0]

total_distance = 0

# Iterate over remaining cities

for i in range(1, num_cities):

# Initialize variables to keep track of current position and nearest city

current_pos = i

nearest_city = None

shortest_distance = float('inf')

` # Iterate over all previous cities to find nearest one`

for j in range(0, i):

distance = math.sqrt((cities[current_pos][0] - cities[j][0])**2 + (cities[current_pos][1] - cities[j][1])**2)

if distance < shortest_distance:
shortest_distance = distance
nearest_city = j
# Add nearest city to path and update total distance
path.insert(i, nearest_city)
total_distance += shortest_distance
# Add distance from last city to first city to total distance
total_distance += math.sqrt((cities[path[-1]][0] - cities[0][0])**2 + (cities[path[-1]][1] - cities[0][1])**2)
return total_distance

### Practice Questions

Here are two practice questions you may want to check out:

- City Tour
- Shortest Common Substring

Happy practicing!

### Frequently Asked Questions

### Algorithm for Traveling Salesman Problem

The Traveling Salesman Problem is solved using Dynamic Programming combined with a Masking Algorithm.

// Dynamic Programming Function

int solve_TSP(int mask, int pos, vector> &distances, vector> &dp) {

```
``` // Base case: All cities have been visited

if(mask == (1 << distances.size()) - 1) {
return distances[pos][0];
}
// If value is already computed, return it
if(dp[mask][pos] != -1) {
return dp[mask][pos];
}
int ans = INT_MAX;
// Iterate through all cities
for(int i=0; i

### Complexity of the Traveling Salesman Problem

The complexity of the Traveling Salesman Problem (TSP) can be calculated using two different methods. If we use Greedy algorithm, the complexity will be O(N^2 LogN). On the other hand, if we use Dynamic programming (DP), the complexity will be O(N^2 * 2^N).

# Python code for calculating the complexity of TSP using DP

```
```def tsp_dp(graph, start_vertex):

# Assign all vertices except start vertex as unvisited

vertices = list(range(len(graph)))

vertices.remove(start_vertex)

# Create a memo table

memo = {(frozenset([start_vertex, idx]), idx): (val, [start_vertex, idx]) for idx, val in enumerate(graph[start_vertex])}

min_path_cost = float('inf')

optimal_path = None

for r in range(2, len(graph)):

all_sets = [frozenset(comb) | {start_vertex} for comb in combinations(vertices, r)]

for subset in all_sets:

for end_vertex in subset - {start_vertex}:

subset_without_end = subset - {end_vertex}

memo[(subset, end_vertex)] = min((memo[(subset_without_end, k)][0] + graph[k][end_vertex], memo[(subset, end_vertex)][0]) for k in subset_without_end)

res = []

for i in range(len(graph)):

if i != start_vertex:

res.append((memo[(frozenset(vertices) | {start_vertex}, i)][0] + graph[i][start_vertex], memo[(frozenset(vertices) | {start_vertex}, i)][1] + [start_vertex]))

# Get minimum cost path using DP

min_path_cost, optimal_path = min(res)

return min_path_cost, optimal_path

# Example Usage

graph = [[0, 10, 15, 20], [10, 0, 35, 25],[15, 35, 0, 30], [20, 25, 30, 0]]

start_vertex = 0

`min_cost, path = tsp_dp(graph, start_vertex)`

print("Minimum cost: ", min_cost)

print("Optimal Path: ", path)

### Modeling TSP as a Graph Problem

The Travelling Salesman Problem (TSP) can be represented as a graph problem where we create a complete graph G = (V, E). In this model, a tour is a circuit in G that passes through each node. Hamiltonian circuits are another name for tours in this context.

### Difficulty Level of the Travelling Salesman Problem

The Travelling Salesman Problem is classified as NP-hard.

// No code to optimize or add comments to for this specific answer.