76 lines
2.3 KiB
Python
76 lines
2.3 KiB
Python
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
|