Skip to content

Commit f418dba

Browse files
committed
TSP: rename 'i' to 'node', inline fun tsp()
1 parent 25ba032 commit f418dba

File tree

1 file changed

+30
-27
lines changed

1 file changed

+30
-27
lines changed

src/main/kotlin/de/ronny_h/aoc/extensions/graphs/TravelingSalesman.kt

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,33 @@ class TravelingSalesman(private val adj: List<List<Int>>) {
2525
// Stores the final minimum weight of shortest tour.
2626
private var finalLength: Int = Int.MAX_VALUE
2727

28-
// Function to find the minimum edge cost having an end at the vertex i
29-
private fun firstMin(i: Int): Int {
28+
/**
29+
* Find the minimum edge cost having an end at the vertex [node]
30+
*/
31+
private fun firstMin(node: Int): Int {
3032
var min = MAX_WEIGHT
31-
for (k in 0..<N) {
32-
if (adj[i][k] < min && i != k) min = adj[i][k]
33+
for (otherNode in 0..<N) {
34+
if (adj[node][otherNode] < min && node != otherNode) {
35+
min = adj[node][otherNode]
36+
}
3337
}
3438
return min
3539
}
3640

37-
// function to find the second minimum edge cost having an end at the vertex i
38-
private fun secondMin(i: Int): Int {
41+
/**
42+
* Find the second minimum edge cost having an end at the vertex [node]
43+
*/
44+
private fun secondMin(node: Int): Int {
3945
var first = MAX_WEIGHT
4046
var second = MAX_WEIGHT
41-
for (j in 0..<N) {
42-
if (i == j) continue
47+
for (otherNode in 0..<N) {
48+
if (node == otherNode) continue
4349

44-
if (adj[i][j] <= first) {
50+
if (adj[node][otherNode] <= first) {
4551
second = first
46-
first = adj[i][j]
47-
} else if (adj[i][j] <= second && adj[i][j] != first) {
48-
second = adj[i][j]
52+
first = adj[node][otherNode]
53+
} else if (adj[node][otherNode] <= second && adj[node][otherNode] != first) {
54+
second = adj[node][otherNode]
4955
}
5056
}
5157
return second
@@ -81,31 +87,31 @@ class TravelingSalesman(private val adj: List<List<Int>>) {
8187
}
8288

8389
// for any other level iterate for all vertices to build the search space tree recursively
84-
for (i in 0..<N) {
90+
for (node in 0..<N) {
8591
// Consider next vertex if it is not same (diagonal
8692
// entry in adjacency matrix) and not visited already
87-
if (i != currentPath[level - 1] && !visited.contains(i)) {
88-
val temp = currentBound
89-
currentWeight += adj[currentPath[level - 1]][i]
93+
if (node != currentPath[level - 1] && !visited.contains(node)) {
94+
val tempBound = currentBound
95+
currentWeight += adj[currentPath[level - 1]][node]
9096

9197
// different computation of currentBound for level 2 from the other levels
9298
currentBound -= if (level == 1) {
93-
ceil((firstMin(currentPath[0]) + firstMin(i)) / 2.0).toInt()
99+
ceil((firstMin(currentPath[0]) + firstMin(node)) / 2.0).toInt()
94100
} else {
95-
ceil((secondMin(currentPath[level - 1]) + firstMin(i)) / 2.0).toInt()
101+
ceil((secondMin(currentPath[level - 1]) + firstMin(node)) / 2.0).toInt()
96102
}
97103

98104
// currentBound + currentWeight is the actual lower bound for the node that we have arrived on
99105
// If current lower bound < finalLength, we need to explore the node further
100106
if (currentBound + currentWeight < finalLength) {
101-
visited += i
102-
tspRecursive(currentBound, currentWeight, level + 1, currentPath + i)
107+
visited += node
108+
tspRecursive(currentBound, currentWeight, level + 1, currentPath + node)
103109
}
104110

105111
// Else we have to prune the node by resetting
106112
// all changes to currentWeight and currentBound
107-
currentWeight -= adj[currentPath[level - 1]][i]
108-
currentBound = temp
113+
currentWeight -= adj[currentPath[level - 1]][node]
114+
currentBound = tempBound
109115

110116
// Also reset the visited list
111117
visited = currentPath
@@ -114,18 +120,15 @@ class TravelingSalesman(private val adj: List<List<Int>>) {
114120
}
115121

116122
fun calculateShortestRoundTrip(): TravelingSalesmanProblemSolution {
117-
tsp()
118-
return TravelingSalesmanProblemSolution(finalLength, finalPath + finalPath[0])
119-
}
120-
121-
private fun tsp() {
122123
// Calculate initial lower bound for the root node using the formula
123124
// 1/2 * (sum of first min + second min) for all edges, rounded off to an integer
124125
val currentBound = ((0..<N).sumOf { firstMin(it) + secondMin(it) } / 2.0).toInt()
125126

126127
// We start at vertex 1 so the first vertex in currentPath is 0
127128
visited = listOf(0)
129+
128130
tspRecursive(currentBound, 0, 1, listOf(0))
131+
return TravelingSalesmanProblemSolution(finalLength, finalPath + finalPath[0])
129132
}
130133
}
131134

0 commit comments

Comments
 (0)