com2014-template/Workshop - 5 (PSO, ACO).ipynb

64 KiB

None <html> <head> </head>

Make sure you run this at the begining

In [2]:
import os
import sys
import math
import numpy as np
import matplotlib.pyplot as plt

# Append template path to sys path
sys.path.append(os.getcwd() + "/template")
In [3]:
from utils.load_data import load_data
from utils.load_data import log
from utils.visualize_tsp import plotTSP
from utils.tsp import TSP

Workshop Starts Here

TSP
solutions

Get familiar with your dataset

There are problems at different levels. 3 simple, 2 medium, 1 hard.

In [ ]:
for root, _, files in os.walk('./template/data'):
    if(files):
        for f in files:
            print(str(root) + "/" + f)
In [ ]:
ulysses16 = np.array(load_data("./template/data/simple/ulysses16.tsp"))
In [ ]:
ulysses16[:]
In [ ]:
plt.scatter(ulysses16[:, 0], ulysses16[:, 1])
for i in range(0, 16):
    plt.annotate(i, (ulysses16[i, 0], ulysses16[i, 1]+0.5))

Naive Solution: In Order

In [ ]:
simple_sequence = list(range(0, 16))
print(simple_sequence)
In [ ]:
plotTSP([simple_sequence], ulysses16, num_iters=1)

Naive Solution: Random Permutation

In [ ]:
random_permutation = np.random.permutation(16).tolist()
print(random_permutation)
In [ ]:
plotTSP([random_permutation], ulysses16, num_iters=1)

Best Solution

In [ ]:
best_ulysses16 = [0, 13, 12, 11, 6, 5, 14, 4, 10, 8, 9, 15, 2, 1, 3, 7]
plotTSP([best_ulysses16], ulysses16, num_iters=1)

Calculate Fitness (Sum of all Distances)

In [6]:
def dist(node_0, node_1, coords):
        """
        Euclidean distance between two nodes.
        """
        coord_0, coord_1 = coords[node_0], coords[node_1]
        return math.sqrt((coord_0[0] - coord_1[0]) ** 2 + (coord_0[1] - coord_1[1]) ** 2)
In [ ]:
print("Coordinate of City 0:", ulysses16[0])
In [ ]:
print("Coordinate of City 1:", ulysses16[1])
In [ ]:
print("Distance Between", dist(0, 1, ulysses16))
In [7]:
def fitness(solution, coords):
    N = len(coords)
    cur_fit = 0
    for i in range(len(solution)):
        cur_fit += dist(solution[i % N], solution[(i + 1) % N], coords)
    return cur_fit
In [ ]:
print ("Order Fitness:\t", fitness(simple_sequence, ulysses16))
print ("Random Fitness:\t", fitness(random_permutation, ulysses16))
print ("Best Fitness:\t", fitness(best_ulysses16, ulysses16))

Naive Random Model

In [ ]:
import math
import random
from model.base_model import Model

class MyModel(Model):
    def __init__(self):
        super().__init__()

    def init(self, coords):
        """
        Put your initialization here.
        """
        super().init(coords)
        self.log("Nothing to initialize in your model now")

    def fit(self, max_it=1000, visualize=False):
        """
        Put your iteration process here.
        """
        self.log("Naive Random Solution")
        self.best_solution = np.random.permutation(self.N).tolist()
        self.fitness_list.append(self.fitness(self.best_solution))

        return self.best_solution, self.fitness_list
In [ ]:
tsp_problem = './template/data/simple/ulysses16.tsp'
tsp_coords = np.array(load_data(tsp_problem))

import timeit
start = timeit.default_timer()

# Your Model Running

model = MyModel()
best_solution, fitness_list = TSP(tsp_problem, model)

# Your Model End

stop = timeit.default_timer()
print()
print('[*] Running for: {time:.1f} seconds'.format(time=(stop - start)))

print()
print ("Best Fitness:\t", fitness(best_solution, tsp_coords))
print ("Best Solution:\t", best_solution)

Minimum Spanning Tree (Depth First)

In [85]:
import math
import random
from model.base_model import Model

class MyModel(Model):
    def __init__(self):
        super().__init__()

    def init(self, coords):
        """
        Put your initialization here.
        """
        super().init(coords)
        self.log("Nothing to initialize in your model now")

    def fit(self, max_it=1000, visualize=False):
        """
        Put your iteration process here.
        """
        self.log("Uniform Cost Search Solution")

        UCS_solutions = []
        UCS_losses = []
        # Depth First: Set one city as starting point, iterate to the end, then select next city as starting point.
        for i in range(0, self.N):
            solution = []
            solution.append(i)
            unvisited_list = list(range(0, self.N))
            cur_city = i
            print("[starting]", i)
            for steps in range(self.N - 1):
                # print(unvisited_list)
                unvisited_list.remove(cur_city)
                closest_neighbour = -1
                shortest_distance = math.inf
                for j in unvisited_list:
                    if(self.dist(cur_city, j) < shortest_distance):
                        closest_neighbour = j
                        shortest_distance = self.dist(cur_city, j)
                solution.append(closest_neighbour)
                cur_city = closest_neighbour
            UCS_solutions.append(solution)
            UCS_losses.append(self.fitness(solution))

        self.best_solution = UCS_solutions[ UCS_losses.index(min(UCS_losses)) ]
        self.fitness_list.append(self.fitness(self.best_solution))

        return self.best_solution, self.fitness_list
In [86]:
tsp_problem = './template/data/medium/pcb442.tsp'
tsp_coords = np.array(load_data(tsp_problem))

import timeit
start = timeit.default_timer()

# Your Model Running

model = MyModel()
best_solution, fitness_list = TSP(tsp_problem, model)

