def sa_algorithm(self): ga = Greedy(self.cities_matrix, self.number_of_cities) solution = ga.greedy_algorithm() starting_temp = 100 current_temperature = starting_temp min_length = self.tour_length(solution) best_solution = [] i = 0 coolingRate = 0.00015 #this is the best I've found: 0.0002 cool_count = 0 lengths = [] loop_count = [] lo = 0 average_distance = self.cities_matrix.sum() / self.number_of_cities**3 print(average_distance) diff_frac = 0.01 * average_distance**0.5 print('Diff_frac' + str(diff_frac)) while current_temperature > 0.05: i += 1 solution = self.optimise(self.cities_matrix, solution, self.number_of_cities, current_temperature, diff_frac) if i >= 150: i = 0 #reset i cool_count += 1 currentLength = self.tour_length(solution) #Exponential multiplicative cooling: current_temperature = starting_temp * ( 1 - coolingRate)**cool_count #t *= 1 - coolingRate #current_temperature = starting_temp*math.exp( -( 0.001*1.2*cool_count**1.15 ) ) # current_temperature = starting_temp/(1+1.8*math.log(1+0.001*cool_count)) lo += 1 loop_count.append(lo) lengths.append(currentLength) if currentLength < min_length: min_length = currentLength best_solution = solution[:] # plt.plot(loop_count, lengths, 'b.') # filename = 'city'+str(number_of_cities) # plt.savefig(filename, format='svg', dpi=1200) # plt.show() return best_solution
def genetic(self): #init ga = Greedy(self.cities_matrix, self.tourlength) initial = ga.greedy_algorithm() current_pop = [] for i in range(100): baby = initial[:] #swap a few in initial if random.random() < 0.95: baby = self.rnd_swap(baby) if random.random() < 0.7: baby = self.rnd_swap(baby) if random.random() < 0.4: baby = self.rnd_swap(baby) #current.shuffle()#shuffle to a certain degree # current = random.sample(range(1, tourlength + 1), tourlength) current_pop.append((baby, self.tour_length(baby))) # print("currentpopppppp"+str(len(current_pop))) min_length = min(list(map(lambda x: x[1], current_pop))) curr_best = list(filter(lambda x: x[1] == min_length, current_pop))[0] # print(curr_best) ######################## new_best = curr_best[:] checker = 0 new_pop = [] while checker < 20: #while not(max fitness hasn't improved in x generations) for i in range(100): parents = self.select_parents(current_pop) dad, mum = parents[0], parents[1] #SPLICE rand_index = random.randint(0, self.tourlength - 1) #take the prefix of dad and add the suffix of mum child_with_duplicates = dad[0][:rand_index] + mum[0][ rand_index:] #MUTATE for j in range(len(child_with_duplicates)): #for city in child_with_duplicates: if random.random( ) < 0.01: #with a 1% chance randomly mutate each city #city = random.sample(range(1, tourlength + 1), tourlength)[0] child_with_duplicates[j] = random.randint( 1, self.tourlength) #make a set of all the cities not included not_included = [x for x in range(1, self.tourlength + 1)] for c in child_with_duplicates: if c in not_included: not_included.remove(c) random.shuffle(not_included) #check over for repetitions, if there is: add the first from the set child = [] for c in child_with_duplicates: if c in child: child.append(not_included[0]) not_included.pop(0) else: child.append(c) #add child to current_pop[i] new_pop.append((child, self.tour_length(child))) current_pop = new_pop new_pop = [] min_length = min(list(map(lambda x: x[1], current_pop))) new_best = list(filter(lambda x: x[1] == min_length, current_pop))[0] # print("new_best: " + str(new_best[1]) + "curr_best: " + str(curr_best[1])) # print("curr_best[1] > new_best[1] : " + str(curr_best[1] > new_best[1])) ######################## if curr_best[1] > new_best[1]: curr_best = new_best checker == 0 elif curr_best[1] == new_best[1]: checker += 1 # else : # checker == 0 # print("new_best: " + str(new_best[1])) # print("Fittest in generation: " + str(curr_best[0])) # print("Length: " + str(curr_best[1])) # print("checker:" + str(checker)) return curr_best[0]