def main(): parser = argparse.ArgumentParser() parser.add_argument("dataset", help="Path to graph dataset (.gml format)") parser.add_argument("-n", "--number", type=int, help="Number of solutions to generate", required=True) parser.add_argument("-v", "--verbose", action='store_true', help="Show all vertices value") parser.add_argument("-t", "--timeit", action='store_true', help="Print execution time of chosen method") parser.add_argument("-p", "--plot", action='store_true', help="Plot the graphs generated") args = parser.parse_args() graph = tsp.TSP(args.dataset) if (args.plot): tsp.plot(graph.graph, 0, "Graph") for i in range(args.number): t = process_time() (hamiltonian_graph, hamiltonian_path) = graph.twice_around() elapsed_time = process_time() - t print("TSP solution #%d: %d" % (i + 1, tsp.sum_weights(hamiltonian_graph))) if args.verbose: print("Path: ", end="") for j in range(len(hamiltonian_path)): if j != 0: print(" -> ", end="") print(hamiltonian_path[j], end="") print() if (args.timeit): print("Time: %.5f seconds" % elapsed_time) if (args.plot): tsp.plot(hamiltonian_graph, i + 1, "Hamiltonian Graph #" + str(i + 1)) print() if args.plot: plt.show()
def main(): parser = argparse.ArgumentParser() parser.add_argument("dataset", help="Path to graph dataset (.gml format)") parser.add_argument("-n", "--number", type=int, help="Number of solutions to generate", required=True) parser.add_argument("-v", "--verbose", action='store_true', help="Show all vertices value") parser.add_argument("-t", "--timeit", action='store_true', help="Print execution time of chosen method") parser.add_argument("-p", "--plot", action='store_true', help="Plot the graphs generated") args = parser.parse_args() graph = tsp.TSP(args.dataset) if (args.plot): tsp.plot(graph.graph, 0, "Graph") for i in range(args.number): t = process_time() (hamiltonian_graph, hamiltonian_path) = graph.twice_around() elapsed_time = process_time() - t print("TSP solution #%d: %d" % (i+1, tsp.sum_weights(hamiltonian_graph))) if args.verbose: print("Path: ", end="") for j in range(len(hamiltonian_path)): if j != 0: print(" -> ", end="") print(hamiltonian_path[j], end="") print() if (args.timeit): print("Time: %.5f seconds" % elapsed_time) if (args.plot): tsp.plot(hamiltonian_graph, i+1, "Hamiltonian Graph #" + str(i+1)) print() if args.plot: plt.show()
# https://ericphanson.com/blog/2016/the-traveling-salesman-and-10-lines-of-python/ # *also 10 lines of code (w/o comments, empty lines + merge 'if' into one line ) # but with usage of tsp 'library' :) ~ simulated annealing logic is all here. import random import numpy as np from tsp import tsp_map, mutate, cost, plot cities = tsp_map(n_cities=20, scale=1000) path = np.random.choice(np.arange(len(cities)), len(cities), replace=False) # we cut half of logspace as first/second half is bit brutal for temperature for temperature in reversed(np.logspace(0, 3, 1e5)[:int(1e5 / 2)]): a, b = mutate(path, degree=2) # interesting trick: we dont need to checkpoint best path !! # as if new path better np.exp(-..) is low, best path will survive most likely if np.exp( (cost(cities, path, [a, b], [a, b]) - cost(cities, path, [a, b], [b, a])) / temperature) > random.random(): path[[a, b]] = path[[b, a]] plot(cities, path)
while len(visited) != len(cities): mu = trail[len(visited)] # not actually same as learning rate, # therefore degree of how fierce we want to follow pheromone paths sigma = DEGREE_OF_STEP * error(trails, neighbours, len(visited), mu) mu_ex = action(visited, mu, sigma) var += sigma stats.append([mu_ex, mu, sigma, len(visited)]) visited.append(mu_ex) if len(visited) > 1: score += dist[visited[-1], visited[-2]] trails[EVAPORATION_POOL + c, len(visited) - 1] = visited[-1] total_cost[EVAPORATION_POOL + c] = score if var < VAR_CERTAINITY: break # heur :: model seems certain enough scores.append(np.mean(total_cost[EVAPORATION_POOL:])) trails, total_cost = evaluate(trails, total_cost) print("EPOCH", i, "cost:", scores[-1], "var", var) # not too readable as now difference is relative on distance not on order [print("-->", s) for s in stats] plot_learning(scores) plot(cities, [int(t) for t in trails[0]]) # best plot(cities, [int(t) for t in trails[COUNT]]) # currently explored
def plot(self): self.particles.sort(key=lambda p: p.best.error) plot(swarm.cities, self.particles[0].best.path)
scores = [] for _ in range(200): elite = np.argsort(fitness)[:ELITE] for i in range(COUNT): # out = ''' op = random.randint(0, 2) a, b = tournament(fitness) if 1 > op: pop_c, fit_c = mutation(cities, population, a) elif 2 > op: pop_c, fit_c = pclone(cities, population, a, b) elif 3 > op: pop_c, fit_c = crossover(cities, population, a, b) if pop_c is None: continue fitness.append(fit_c) population.append(pop_c) elite = np.argsort(fitness) breed = np.argsort([evaluate(fitness, i) for i in range(len(fitness))]) evolution = np.concatenate([elite[:ELITE], breed[:COUNT - ELITE]]) scores.append( np.asarray(fitness)[evolution].mean()) #elite[:ELITE]].mean()) fitness = [fitness[i] for i in evolution] population = [population[i] for i in evolution] plot_learning(scores) plot(cities, population[np.argsort(fitness)[0]])
def action(visited, pheromones): todos = list(set(range(len(pheromones[0]))) - set(visited)) phero = pheromones[visited[-1]][todos] probs = phero / phero.sum() return np.random.choice(todos, size=1, p=probs)[0] pheromones = np.ones([len(cities), len(cities)]) * 1e-8 scores = [] for i in range(50): phero = pheromones.copy()**C_PHERO * (1. / dist)**C_HEUR total_cost = [] trails = [] for _ in range(COUNT): visited = [random.randint(0, len(cities) - 1)] score = 0 while len(visited) != len(cities): visited.append(action(visited, phero)) score += dist[visited[-1], visited[-2]] total_cost.append(score) trails.append(visited) pheromones = evaluate(cities, trails, pheromones, total_cost) scores.append(np.mean(total_cost)) print("EPOCH", i, "cost: ", scores[-1]) plot_learning(scores) plot(cities, trails[np.argsort(total_cost[-len(trails):])[0]])