# Your Model End

stop = timeit.default_timer()
print()
print('[*] Running for: {time:.1f} seconds'.format(time=(stop - start)))

print()
print ("Best Fitness:\t", fitness(best_solution, tsp_coords))
print ("Best Solution:\t", best_solution)
[MyModel] Nothing to initialize in your model now
[MyModel] Uniform Cost Search Solution
[starting] 0
[starting] 1
[starting] 2
[starting] 3
[starting] 4
[starting] 5
[starting] 6
[starting] 7
[starting] 8
[starting] 9
[starting] 10
[starting] 11
[starting] 12
[starting] 13
[starting] 14
[starting] 15
[starting] 16
[starting] 17
[starting] 18
[starting] 19
[starting] 20
[starting] 21
[starting] 22
[starting] 23
[starting] 24
[starting] 25
[starting] 26
[starting] 27
[starting] 28
[starting] 29
[starting] 30
[starting] 31
[starting] 32
[starting] 33
[starting] 34
[starting] 35
[starting] 36
[starting] 37
[starting] 38
[starting] 39
[starting] 40
[starting] 41
[starting] 42
[starting] 43
[starting] 44
[starting] 45
[starting] 46
[starting] 47
[starting] 48
[starting] 49
[starting] 50
[starting] 51
[starting] 52
[starting] 53
[starting] 54
[starting] 55
[starting] 56
[starting] 57
[starting] 58
[starting] 59
[starting] 60
[starting] 61
[starting] 62
[starting] 63
[starting] 64
[starting] 65
[starting] 66
[starting] 67
[starting] 68
[starting] 69
[starting] 70
[starting] 71
[starting] 72
[starting] 73
[starting] 74
[starting] 75
[starting] 76
[starting] 77
[starting] 78
[starting] 79
[starting] 80
[starting] 81
[starting] 82
[starting] 83
[starting] 84
[starting] 85
[starting] 86
[starting] 87
[starting] 88
[starting] 89
[starting] 90
[starting] 91
[starting] 92
[starting] 93
[starting] 94
[starting] 95
[starting] 96
[starting] 97
[starting] 98
[starting] 99
[starting] 100
[starting] 101
[starting] 102
[starting] 103
[starting] 104
[starting] 105
[starting] 106
[starting] 107
[starting] 108
[starting] 109
[starting] 110
[starting] 111
[starting] 112
[starting] 113
[starting] 114
[starting] 115
[starting] 116
[starting] 117
[starting] 118
[starting] 119
[starting] 120
[starting] 121
[starting] 122
[starting] 123
[starting] 124
[starting] 125
[starting] 126
[starting] 127
[starting] 128
[starting] 129
[starting] 130
[starting] 131
[starting] 132
[starting] 133
[starting] 134
[starting] 135
[starting] 136
[starting] 137
[starting] 138
[starting] 139
[starting] 140
[starting] 141
[starting] 142
[starting] 143
[starting] 144
[starting] 145
[starting] 146
[starting] 147
[starting] 148
[starting] 149
[starting] 150
[starting] 151
[starting] 152
[starting] 153
[starting] 154
[starting] 155
[starting] 156
[starting] 157
[starting] 158
[starting] 159
[starting] 160
[starting] 161
[starting] 162
[starting] 163
[starting] 164
[starting] 165
[starting] 166
[starting] 167
[starting] 168
[starting] 169
[starting] 170
[starting] 171
[starting] 172
[starting] 173
[starting] 174
[starting] 175
[starting] 176
[starting] 177
[starting] 178
[starting] 179
[starting] 180
[starting] 181
[starting] 182
[starting] 183
[starting] 184
[starting] 185
[starting] 186
[starting] 187
[starting] 188
[starting] 189
[starting] 190
[starting] 191
[starting] 192
[starting] 193
[starting] 194
[starting] 195
[starting] 196
[starting] 197
[starting] 198
[starting] 199
[starting] 200
[starting] 201
[starting] 202
[starting] 203
[starting] 204
[starting] 205
[starting] 206
[starting] 207
[starting] 208
[starting] 209
[starting] 210
[starting] 211
[starting] 212
[starting] 213
[starting] 214
[starting] 215
[starting] 216
[starting] 217
[starting] 218
[starting] 219
[starting] 220
[starting] 221
[starting] 222
[starting] 223
[starting] 224
[starting] 225
[starting] 226
[starting] 227
[starting] 228
[starting] 229
[starting] 230
[starting] 231
[starting] 232
[starting] 233
[starting] 234
[starting] 235
[starting] 236
[starting] 237
[starting] 238
[starting] 239
[starting] 240
[starting] 241
[starting] 242
[starting] 243
[starting] 244
[starting] 245
[starting] 246
[starting] 247
[starting] 248
[starting] 249
[starting] 250
[starting] 251
[starting] 252
[starting] 253
[starting] 254
[starting] 255
[starting] 256
[starting] 257
[starting] 258
[starting] 259
[starting] 260
[starting] 261
[starting] 262
[starting] 263
[starting] 264
[starting] 265
[starting] 266
[starting] 267
[starting] 268
[starting] 269
[starting] 270
[starting] 271
[starting] 272
[starting] 273
[starting] 274
[starting] 275
[starting] 276
[starting] 277
[starting] 278
[starting] 279
[starting] 280
[starting] 281
[starting] 282
[starting] 283
[starting] 284
[starting] 285
[starting] 286
[starting] 287
[starting] 288
[starting] 289
[starting] 290
[starting] 291
[starting] 292
[starting] 293
[starting] 294
[starting] 295
[starting] 296
[starting] 297
[starting] 298
[starting] 299
[starting] 300
[starting] 301
[starting] 302
[starting] 303
[starting] 304
[starting] 305
[starting] 306
[starting] 307
[starting] 308
[starting] 309
[starting] 310
[starting] 311
[starting] 312
[starting] 313
[starting] 314
[starting] 315
[starting] 316
[starting] 317
[starting] 318
[starting] 319
[starting] 320
[starting] 321
[starting] 322
[starting] 323
[starting] 324
[starting] 325
[starting] 326
[starting] 327
[starting] 328
[starting] 329
[starting] 330
[starting] 331
[starting] 332
[starting] 333
[starting] 334
[starting] 335
[starting] 336
[starting] 337
[starting] 338
[starting] 339
[starting] 340
[starting] 341
[starting] 342
[starting] 343
[starting] 344
[starting] 345
[starting] 346
[starting] 347
[starting] 348
[starting] 349
[starting] 350
[starting] 351
[starting] 352
[starting] 353
[starting] 354
[starting] 355
[starting] 356
[starting] 357
[starting] 358
[starting] 359
[starting] 360
[starting] 361
[starting] 362
[starting] 363
[starting] 364
[starting] 365
[starting] 366
[starting] 367
[starting] 368
[starting] 369
[starting] 370
[starting] 371
[starting] 372
[starting] 373
[starting] 374
[starting] 375
[starting] 376
[starting] 377
[starting] 378
[starting] 379
[starting] 380
[starting] 381
[starting] 382
[starting] 383
[starting] 384
[starting] 385
[starting] 386
[starting] 387
[starting] 388
[starting] 389
[starting] 390
[starting] 391
[starting] 392
[starting] 393
[starting] 394
[starting] 395
[starting] 396
[starting] 397
[starting] 398
[starting] 399
[starting] 400
[starting] 401
[starting] 402
[starting] 403
[starting] 404
[starting] 405
[starting] 406
[starting] 407
[starting] 408
[starting] 409
[starting] 410
[starting] 411
[starting] 412
[starting] 413
[starting] 414
[starting] 415
[starting] 416
[starting] 417
[starting] 418
[starting] 419
[starting] 420
[starting] 421
[starting] 422
[starting] 423
[starting] 424
[starting] 425
[starting] 426
[starting] 427
[starting] 428
[starting] 429
[starting] 430
[starting] 431
[starting] 432
[starting] 433
[starting] 434
[starting] 435
[starting] 436
[starting] 437
[starting] 438
[starting] 439
[starting] 440
[starting] 441
[*] Best: 58952.967129705365
[*] Writing the best solution to file

