import math import random import numpy as np from model.base_model import Model class MyHillClimbModel(Model): def __init__(self): super().__init__() def init(self, nodes): """ Put your initialization here. """ super().init(nodes) def random_tour(self): return np.random.permutation(self.N).tolist() def all_pairs(self, size, shuffle=random.shuffle): r1 = list(range(size)) r2 = list(range(size)) if shuffle: shuffle(r1) shuffle(r2) for i in r1: for j in r2: yield (i,j) def move_operator(self, tour): '''generator to return all possible variations where the section between two cities are swapped''' for i,j in self.all_pairs(len(tour)): if i != j: copy=tour[:] if i < j: copy[i:j+1]=reversed(tour[i:j+1]) else: copy[i+1:]=reversed(tour[:j]) copy[:j]=reversed(tour[i+1:]) if copy != tour: # no point returning the same tour yield copy def fit(self, max_it=100): """ Put your iteration process here. """ self.best_solution = self.random_tour() best_score = -self.fitness(self.best_solution) num_evaluations = 0 while num_evaluations < max_it: # examine moves around our current position move_made = False for next_solution in self.move_operator(self.best_solution): if num_evaluations >= max_it: print("Max iteration reached:", max_it) break # see if this move is better than the current next_score = -self.fitness(next_solution) num_evaluations += 1 if next_score > best_score: self.best_solution = next_solution self.fitness_list.append(self.fitness(self.best_solution)) best_score=next_score move_made=True break # depth first search if not move_made: break # we couldn't find a better move (must be at a local maximum) return self.best_solution, self.fitness_list