📜  使用BackTracking的旅行推销员问题实施

📅  最后修改于: 2021-04-24 20:01:26             🧑  作者: Mango

旅行推销员问题(TSP):给定一组城市并确定每对城市之间的距离,问题在于找到一条最短的路线,该路线可以精确地访问每个城市一次并返回起点。

注意汉密尔顿周期和TSP之间的差异。汉密尔顿循环问题是要找出是否存在一次游览每个城市一次的旅行。在这里,我们知道存在汉密尔顿巡回赛(因为该图是完整的),并且实际上存在许多此类巡回赛,问题在于找到最小权重的汉密尔顿循环。
例如,考虑图中所示的图形。图中的TSP巡视为1-> 2-> 4-> 3->1。巡视的成本为10 + 25 + 30 + 15,即80。

该问题是著名的NP难题。没有多项式时间已知的解决方案来解决此问题。

TSP

方法:在这篇文章中,讨论了简单解决方案的实现。

  • 将城市1(假设第0个节点)作为起点和终点。由于路线是循环的,因此我们可以将任何点视为起点。
  • 开始以dfs方式从源遍历到其相邻节点。
  • 计算每次遍历的成本并跟踪最小成本,并不断更新最小成本储值的值。
  • 以最小的成本返回排列。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
#define V 4
  
// Function to find the minimum weight Hamiltonian Cycle
void tsp(int graph[][V], vector& v, int currPos,
         int n, int count, int cost, int& ans)
{
  
    // If last node is reached and it has a link
    // to the starting node i.e the source then
    // keep the minimum value out of the total cost
    // of traversal and "ans"
    // Finally return to check for more possible values
    if (count == n && graph[currPos][0]) {
        ans = min(ans, cost + graph[currPos][0]);
        return;
    }
  
    // BACKTRACKING STEP
    // Loop to traverse the adjacency list
    // of currPos node and increasing the count
    // by 1 and cost by graph[currPos][i] value
    for (int i = 0; i < n; i++) {
        if (!v[i] && graph[currPos][i]) {
  
            // Mark as visited
            v[i] = true;
            tsp(graph, v, i, n, count + 1,
                cost + graph[currPos][i], ans);
  
            // Mark ith node as unvisited
            v[i] = false;
        }
    }
};
  
// Driver code
int main()
{
    // n is the number of nodes i.e. V
    int n = 4;
  
    int graph[][V] = {
        { 0, 10, 15, 20 },
        { 10, 0, 35, 25 },
        { 15, 35, 0, 30 },
        { 20, 25, 30, 0 }
    };
  
    // Boolean array to check if a node
    // has been visited or not
    vector v(n);
    for (int i = 0; i < n; i++)
        v[i] = false;
  
    // Mark 0th node as visited
    v[0] = true;
    int ans = INT_MAX;
  
    // Find the minimum weight Hamiltonian Cycle
    tsp(graph, v, 0, n, 1, 0, ans);
  
    // ans is the minimum weight Hamiltonian Cycle
    cout << ans;
  
    return 0;
}


Java
// Java implementation of the approach
class GFG 
{
  
    // Function to find the minimum weight 
    // Hamiltonian Cycle
    static int tsp(int[][] graph, boolean[] v, 
                   int currPos, int n, 
                   int count, int cost, int ans) 
    {
  
        // If last node is reached and it has a link
        // to the starting node i.e the source then
        // keep the minimum value out of the total cost
        // of traversal and "ans"
        // Finally return to check for more possible values
        if (count == n && graph[currPos][0] > 0) 
        {
            ans = Math.min(ans, cost + graph[currPos][0]);
            return ans;
        }
  
        // BACKTRACKING STEP
        // Loop to traverse the adjacency list
        // of currPos node and increasing the count
        // by 1 and cost by graph[currPos,i] value
        for (int i = 0; i < n; i++) 
        {
            if (v[i] == false && graph[currPos][i] > 0) 
            {
  
                // Mark as visited
                v[i] = true;
                ans = tsp(graph, v, i, n, count + 1,
                          cost + graph[currPos][i], ans);
  
                // Mark ith node as unvisited
                v[i] = false;
            }
        }
        return ans;
    }
  
