TSP traveling salesman problem

What is TSP? Generally speaking, this problem can be described as a commodity salesman going to several cities to sell commodities. The salesman starts from one city and needs to go through all cities before returning to the starting place. How to select the travel route to minimize the total travel. So it is to start from a point in a diagram and find a loop to return to this point, and the total cost is the smallest. So what do we do? We use dynamic programming to write this article.

First, please take a look at the description of dynamic programming process on bilibili, which is the basis of our algorithm:

 

 

  I think these two pictures are easy to understand. The cost of starting from city 0, passing through cities 1, 2 and 3, and finally returning to city 0 is the minimum of three small costs. What are these three small costs? Is the distance from city 0 to city 1, plus the distance from city 1, through city 2 and 3, and finally back to city 0,... And so on. The recursive formula has been written above. Therefore, this recursion is the core of our recursion. We need to constantly update d the set of cities (to put it bluntly, we need to constantly remove the cities from it, one at a time). In this way, in the end of recursion, the set of cities is empty. What shall we do at this time? Don't worry, it's also written in the above formula. Recursion to the end, I just need to calculate the distance from the city outside the set (defined as d(city, collection), where the city outside the set refers to D's city) to city 0, that is, directly return this distance. In this way, our idea of writing code comes out. Then do some initialization before.

Paste the following code:

In the first step, we define several variables:

1 public int[][] dis;
2 public ArrayList<Integer> cities;
3 public int source;

The two-dimensional array DIS in the first row stores the distance. For example, dis[i][j] represents the distance from city I to city j;

The second line is the collection, which stores the city. Since cities are numbered by numbers, we use an ArrayList set of Integer type;

The third line is the source point, i.e. City 0

Then we initialize the constructor:

1 public Traveling(int n) {
2         cities = new ArrayList<>();
3         for (int i = 0; i < n; ++i) {
4             cities.add(i);
5         }
6         source = 0;
7 }

Add all cities in the cities collection, where the city number starts from 0.

Then we write an init method to initialize the dis array. What is the standard? Of course, the distance from the city itself to itself is 0. In addition, all are set to positive infinity.

1 public void init() {
2         int n = dis.length;
3         for (int i = 0; i < n; ++i) {
4             for (int j = 0; j < n; ++j) {
5                 dis[i][j] = ((i == j) ? 0 : Integer.MAX_VALUE);
6             }
7         }
8 }

Then, in order to realize several different cases of city sets in the recursive code, we write a method of assigning sets (otherwise, it will explode, because java does not allow modifying the elements in the set while iterating over the set):

1 private ArrayList<Integer> copy(ArrayList<Integer> a) {
2         ArrayList<Integer> list = new ArrayList<>();
3         for (Integer i : a) {
4             list.add(i);
5         }
6         return list;
7 }

Finally, we write a distance function, which is actually the process of tsp dynamic planning:

 1 private int distance(int start, ArrayList<Integer> list) {
 2         if (list.size() == 0) {
 3             return dis[start][source];
 4         } 
 5         int temp = Integer.MAX_VALUE;
 6         for (Integer i : list) {
 7             ArrayList<Integer> copied = copy(list);
 8             copied.remove(i);
 9             int res = distance(i, copied) + dis[start][i];
10             temp = temp < res ? temp : res;
11         }
12         return temp;
13 }

First, we need to define the exit condition of the recursive function, that is, when the city set is empty, we should directly return the distance.

Secondly, traverse all the cities in the city set, pick them out respectively, and calculate which one costs the least. We'll just choose that. Finally, we'll return the minimum price.

Finally, we provide a method for the outside world:

1 public int tsp() {
2         return distance(source, cities);
3 }

A complete code:

 1 package com.hw.others;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Scanner;
 5 
 6 public class Traveling {
 7     public int[][] dis;
 8     public ArrayList<Integer> cities;
 9     public int source;
10 
11     public Traveling(int n) {
12         cities = new ArrayList<>();
13         for (int i = 0; i < n; ++i) {
14             cities.add(i);
15         }
16         source = 0;
17     }
18 
19     public void init() {
20         int n = dis.length;
21         for (int i = 0; i < n; ++i) {
22             for (int j = 0; j < n; ++j) {
23                 dis[i][j] = ((i == j) ? 0 : Integer.MAX_VALUE);
24             }
25         }
26     }
27 
28     private ArrayList<Integer> copy(ArrayList<Integer> a) {
29         ArrayList<Integer> list = new ArrayList<>();
30         for (Integer i : a) {
31             list.add(i);
32         }
33         return list;
34     }
35 
36     private int distance(int start, ArrayList<Integer> list) {
37         if (list.size() == 0) {
38             return dis[start][source];
39         } 
40         int temp = Integer.MAX_VALUE;
41         for (Integer i : list) {
42             ArrayList<Integer> copied = copy(list);
43             copied.remove(i);
44             int res = distance(i, copied) + dis[start][i];
45             temp = temp < res ? temp : res;
46         }
47         return temp;
48     }
49 
50     public int tsp() {
51         return distance(source, cities);
52     }
53 
54     public static void main(String[] args) {
55         Scanner s = new Scanner(System.in);
56         System.out.println("Enter the number of cities:");
57         int n = s.nextInt();
58         Traveling traveler = new Traveling(n);
59         traveler.dis = new int[n+1][n+1];
60         traveler.init();
61         System.out.println("Enter the number of edges:");
62         int edge = s.nextInt();
63         System.out.println("Now enter the distance between cities(City number starts from 0):");
64         for (int i = 0; i < edge; ++i) {
65             int start = s.nextInt();
66             int end = s.nextInt();
67             int weight = s.nextInt();
68             traveler.dis[start][end] = weight;
69             traveler.dis[end][start] = weight;
70         }
71         int length = traveler.tsp();
72         System.out.println("The shortest path cost is:" + length);
73         s.close();
74     }
75 }

 

Posted by ms.buggy on Mon, 08 Nov 2021 08:42:04 -0800