[*] Running for: 18.7 seconds

Best Fitness:	 58952.967129705365
Best Solution:	 [395, 173, 172, 161, 149, 136, 126, 385, 114, 103, 440, 101, 102, 113, 125, 135, 148, 160, 171, 184, 399, 404, 226, 233, 237, 238, 265, 268, 272, 275, 278, 280, 281, 427, 341, 340, 345, 346, 347, 432, 348, 349, 350, 351, 342, 352, 353, 354, 433, 355, 356, 357, 434, 358, 359, 360, 343, 361, 362, 363, 364, 365, 366, 344, 367, 368, 369, 370, 371, 372, 373, 374, 337, 336, 426, 335, 334, 333, 306, 332, 331, 330, 305, 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 279, 425, 439, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 428, 324, 325, 326, 327, 328, 329, 430, 429, 277, 416, 417, 252, 251, 250, 249, 414, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 234, 227, 405, 400, 185, 398, 186, 174, 391, 137, 115, 388, 386, 150, 151, 392, 152, 138, 127, 116, 104, 105, 106, 117, 128, 140, 153, 164, 163, 176, 188, 200, 401, 201, 189, 190, 397, 177, 165, 154, 141, 129, 118, 107, 438, 82, 50, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 441, 98, 99, 83, 51, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 375, 376, 32, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 84, 85, 86, 377, 87, 88, 89, 90, 91, 92, 93, 94, 378, 95, 379, 96, 97, 382, 383, 112, 124, 134, 147, 159, 170, 183, 198, 209, 219, 225, 410, 409, 413, 236, 264, 419, 267, 415, 263, 262, 235, 261, 260, 259, 258, 257, 256, 255, 254, 253, 231, 223, 214, 202, 178, 394, 393, 166, 155, 142, 130, 119, 108, 384, 120, 121, 109, 131, 144, 143, 390, 156, 167, 180, 193, 204, 205, 206, 194, 195, 196, 181, 168, 157, 145, 132, 122, 110, 100, 435, 111, 123, 133, 146, 158, 169, 182, 197, 208, 218, 217, 207, 216, 403, 408, 407, 411, 412, 418, 421, 437, 422, 271, 274, 436, 431, 232, 224, 215, 203, 191, 179, 192, 389, 387, 380, 381, 139, 162, 175, 187, 199, 212, 221, 229, 228, 220, 210, 402, 211, 396, 213, 222, 230, 424, 420, 423, 339, 338, 276, 273, 270, 266, 269, 406]

Minimum Spanning Tree (Breadth First)

In [87]:
import math
import random
from model.base_model import Model