    // Driver code
    public static void main(String[] args)
    {
  
        // n is the number of nodes i.e. V
        int n = 4;
  
        int[][] graph = {{0, 10, 15, 20},
                         {10, 0, 35, 25},
                         {15, 35, 0, 30},
                         {20, 25, 30, 0}};
  
        // Boolean array to check if a node
        // has been visited or not
        boolean[] v = new boolean[n];
  
        // Mark 0th node as visited
        v[0] = true;
        int ans = Integer.MAX_VALUE;
  
        // Find the minimum weight Hamiltonian Cycle
        ans = tsp(graph, v, 0, n, 1, 0, ans);
  
        // ans is the minimum weight Hamiltonian Cycle
        System.out.println(ans);
    }
}
  
// This code is contributed by Rajput-Ji


Python3
# Python3 implementation of the approach
V = 4
answer = []
  
# Function to find the minimum weight 
# Hamiltonian Cycle
def tsp(graph, v, currPos, n, count, cost):
  
    # If last node is reached and it has 
    # a link to the starting node i.e 
    # the source then keep the minimum 
    # value out of the total cost of 
    # traversal and "ans"
    # Finally return to check for 
    # more possible values
    if (count == n and graph[currPos][0]):
        answer.append(cost + graph[currPos][0])
        return
  
    # BACKTRACKING STEP
    # Loop to traverse the adjacency list
    # of currPos node and increasing the count
    # by 1 and cost by graph[currPos][i] value
    for i in range(n):
        if (v[i] == False and graph[currPos][i]):
              
            # Mark as visited
            v[i] = True
            tsp(graph, v, i, n, count + 1, 
                cost + graph[currPos][i])
              
            # Mark ith node as unvisited
            v[i] = False
  
# Driver code
  
# n is the number of nodes i.e. V
if __name__ == '__main__':
    n = 4
    graph= [[ 0, 10, 15, 20 ],
            [ 10, 0, 35, 25 ],
            [ 15, 35, 0, 30 ],
            [ 20, 25, 30, 0 ]]
  
    # Boolean array to check if a node
    # has been visited or not
    v = [False for i in range(n)]
      
    # Mark 0th node as visited
    v[0] = True
  
    # Find the minimum weight Hamiltonian Cycle
    tsp(graph, v, 0, n, 1, 0)
  
    # ans is the minimum weight Hamiltonian Cycle
    print(min(answer))
  
# This code is contributed by mohit kumar


C#
// C# implementation of the approach
using System;
  
class GFG
{
  
// Function to find the minimum weight Hamiltonian Cycle
static int tsp(int [,]graph, bool []v, int currPos,
        int n, int count, int cost, int ans)
{
  
    // If last node is reached and it has a link
    // to the starting node i.e the source then
    // keep the minimum value out of the total cost
    // of traversal and "ans"
    // Finally return to check for more possible values
    if (count == n && graph[currPos,0] > 0) 
    {
        ans = Math.Min(ans, cost + graph[currPos,0]);
        return ans;
    }
  
    // BACKTRACKING STEP
    // Loop to traverse the adjacency list
    // of currPos node and increasing the count
    // by 1 and cost by graph[currPos,i] value
    for (int i = 0; i < n; i++) {
        if (v[i] == false && graph[currPos,i] > 0)
        {
  
            // Mark as visited
            v[i] = true;
            ans = tsp(graph, v, i, n, count + 1,
                cost + graph[currPos,i], ans);
  
            // Mark ith node as unvisited
            v[i] = false;
        }
    }
    return ans;
}
  
// Driver code
static void Main()
{
    // n is the number of nodes i.e. V
    int n = 4;
  
    int [,]graph = {
        { 0, 10, 15, 20 },
        { 10, 0, 35, 25 },
        { 15, 35, 0, 30 },
        { 20, 25, 30, 0 }
    };
  
    // Boolean array to check if a node
    // has been visited or not
    bool[] v = new bool[n];
  
    // Mark 0th node as visited
    v[0] = true;
    int ans = int.MaxValue;
  
    // Find the minimum weight Hamiltonian Cycle
    ans = tsp(graph, v, 0, n, 1, 0, ans);
  
    // ans is the minimum weight Hamiltonian Cycle
    Console.Write(ans);
  
}
}
  
// This code is contributed by mits


输出:
80