import numpy as np from random import randrange, random from math import floor import copy num_of_surviving = 6 num_of_couples = 8 mutation_probability = 0.07 max_population = 20 iterations = 50 # creates new random solution to add to population def create_new_route(points): route = np.random.permutation(points) route = [x + 1 for x in route] return route # creates initian population def create_population(points): population = [] for i in range(max_population): population.append(create_new_route(points)) return population # gives score to a solution based on lenght def score_route(graph_map, route): score = graph_map[0][route[0]] for i in range(len(route) - 2): rack = len(route) + route[0] score = score + graph_map[rack][route[i + 1]] score = score + graph_map[route[i + 1]][route[i + 2]] return score # scores every solution in population def score_all(graph_map, population): scores = [] for i in range(len(population)): tmp = [i, score_route(graph_map, population[i])] scores.append(tmp) return scores # designed to create new population by mixing steps between most succesfull solutions def crossover(a, b): new_a = copy.deepcopy(a) new_b = copy.deepcopy(b) for i in range(floor(len(a) / 2)): rel = randrange(len(a)) tmp_a = new_a[rel] tmp_b = new_b[rel] if tmp_a == tmp_b: continue new_a[new_a.index(tmp_b)] = tmp_a new_b[new_b.index(tmp_a)] = tmp_b new_a[rel] = tmp_b new_b[rel] = tmp_a return new_a, new_b # adds randomness to newly created solutions def mutate(route): new_route = copy.deepcopy(route) for i in range(len(route) - 1): if random() < mutation_probability: tmp = new_route[i] new_route[i] = new_route[i + 1] new_route[i + 1] = tmp return new_route # main function that iterate population until the best solutions emerge def genetic_trace_route(graph_map, packages): population = create_population(packages) for i in range(iterations): new_population = [] scores = score_all(graph_map, population) scores.sort(key=lambda x: x[1]) # breeding for j in range(0, num_of_couples, 2): a, b = crossover(population[scores[j][0]], population[scores[j+1][0]]) new_population.append(a) new_population.append(b) # mutations for j in range(len(new_population)): mutate(new_population[j]) # survival for j in range(0, num_of_surviving): new_population.append(population[scores[j][0]]) # random new for j in range(max_population - (num_of_surviving + num_of_couples)): new_population.append(create_new_route(packages)) population.clear() population = copy.deepcopy(new_population) scores = score_all(graph_map, population) scores.sort(key=lambda x: x[1]) # print("Best route of all population in iteration " + str(i + 1)) # print(scores[0][1]) scores = score_all(graph_map, population) scores.sort(key=lambda x: x[1]) return population[scores[0][0]]