class MyModel(Model):
    def __init__(self):
        super().__init__()

    def init(self, coords):
        """
        Put your initialization here.
        """
        super().init(coords)
        self.log("Nothing to initialize in your model now")

    def fit(self, max_it=1000, visualize=False):
        """
        Put your iteration process here.
        """
        self.log("Uniform Cost Search Solution")

        UCS_solutions = []
        UCS_losses = []
    
        for i in range(0, self.N):
            solution = [i]
            UCS_solutions.append(solution)
    
        # Breadth First: Set each city as starting point, then go to next city simultaneously
        for step in range(0, self.N - 1):
            print("[step]", step)
            UCS_solutions[i]
            solution = []
            solution.append(i)
            unvisited_list = list(range(0, self.N))
            cur_city = i
            # For each search path
            for i in range(0, self.N):
                cur_city = UCS_solutions[i][step]
                unvisited_list = list( set(range(0, self.N)) - set(UCS_solutions[i]) )
                # print(unvisited_list)
                closest_neighbour = -1
                shortest_distance = math.inf
                for j in unvisited_list:
                    if(self.dist(cur_city, j) < shortest_distance):
                        closest_neighbour = j
                        shortest_distance = self.dist(cur_city, j)
                UCS_solutions[i].append(closest_neighbour)

        for i in range(0, self.N):
            UCS_losses.append(self.fitness(UCS_solutions[i]))
 
        self.best_solution = UCS_solutions[ UCS_losses.index(min(UCS_losses)) ]
        self.fitness_list.append(self.fitness(self.best_solution))

        return self.best_solution, self.fitness_list
In [89]:
tsp_problem = './template/data/medium/pcb442.tsp'
tsp_coords = np.array(load_data(tsp_problem))

import timeit
start = timeit.default_timer()

# Your Model Running

model = MyModel()
best_solution, fitness_list = TSP(tsp_problem, model)

# Your Model End

stop = timeit.default_timer()
print()
print('[*] Running for: {time:.1f} seconds'.format(time=(stop - start)))

print()
print ("Best Fitness:\t", fitness(best_solution, tsp_coords))
print ("Best Solution:\t", best_solution)
[MyModel] Nothing to initialize in your model now
[MyModel] Uniform Cost Search Solution
[step] 0
[step] 1
[step] 2
[step] 3
[step] 4
[step] 5
[step] 6
[step] 7
[step] 8
[step] 9
[step] 10
[step] 11
[step] 12
[step] 13
[step] 14
[step] 15
[step] 16
[step] 17
[step] 18
[step] 19
[step] 20
[step] 21
[step] 22
[step] 23
[step] 24
[step] 25
[step] 26
[step] 27
[step] 28
[step] 29
[step] 30
[step] 31
[step] 32
[step] 33
[step] 34
[step] 35
[step] 36
[step] 37
[step] 38
[step] 39
[step] 40
[step] 41
[step] 42
[step] 43
[step] 44
[step] 45
[step] 46
[step] 47
[step] 48
[step] 49
[step] 50
[step] 51
[step] 52
[step] 53
[step] 54
[step] 55
[step] 56
[step] 57
[step] 58
[step] 59
[step] 60
[step] 61
[step] 62
[step] 63
[step] 64
[step] 65
[step] 66
[step] 67
[step] 68
[step] 69
[step] 70
[step] 71
[step] 72
[step] 73
[step] 74
[step] 75
[step] 76
[step] 77
[step] 78
[step] 79
[step] 80
[step] 81
[step] 82
[step] 83
[step] 84
[step] 85
[step] 86
[step] 87
[step] 88
[step] 89
[step] 90
[step] 91
[step] 92
[step] 93
[step] 94
[step] 95
[step] 96
[step] 97
[step] 98
[step] 99
[step] 100
[step] 101
[step] 102
[step] 103
[step] 104
[step] 105
[step] 106
[step] 107
[step] 108
[step] 109
[step] 110
[step] 111
[step] 112
[step] 113
[step] 114
[step] 115
[step] 116
[step] 117
[step] 118
[step] 119
[step] 120
[step] 121
[step] 122
[step] 123
[step] 124
[step] 125
[step] 126
[step] 127
[step] 128
[step] 129
[step] 130
[step] 131
[step] 132
[step] 133
[step] 134
[step] 135
[step] 136
[step] 137
[step] 138
[step] 139
[step] 140
[step] 141
[step] 142
[step] 143
[step] 144
[step] 145
[step] 146
[step] 147
[step] 148
[step] 149
[step] 150
[step] 151
[step] 152
[step] 153
[step] 154
[step] 155
[step] 156
[step] 157
[step] 158
[step] 159
[step] 160
[step] 161
[step] 162
[step] 163
[step] 164
[step] 165
[step] 166
[step] 167
[step] 168
[step] 169
[step] 170
[step] 171
[step] 172
[step] 173
[step] 174
[step] 175
[step] 176
[step] 177
[step] 178
[step] 179
[step] 180
[step] 181
[step] 182
[step] 183
[step] 184
[step] 185
[step] 186
[step] 187
[step] 188
[step] 189
[step] 190
[step] 191
[step] 192
[step] 193
[step] 194
[step] 195
[step] 196
[step] 197
[step] 198
[step] 199
[step] 200
[step] 201
[step] 202
[step] 203
[step] 204
[step] 205
[step] 206
[step] 207
[step] 208
[step] 209
[step] 210
[step] 211
[step] 212
[step] 213
[step] 214
[step] 215
[step] 216
[step] 217
[step] 218
[step] 219
[step] 220
[step] 221
[step] 222
[step] 223
[step] 224
[step] 225
[step] 226
[step] 227
[step] 228
[step] 229
[step] 230
[step] 231
[step] 232
[step] 233
[step] 234
[step] 235
[step] 236
[step] 237
[step] 238
[step] 239
[step] 240
[step] 241
[step] 242
[step] 243
[step] 244
[step] 245
[step] 246
[step] 247
[step] 248
[step] 249
[step] 250
[step] 251
[step] 252
[step] 253
[step] 254
[step] 255
[step] 256
[step] 257
[step] 258
[step] 259
[step] 260
[step] 261
[step] 262
[step] 263
[step] 264
[step] 265
[step] 266
[step] 267
[step] 268
[step] 269
[step] 270
[step] 271
[step] 272
[step] 273
[step] 274
[step] 275
[step] 276
[step] 277
[step] 278
[step] 279
[step] 280
[step] 281
[step] 282
[step] 283
[step] 284
[step] 285
[step] 286
[step] 287
[step] 288
[step] 289
[step] 290
[step] 291
[step] 292
[step] 293
[step] 294
[step] 295
[step] 296
[step] 297
[step] 298
[step] 299
[step] 300
[step] 301
[step] 302
[step] 303
[step] 304
[step] 305
[step] 306
[step] 307
[step] 308
[step] 309
[step] 310
[step] 311
[step] 312
[step] 313
[step] 314
[step] 315
[step] 316
[step] 317
[step] 318
[step] 319
[step] 320
[step] 321
[step] 322
[step] 323
[step] 324
[step] 325
[step] 326
[step] 327
[step] 328
[step] 329
[step] 330
[step] 331
[step] 332
[step] 333
[step] 334
[step] 335
[step] 336
[step] 337
[step] 338
[step] 339
[step] 340
[step] 341
[step] 342
[step] 343
[step] 344
[step] 345
[step] 346
[step] 347
[step] 348
[step] 349
[step] 350
[step] 351
[step] 352
[step] 353
[step] 354
[step] 355
[step] 356
[step] 357
[step] 358
[step] 359
[step] 360
[step] 361
[step] 362
[step] 363
[step] 364
[step] 365
[step] 366
[step] 367
[step] 368
[step] 369
[step] 370
[step] 371
[step] 372
[step] 373
[step] 374
[step] 375
[step] 376
[step] 377
[step] 378
[step] 379
[step] 380
[step] 381
[step] 382
[step] 383
[step] 384
[step] 385
[step] 386
[step] 387
[step] 388
[step] 389
[step] 390
[step] 391
[step] 392
[step] 393
[step] 394
[step] 395
[step] 396
[step] 397
[step] 398
[step] 399
[step] 400
[step] 401
[step] 402
[step] 403
[step] 404
[step] 405
[step] 406
[step] 407
[step] 408
[step] 409
[step] 410
[step] 411
[step] 412
[step] 413
[step] 414
[step] 415
[step] 416
[step] 417
[step] 418
[step] 419
[step] 420
[step] 421
[step] 422
[step] 423
[step] 424
[step] 425
[step] 426
[step] 427
[step] 428
[step] 429
[step] 430
[step] 431
[step] 432
[step] 433
[step] 434
[step] 435
[step] 436
[step] 437
[step] 438
[step] 439
[step] 440
[*] Best: 58952.967129705365
[*] Writing the best solution to file

