Zaktualizuj 'genetic_route.py'

This commit is contained in:
Jakub Damiński 2020-06-15 01:32:04 +00:00
parent 03efb3cdcf
commit b6faed1ed2

View File

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