旅行商问题 (TSP) 实施
旅行商问题(TSP):给定一组城市和每对城市之间的距离,问题是找到最短的可能路线,该路线恰好访问每个城市一次并返回起点。
注意哈密顿循环和 TSP 之间的区别。哈密顿循环问题是找出是否存在一个游览每个城市恰好一次的游览。在这里我们知道 Hamiltonian Tour 存在(因为图是完整的),实际上存在很多这样的 tours,问题是要找到一个最小权重的 Hamiltonian Cycle。
例如,考虑右侧图中所示的图表。图中的 TSP 巡回是 1-2-4-3-1。旅游费用为10+25+30+15,即80。
这个问题是一个著名的 NP-hard 问题。这个问题没有多项式时间已知的解决方案。
例子:
Output of Given Graph:
minimum weight Hamiltonian Cycle :
10 + 25 + 30 + 15 := 80
在这篇文章中,讨论了一个简单解决方案的实现。
- 将城市 1 视为起点和终点。由于路线是循环的,我们可以将任何点视为起点。
- 生成所有(n-1)!城市的排列。
- 计算每个排列的成本并跟踪最小成本排列。
- 以最小成本返回排列。
下面是上述想法的实现
C++
// CPP program to implement traveling salesman
// problem using naive approach.
#include
using namespace std;
#define V 4
// implementation of traveling Salesman Problem
int travllingSalesmanProblem(int graph[][V], int s)
{
// store all vertex apart from source vertex
vector vertex;
for (int i = 0; i < V; i++)
if (i != s)
vertex.push_back(i);
// store minimum weight Hamiltonian Cycle.
int min_path = INT_MAX;
do {
// store current Path weight(cost)
int current_pathweight = 0;
// compute current path weight
int k = s;
for (int i = 0; i < vertex.size(); i++) {
current_pathweight += graph[k][vertex[i]];
k = vertex[i];
}
current_pathweight += graph[k][s];
// update minimum
min_path = min(min_path, current_pathweight);
} while (
next_permutation(vertex.begin(), vertex.end()));
return min_path;
}
// Driver Code
int main()
{
// matrix representation of graph
int graph[][V] = { { 0, 10, 15, 20 },
{ 10, 0, 35, 25 },
{ 15, 35, 0, 30 },
{ 20, 25, 30, 0 } };
int s = 0;
cout << travllingSalesmanProblem(graph, s) << endl;
return 0;
}
Java
// Java program to implement
// traveling salesman problem
// using naive approach.
import java.util.*;
class GFG{
static int V = 4;
// implementation of traveling
// Salesman Problem
static int travllingSalesmanProblem(int graph[][],
int s)
{
// store all vertex apart
// from source vertex
ArrayList vertex =
new ArrayList();
for (int i = 0; i < V; i++)
if (i != s)
vertex.add(i);
// store minimum weight
// Hamiltonian Cycle.
int min_path = Integer.MAX_VALUE;
do
{
// store current Path weight(cost)
int current_pathweight = 0;
// compute current path weight
int k = s;
for (int i = 0;
i < vertex.size(); i++)
{
current_pathweight +=
graph[k][vertex.get(i)];
k = vertex.get(i);
}
current_pathweight += graph[k][s];
// update minimum
min_path = Math.min(min_path,
current_pathweight);
} while (findNextPermutation(vertex));
return min_path;
}
// Function to swap the data
// present in the left and right indices
public static ArrayList swap(
ArrayList data,
int left, int right)
{
// Swap the data
int temp = data.get(left);
data.set(left, data.get(right));
data.set(right, temp);
// Return the updated array
return data;
}
// Function to reverse the sub-array
// starting from left to the right
// both inclusive
public static ArrayList reverse(
ArrayList data,
int left, int right)
{
// Reverse the sub-array
while (left < right)
{
int temp = data.get(left);
data.set(left++,
data.get(right));
data.set(right--, temp);
}
// Return the updated array
return data;
}
// Function to find the next permutation
// of the given integer array
public static boolean findNextPermutation(
ArrayList data)
{
// If the given dataset is empty
// or contains only one element
// next_permutation is not possible
if (data.size() <= 1)
return false;
int last = data.size() - 2;
// find the longest non-increasing
// suffix and find the pivot
while (last >= 0)
{
if (data.get(last) <
data.get(last + 1))
{
break;
}
last--;
}
// If there is no increasing pair
// there is no higher order permutation
if (last < 0)
return false;
int nextGreater = data.size() - 1;
// Find the rightmost successor
// to the pivot
for (int i = data.size() - 1;
i > last; i--) {
if (data.get(i) >
data.get(last))
{
nextGreater = i;
break;
}
}
// Swap the successor and
// the pivot
data = swap(data,
nextGreater, last);
// Reverse the suffix
data = reverse(data, last + 1,
data.size() - 1);
// Return true as the
// next_permutation is done
return true;
}
// Driver Code
public static void main(String args[])
{
// matrix representation of graph
int graph[][] = {{0, 10, 15, 20},
{10, 0, 35, 25},
{15, 35, 0, 30},
{20, 25, 30, 0}};
int s = 0;
System.out.println(
travllingSalesmanProblem(graph, s));
}
}
// This code is contributed by adityapande88
Python3
# Python3 program to implement traveling salesman
# problem using naive approach.
from sys import maxsize
from itertools import permutations
V = 4
# implementation of traveling Salesman Problem
def travellingSalesmanProblem(graph, s):
# store all vertex apart from source vertex
vertex = []
for i in range(V):
if i != s:
vertex.append(i)
# store minimum weight Hamiltonian Cycle
min_path = maxsize
next_permutation=permutations(vertex)
for i in next_permutation:
# store current Path weight(cost)
current_pathweight = 0
# compute current path weight
k = s
for j in i:
current_pathweight += graph[k][j]
k = j
current_pathweight += graph[k][s]
# update minimum
min_path = min(min_path, current_pathweight)
return min_path
# Driver Code
if __name__ == "__main__":
# matrix representation of graph
graph = [[0, 10, 15, 20], [10, 0, 35, 25],
[15, 35, 0, 30], [20, 25, 30, 0]]
s = 0
print(travellingSalesmanProblem(graph, s))
输出
80