[*] Running for: 21.8 seconds

Best Fitness:	 58952.967129705365
Best Solution:	 [395, 173, 172, 161, 149, 136, 126, 385, 114, 103, 440, 101, 102, 113, 125, 135, 148, 160, 171, 184, 399, 404, 226, 233, 237, 238, 265, 268, 272, 275, 278, 280, 281, 427, 341, 340, 345, 346, 347, 432, 348, 349, 350, 351, 342, 352, 353, 354, 433, 355, 356, 357, 434, 358, 359, 360, 343, 361, 362, 363, 364, 365, 366, 344, 367, 368, 369, 370, 371, 372, 373, 374, 337, 336, 426, 335, 334, 333, 306, 332, 331, 330, 305, 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 279, 425, 439, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 428, 324, 325, 326, 327, 328, 329, 430, 429, 277, 416, 417, 252, 251, 250, 249, 414, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 234, 227, 405, 400, 185, 398, 186, 174, 391, 137, 115, 388, 386, 150, 151, 392, 152, 138, 127, 116, 104, 105, 106, 117, 128, 140, 153, 164, 163, 176, 188, 200, 401, 201, 189, 190, 397, 177, 165, 154, 141, 129, 118, 107, 438, 82, 50, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 441, 98, 99, 83, 51, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 375, 376, 32, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 84, 85, 86, 377, 87, 88, 89, 90, 91, 92, 93, 94, 378, 95, 379, 96, 97, 382, 383, 112, 124, 134, 147, 159, 170, 183, 198, 209, 219, 225, 410, 409, 413, 236, 264, 419, 267, 415, 263, 262, 235, 261, 260, 259, 258, 257, 256, 255, 254, 253, 231, 223, 214, 202, 178, 394, 393, 166, 155, 142, 130, 119, 108, 384, 120, 121, 109, 131, 144, 143, 390, 156, 167, 180, 193, 204, 205, 206, 194, 195, 196, 181, 168, 157, 145, 132, 122, 110, 100, 435, 111, 123, 133, 146, 158, 169, 182, 197, 208, 218, 217, 207, 216, 403, 408, 407, 411, 412, 418, 421, 437, 422, 271, 274, 436, 431, 232, 224, 215, 203, 191, 179, 192, 389, 387, 380, 381, 139, 162, 175, 187, 199, 212, 221, 229, 228, 220, 210, 402, 211, 396, 213, 222, 230, 424, 420, 423, 339, 338, 276, 273, 270, 266, 269, 406]

Dynamic Programming

Costs a lot of memory

In [90]:
import math
import random
from model.base_model import Model

