📜  使用 BackTracking 实现旅行商问题

📅  最后修改于: 2021-10-25 03:31:29             🧑  作者: Mango

旅行商问题 (TSP):给定一组城市和每对城市之间的距离,问题是找到最短的路线,该路线恰好访问每个城市一次并返回起点。
注意哈密顿循环和 TSP 之间的区别。 Hamiltoninan 循环问题是寻找是否存在一次访问每个城市恰好一次的旅行。这里我们知道哈密顿环存在(因为图是完整的)并且实际上存在许多这样的环,问题是找到一个最小权重的哈密顿环。
例如,考虑图中所示的图形。图中的 TSP 游览是 1 -> 2 -> 4 -> 3 -> 1。游览的成本是 10 + 25 + 30 + 15,即 80。
该问题是著名的 NP 难题。这个问题没有多项式时间已知解。

运输供应商

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

  • 考虑城市 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


Javascript


输出:
80

时间复杂度: O(N!),对于第一个节点有 N 种可能性,对于第二个节点有 n-1 种可能性。
对于 N 个节点,时间复杂度 = N * (N – 1) * 。 . . 1 = O(N!)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程