@@ -64,5 +64,90 @@ let items = [Item(name: "television", weight: 50, value: 500),
|
64 | 64 | Item(name: "painting", weight: 10, value: 1000)]
|
65 | 65 | knapsack(items: items, maxCapacity: 75)
|
66 | 66 |
|
| 67 | +/// Travelling Salesman |
| 68 | + |
| 69 | +let vtCities = ["Rutland", "Burlington", "White River Junction", "Bennington", "Brattleboro"] |
| 70 | + |
| 71 | +let vtDistances = [ |
| 72 | +"Rutland": |
| 73 | +["Burlington": 67, "White River Junction": 46, "Bennington": 55, "Brattleboro": 75], |
| 74 | +"Burlington": |
| 75 | +["Rutland": 67, "White River Junction": 91, "Bennington": 122, "Brattleboro": 153], |
| 76 | +"White River Junction": |
| 77 | +["Rutland": 46, "Burlington": 91, "Bennington": 98, "Brattleboro": 65], |
| 78 | +"Bennington": |
| 79 | +["Rutland": 55, "Burlington": 122, "White River Junction": 98, "Brattleboro": 40], |
| 80 | +"Brattleboro": |
| 81 | +["Rutland": 75, "Burlington": 153, "White River Junction": 65, "Bennington": 40] |
| 82 | +] |
| 83 | + |
| 84 | +// backtracking permutations algorithm |
| 85 | +func allPermutationsHelper<T>(contents: [T], permutations: inout [[T]], n: Int) { |
| 86 | +guard n > 0 else { permutations.append(contents); return } |
| 87 | +var tempContents = contents |
| 88 | +for i in 0..<n { |
| 89 | +tempContents.swapAt(i, n - 1) // move the element at i to the end |
| 90 | +// move everything else around, holding the end constant |
| 91 | +allPermutationsHelper(contents: tempContents, permutations: &permutations, n: n - 1) |
| 92 | +tempContents.swapAt(i, n - 1) // backtrack |
| 93 | +} |
| 94 | +} |
| 95 | + |
| 96 | +// find all of the permutations of a given array |
| 97 | +func allPermutations<T>(_ original: [T]) -> [[T]] { |
| 98 | +var permutations = [[T]]() |
| 99 | +allPermutationsHelper(contents: original, permutations: &permutations, n: original.count) |
| 100 | +return permutations |
| 101 | +} |
| 102 | + |
| 103 | +// test allPermutations |
| 104 | +let abc = ["a","b","c"] |
| 105 | +let testPerms = allPermutations(abc) |
| 106 | +print(testPerms) |
| 107 | +print(testPerms.count) |
| 108 | + |
| 109 | +// make complete paths for tsp |
| 110 | +func tspPaths<T>(_ permutations: [[T]]) -> [[T]] { |
| 111 | +return permutations.map { |
| 112 | +if let first = $0.first { |
| 113 | +return ($0 + [first]) // append first to end |
| 114 | +} else { |
| 115 | +return [] // empty is just itself |
| 116 | +} |
| 117 | +} |
| 118 | +} |
| 119 | + |
| 120 | +print(tspPaths(testPerms)) |
| 121 | + |
| 122 | +func solveTSP<T>(cities: [T], distances: [T: [T: Int]]) -> (solution: [T], distance: Int) { |
| 123 | +let possiblePaths = tspPaths(allPermutations(cities)) |
| 124 | +var bestPath: [T] = [] |
| 125 | +var minDistance: Int = Int.max |
| 126 | +for path in possiblePaths { |
| 127 | +if path.count < 2 { continue } |
| 128 | +var distance = 0 |
| 129 | +var last = path.first! // we know there is one becuase of above line |
| 130 | +for next in path[1..<path.count] { |
| 131 | +distance += distances[last]![next]! |
| 132 | +last = next |
| 133 | +} |
| 134 | +if distance < minDistance { |
| 135 | +minDistance = distance |
| 136 | +bestPath = path |
| 137 | +} |
| 138 | +} |
| 139 | +return (solution: bestPath, distance: minDistance) |
| 140 | +} |
| 141 | + |
| 142 | +let vtTSP = solveTSP(cities: vtCities, distances: vtDistances) |
| 143 | +print("The shortest path is \(vtTSP.solution) in \(vtTSP.distance) miles.") |
| 144 | + |
| 145 | +//func dog(test: inout [String]) { |
| 146 | +// test.append("hello") |
| 147 | +// |
| 148 | +//} |
| 149 | + |
| 150 | +// City 0 |
| 151 | + |
67 | 152 | //: [Next](@next)
|
68 | 153 |
|
0 commit comments