class MyModel(Model):
    def __init__(self):
        super().__init__()

    def init(self, coords):
        """
        Put your initialization here.
        """
        super().init(coords)
        self.log("Nothing to initialize in your model now")

    def getMST(self, node):
        MST = []
        distances = []
        for i in range(0, self.N):
            if i != node:
                MST.append(i)
                distances.append(self.dist(node, i))
        return [x for _,x in sorted(zip(distances, MST))]

    def fit(self, max_it=1000, visualize=False):
        """
        Put your iteration process here.
        """
        self.log("Uniform Cost Search Solution")

        UCS_solutions = []
        UCS_losses = []

        # Depth First: Set one city as starting point, iterate to the end, then select next city as starting point.
        MSTs = []
        for i in range(0, self.N):
            MSTs.append([-1] * self.N)
        for i in range(0, self.N):
            solution = []
            solution.append(i)
            unvisited_list = list(range(0, self.N))
            cur_city = i
            print("[starting]", i)
            for steps in range(self.N - 1):
                # print(unvisited_list)
                unvisited_list.remove(cur_city)
                if MSTs[cur_city][0] == -1:
                    MST = self.getMST(cur_city)
                    MSTs[cur_city] = MST
                
                for j in MSTs[cur_city]:
                    if(j in unvisited_list):
                        solution.append(j)
                        cur_city = j
                        break
            # print(solution)
            UCS_solutions.append(solution)
            UCS_losses.append(self.fitness(solution))

        self.best_solution = UCS_solutions[ UCS_losses.index(min(UCS_losses)) ]
        self.fitness_list.append(self.fitness(self.best_solution))

        return self.best_solution, self.fitness_list
In [91]:
tsp_problem = './template/data/medium/pcb442.tsp'
tsp_coords = np.array(load_data(tsp_problem))

import timeit
start = timeit.default_timer()

# Your Model Running

model = MyModel()
best_solution, fitness_list = TSP(tsp_problem, model)

# Your Model End

stop = timeit.default_timer()
print()
print('[*] Running for: {time:.1f} seconds'.format(time=(stop - start)))

print()
print ("Best Fitness:\t", fitness(best_solution, tsp_coords))
print ("Best Solution:\t", best_solution)
[MyModel] Nothing to initialize in your model now
[MyModel] Uniform Cost Search Solution
[starting] 0
[starting] 1
[starting] 2
[starting] 3
[starting] 4
[starting] 5
[starting] 6
[starting] 7
[starting] 8
[starting] 9
[starting] 10
[starting] 11
[starting] 12
[starting] 13
[starting] 14
[starting] 15
[starting] 16
[starting] 17
[starting] 18
[starting] 19
[starting] 20
[starting] 21
[starting] 22
[starting] 23
[starting] 24
[starting] 25
[starting] 26
[starting] 27
[starting] 28
[starting] 29
[starting] 30
[starting] 31
[starting] 32
[starting] 33
[starting] 34
[starting] 35
[starting] 36
[starting] 37
[starting] 38
[starting] 39
[starting] 40
[starting] 41
[starting] 42
[starting] 43
[starting] 44
[starting] 45
[starting] 46
[starting] 47
[starting] 48
[starting] 49
[starting] 50
[starting] 51
[starting] 52
[starting] 53
[starting] 54
[starting] 55
[starting] 56
[starting] 57
[starting] 58
[starting] 59
[starting] 60
[starting] 61
[starting] 62
[starting] 63
[starting] 64
[starting] 65
[starting] 66
[starting] 67
[starting] 68
[starting] 69
[starting] 70
[starting] 71
[starting] 72
[starting] 73
[starting] 74
[starting] 75
[starting] 76
[starting] 77
[starting] 78
[starting] 79
[starting] 80
[starting] 81
[starting] 82
[starting] 83
[starting] 84
[starting] 85
[starting] 86
[starting] 87
[starting] 88
[starting] 89
[starting] 90
[starting] 91
[starting] 92
[starting] 93
[starting] 94
[starting] 95
[starting] 96
[starting] 97
[starting] 98
[starting] 99
[starting] 100
[starting] 101
[starting] 102
[starting] 103
[starting] 104
[starting] 105
[starting] 106
[starting] 107
[starting] 108
[starting] 109
[starting] 110
[starting] 111
[starting] 112
[starting] 113
[starting] 114
[starting] 115
[starting] 116
[starting] 117
[starting] 118
[starting] 119
[starting] 120
[starting] 121
[starting] 122
[starting] 123
[starting] 124
[starting] 125
[starting] 126
[starting] 127
[starting] 128
[starting] 129
[starting] 130
[starting] 131
[starting] 132
[starting] 133
[starting] 134
[starting] 135
[starting] 136
[starting] 137
[starting] 138
[starting] 139
[starting] 140
[starting] 141
[starting] 142
[starting] 143
[starting] 144
[starting] 145
[starting] 146
[starting] 147
[starting] 148
[starting] 149
[starting] 150
[starting] 151
[starting] 152
[starting] 153
[starting] 154
[starting] 155
[starting] 156
[starting] 157
[starting] 158
[starting] 159
[starting] 160
[starting] 161
[starting] 162
[starting] 163
[starting] 164
[starting] 165
[starting] 166
[starting] 167
[starting] 168
[starting] 169
[starting] 170
[starting] 171
[starting] 172
[starting] 173
[starting] 174
[starting] 175
[starting] 176
[starting] 177
[starting] 178
[starting] 179
[starting] 180
[starting] 181
[starting] 182
[starting] 183
[starting] 184
[starting] 185
[starting] 186
[starting] 187
[starting] 188
[starting] 189
[starting] 190
[starting] 191
[starting] 192
[starting] 193
[starting] 194
[starting] 195
[starting] 196
[starting] 197
[starting] 198
[starting] 199
[starting] 200
[starting] 201
[starting] 202
[starting] 203
[starting] 204
[starting] 205
[starting] 206
[starting] 207
[starting] 208
[starting] 209
[starting] 210
[starting] 211
[starting] 212
[starting] 213
[starting] 214
[starting] 215
[starting] 216
[starting] 217
[starting] 218
[starting] 219
[starting] 220
[starting] 221
[starting] 222
[starting] 223
[starting] 224
[starting] 225
[starting] 226
[starting] 227
[starting] 228
[starting] 229
[starting] 230
[starting] 231
[starting] 232
[starting] 233
[starting] 234
[starting] 235
[starting] 236
[starting] 237
[starting] 238
[starting] 239
[starting] 240
[starting] 241
[starting] 242
[starting] 243
[starting] 244
[starting] 245
[starting] 246
[starting] 247
[starting] 248
[starting] 249
[starting] 250
[starting] 251
[starting] 252
[starting] 253
[starting] 254
[starting] 255
[starting] 256
[starting] 257
[starting] 258
[starting] 259
[starting] 260
[starting] 261
[starting] 262
[starting] 263
[starting] 264
[starting] 265
[starting] 266
[starting] 267
[starting] 268
[starting] 269
[starting] 270
[starting] 271
[starting] 272
[starting] 273
[starting] 274
[starting] 275
[starting] 276
[starting] 277
[starting] 278
[starting] 279
[starting] 280
[starting] 281
[starting] 282
[starting] 283
[starting] 284
[starting] 285
[starting] 286
[starting] 287
[starting] 288
[starting] 289
[starting] 290
[starting] 291
[starting] 292
[starting] 293
[starting] 294
[starting] 295
[starting] 296
[starting] 297
[starting] 298
[starting] 299
[starting] 300
[starting] 301
[starting] 302
[starting] 303
[starting] 304
[starting] 305
[starting] 306
[starting] 307
[starting] 308
[starting] 309
[starting] 310
[starting] 311
[starting] 312
[starting] 313
[starting] 314
[starting] 315
[starting] 316
[starting] 317
[starting] 318
[starting] 319
[starting] 320
[starting] 321
[starting] 322
[starting] 323
[starting] 324
[starting] 325
[starting] 326
[starting] 327
[starting] 328
[starting] 329
[starting] 330
[starting] 331
[starting] 332
[starting] 333
[starting] 334
[starting] 335
[starting] 336
[starting] 337
[starting] 338
[starting] 339
[starting] 340
[starting] 341
[starting] 342
[starting] 343
[starting] 344
[starting] 345
[starting] 346
[starting] 347
[starting] 348
[starting] 349
[starting] 350
[starting] 351
[starting] 352
[starting] 353
[starting] 354
[starting] 355
[starting] 356
[starting] 357
[starting] 358
[starting] 359
[starting] 360
[starting] 361
[starting] 362
[starting] 363
[starting] 364
[starting] 365
[starting] 366
[starting] 367
[starting] 368
[starting] 369
[starting] 370
[starting] 371
[starting] 372
[starting] 373
[starting] 374
[starting] 375
[starting] 376
[starting] 377
[starting] 378
[starting] 379
[starting] 380
[starting] 381
[starting] 382
[starting] 383
[starting] 384
[starting] 385
[starting] 386
[starting] 387
[starting] 388
[starting] 389
[starting] 390
[starting] 391
[starting] 392
[starting] 393
[starting] 394
[starting] 395
[starting] 396
[starting] 397
[starting] 398
[starting] 399
[starting] 400
[starting] 401
[starting] 402
[starting] 403
[starting] 404
[starting] 405
[starting] 406
[starting] 407
[starting] 408
[starting] 409
[starting] 410
[starting] 411
[starting] 412
[starting] 413
[starting] 414
[starting] 415
[starting] 416
[starting] 417
[starting] 418
[starting] 419
[starting] 420
[starting] 421
[starting] 422
[starting] 423
[starting] 424
[starting] 425
[starting] 426
[starting] 427
[starting] 428
[starting] 429
[starting] 430
[starting] 431
[starting] 432
[starting] 433
[starting] 434
[starting] 435
[starting] 436
[starting] 437
[starting] 438
[starting] 439
[starting] 440
[starting] 441
[*] Best: 58952.967129705365
[*] Writing the best solution to file

