forked from kelvins/algorithms-and-data-structures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
travelling_salesman.go
152 lines (129 loc) · 4.33 KB
/
travelling_salesman.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* The Traveling Salesman Problem (TSP) is a problem that tries to determine the
* shortest route to visit a series of cities (visiting each one only once), returning to the starting city.
*
* Using a distance matrix to represent an undirected graph.
*
* Assuming we have the following graph:
*
* 6
* -------------------
* | 3 1 |
* (000)-----(001)-----(002)
* | \ / | \ / |
* | \ 6/ | \2 / |
* | \ / | \ / |
* 2| / 8| / |5
* | / \ | / \ |
* | / 3\ | /4 \ |
* | / \ | / \ |
* (003)-----(004)-----(005)
* | 6 4 |
* -------------------
* 1
*
* Distance Matrix
* 0 1 2 3 4 5
* 0 0 3 6 2 3 -
* 1 3 0 1 6 8 2
* 2 6 1 0 - 4 5
* 3 2 6 - 0 6 1
* 4 3 8 4 6 0 4
* 5 - 2 5 1 4 0
*
* Best solution:
* 0 - 3 - 5 - 1 - 2 - 4 - 0: 13
*/
package main
import "fmt"
const vertices = 6
const infinity = 99999999
var distanceMatrix [][]int
var tempSolution []int // Temporary solution
var bestSolution []int // Best solution
var visited []bool // Visited vertices
var bestSolutionValue int
var currentSolutionValue int
func TravelingSalesmanAux(x int) {
// If the current solution value is greater than the best solution value, it means it's no longer the best solution, so we can stop here
if currentSolutionValue > bestSolutionValue {
return
}
// If the temporary solution vector is complete
if x == vertices {
distance := distanceMatrix[tempSolution[x-1]][tempSolution[0]]
// If a better solution is found
if distance < infinity && (currentSolutionValue+distance) < bestSolutionValue {
// We have a better solution
bestSolutionValue = currentSolutionValue + distance
// Copy the entire vector to the best solution
for i := 0; i < vertices; i++ {
bestSolution[i] = tempSolution[i]
}
}
return
}
// Last vertex in the temporary solution
last := tempSolution[x-1]
// Iterate through all columns of the distance matrix in the row of the last vertex
for i := 0; i < vertices; i++ {
// If the position has not been visited and the value in the matrix is less than infinity
if !visited[i] && distanceMatrix[last][i] < infinity {
// Mark the position as visited
visited[i] = true
// Load the current vertex into the temporary solution
tempSolution[x] = i
// Increment the total distance traveled based on the position in the matrix
currentSolutionValue += distanceMatrix[last][i]
// Call recursively for the next vertex
TravelingSalesmanAux(x + 1)
// If it has not finished yet, decrement the value of the variable that stores the total distance
currentSolutionValue -= distanceMatrix[last][i]
// Set it as not visited so it can be accessed by another vertex
visited[i] = false
}
}
}
func TravelingSalesman(initialPosition int) {
// Check if the position is valid
if initialPosition < vertices {
visited[initialPosition] = true // Mark the first vertex as visited
tempSolution[0] = initialPosition // Put the initial position in the first position of the temporary solution
TravelingSalesmanAux(1) // Call the auxiliary method for the traveling salesman
} else {
fmt.Println("Invalid initial vertex")
}
}
// Initialize vectors and default values
func initialize() {
bestSolutionValue = infinity
currentSolutionValue = 0
for i := 0; i < vertices; i++ {
visited = append(visited, false)
tempSolution = append(tempSolution, -1)
bestSolution = append(bestSolution, -1)
}
// Create the distance matrix
row0 := []int{0, 3, 6, 2, 3, infinity}
row1 := []int{3, 0, 1, 6, 8, 2}
row2 := []int{6, 1, 0, infinity, 4, 5}
row3 := []int{2, 6, infinity, 0, 6, 1}
row4 := []int{3, 8, 4, 6, 0, 4}
row5 := []int{infinity, 2, 5, 1, 4, 0}
distanceMatrix = append(distanceMatrix, row0)
distanceMatrix = append(distanceMatrix, row1)
distanceMatrix = append(distanceMatrix, row2)
distanceMatrix = append(distanceMatrix, row3)
distanceMatrix = append(distanceMatrix, row4)
distanceMatrix = append(distanceMatrix, row5)
}
func main() {
initialize()
TravelingSalesman(0)
fmt.Println("Traveling Salesman")
fmt.Println("Minimum path:", bestSolutionValue)
for i := 0; i < vertices; i++ {
fmt.Print(bestSolution[i], ", ")
}
fmt.Println(bestSolution[0])
}