[*] Running for: 1.3 seconds

Best Fitness:	 58952.967129705365
Best Solution:	 [395, 173, 172, 161, 149, 136, 126, 385, 114, 103, 440, 101, 102, 113, 125, 135, 148, 160, 171, 184, 399, 404, 226, 233, 237, 238, 265, 268, 272, 275, 278, 280, 281, 427, 341, 340, 345, 346, 347, 432, 348, 349, 350, 351, 342, 352, 353, 354, 433, 355, 356, 357, 434, 358, 359, 360, 343, 361, 362, 363, 364, 365, 366, 344, 367, 368, 369, 370, 371, 372, 373, 374, 337, 336, 426, 335, 334, 333, 306, 332, 331, 330, 305, 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 279, 425, 439, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 428, 324, 325, 326, 327, 328, 329, 430, 429, 277, 416, 417, 252, 251, 250, 249, 414, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 234, 227, 405, 400, 185, 398, 186, 174, 391, 137, 115, 388, 386, 150, 151, 392, 152, 138, 127, 116, 104, 105, 106, 117, 128, 140, 153, 164, 163, 176, 188, 200, 401, 201, 189, 190, 397, 177, 165, 154, 141, 129, 118, 107, 438, 82, 50, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 441, 98, 99, 83, 51, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 375, 376, 32, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 84, 85, 86, 377, 87, 88, 89, 90, 91, 92, 93, 94, 378, 95, 379, 96, 97, 382, 383, 112, 124, 134, 147, 159, 170, 183, 198, 209, 219, 225, 410, 409, 413, 236, 264, 419, 267, 415, 263, 262, 235, 261, 260, 259, 258, 257, 256, 255, 254, 253, 231, 223, 214, 202, 178, 394, 393, 166, 155, 142, 130, 119, 108, 384, 120, 121, 109, 131, 144, 143, 390, 156, 167, 180, 193, 204, 205, 206, 194, 195, 196, 181, 168, 157, 145, 132, 122, 110, 100, 435, 111, 123, 133, 146, 158, 169, 182, 197, 208, 218, 217, 207, 216, 403, 408, 407, 411, 412, 418, 421, 437, 422, 271, 274, 436, 431, 232, 224, 215, 203, 191, 179, 192, 389, 387, 380, 381, 139, 162, 175, 187, 199, 212, 221, 229, 228, 220, 210, 402, 211, 396, 213, 222, 230, 424, 420, 423, 339, 338, 276, 273, 270, 266, 269, 406]

Your Smart Model

In [ ]:
import math
import random
from model.base_model import Model

class MyModel(Model):
    def __init__(self):
        super().__init__()

    def init(self, coords):
        """
        Put your initialization here.
        """
        super().init(coords)
        self.log("Nothing to initialize in your model now")

    def fit(self, max_it=1000, visualize=False):
        """
        Put your iteration process here.
        """
        self.log("Naive Random Solution")
        self.best_solution = np.random.permutation(self.N).tolist()
        self.fitness_list.append(self.fitness(self.best_solution))

        return self.best_solution, self.fitness_list

Simulated Annealing

In [ ]:
import math
import random
from model.base_model import Model

class MyModel(Model):
    def __init__(self, T=-1, alpha=-1, stopping_T=-1):
        super().__init__()

        self.iteration = 0

        self.T = T
        self.alpha = 0.995 if alpha == -1 else alpha
        self.stopping_temperature = 1e-8 if stopping_T == -1 else stopping_T

    def init(self, coords):
        super().init(coords)

        if (self.T == -1):
            self.T = math.sqrt(self.N) 
        self.T_save = self.T  # save inital T to reset if batch annealing is used

    def initial_solution(self):
        """
        Greedy algorithm to get an initial solution (closest-neighbour).
        """
        cur_node = random.choice(self.nodes)  # start from a random node
        solution = [cur_node]

        free_nodes = set(self.nodes)
        free_nodes.remove(cur_node)
        while free_nodes:
            next_node = min(free_nodes, key=lambda x: self.dist(cur_node, x))  # nearest neighbour
            free_nodes.remove(next_node)
            solution.append(next_node)
            cur_node = next_node

        cur_fit = self.fitness(solution)
        if cur_fit < self.best_fitness:  # If best found so far, update best fitness
            self.best_fitness = cur_fit
            self.best_solution = solution
        self.fitness_list.append(cur_fit)
        return solution, cur_fit

    def p_accept(self, candidate_fitness):
        """
        Probability of accepting if the candidate is worse than current.
        Depends on the current temperature and difference between candidate and current.
        """
        return math.exp(-abs(candidate_fitness - self.cur_fitness) / self.T)

    def accept(self, candidate):
        """
        Accept with probability 1 if candidate is better than current.
        Accept with probabilty p_accept(..) if candidate is worse.
        """
        candidate_fitness = self.fitness(candidate)
        if candidate_fitness < self.cur_fitness:
            self.cur_fitness, self.cur_solution = candidate_fitness, candidate
            if candidate_fitness < self.best_fitness:
                self.best_fitness, self.best_solution = candidate_fitness, candidate
        else:
            if random.random() < self.p_accept(candidate_fitness):
                self.cur_fitness, self.cur_solution = candidate_fitness, candidate

    def fit(self, max_it=1000):
        """
        Execute simulated annealing algorithm.
        """
        # Initialize with the greedy solution.
        self.cur_solution, self.cur_fitness = self.initial_solution()

        self.log("Starting annealing.")
        while self.T >= self.stopping_temperature and self.iteration < max_it:
            candidate = list(self.cur_solution)
            l = random.randint(1, self.N - 1)
            i = random.randint(0, self.N - l)
            candidate[i : (i + l)] = reversed(candidate[i : (i + l)])
            self.accept(candidate)
            self.T *= self.alpha
            self.iteration += 1

            self.fitness_list.append(self.cur_fitness)

        self.log(f"Best fitness obtained: {self.best_fitness}")
        improvement = 100 * (self.fitness_list[0] - self.best_fitness) / (self.fitness_list[0])
        self.log(f"Improvement over greedy heuristic: {improvement : .2f}%")

        return self.best_solution, self.fitness_list

Test your Model

In [ ]:
tsp_problem = './template/data/simple/ulysses16.tsp'
tsp_coords = np.array(load_data(tsp_problem))
In [ ]:
import timeit
start = timeit.default_timer()

# Your Model Running

model = MyModel()
best_solution, fitness_list = TSP(tsp_problem, model)

# Your Model End

stop = timeit.default_timer()
print()
print('[*] Running for: {time:.1f} seconds'.format(time=(stop - start)))

print()
print ("Best Fitness:\t", fitness(best_solution, tsp_coords))
print ("Best Solution:\t", best_solution)

Test All Dataset

In [83]:
for root, _, files in os.walk('./template/data'):
    if(files):
        for f in files:
            print(str(root) + "/" + f)
./template/data/medium/pcb442.tsp
./template/data/medium/a280.tsp
./template/data/hard/dsj1000.tsp
./template/data/simple/att48.tsp
./template/data/simple/ulysses16.tsp
./template/data/simple/st70.tsp
In [ ]:
for root, _, files in os.walk('./template/data'):
    if(files):
        for f in files:
            # Get input file name
            tsp_file = str(root) + '/' + str(f)
            log(tsp_file)

            # Your Model
            model = MyModel()

            # Run TSP
            TSP(tsp_file, model)

            print()
In [ ]:

</html>