generate list of traveling by GA
This commit is contained in:
parent
d363120ef4
commit
80b7e32f47
@ -1,4 +1,38 @@
|
|||||||
from random import random, choice
|
from random import random, choice
|
||||||
|
|
||||||
class GeneticAlgorithm:
|
class GeneticAlgorithm:
|
||||||
pass
|
def __init__(self, firstPopulation, mutationProbability):
|
||||||
|
self.firstPopulation = firstPopulation
|
||||||
|
self.mutationProbability = mutationProbability
|
||||||
|
|
||||||
|
def selectionModel(self, generation):
|
||||||
|
max_selected = int(len(generation) / 10)
|
||||||
|
sorted_by_assess = sorted(generation, key=lambda x: x.fitness)
|
||||||
|
return sorted_by_assess[:max_selected]
|
||||||
|
|
||||||
|
def stopCondition(self, i):
|
||||||
|
return i == 100
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
population = self.firstPopulation
|
||||||
|
population.sort(key=lambda x: x.fitness)
|
||||||
|
populationLen = len(population)
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
selected = self.selectionModel(population)
|
||||||
|
newPopulation = selected.copy()
|
||||||
|
while len(newPopulation) != populationLen:
|
||||||
|
child = choice(population).crossover(choice(population))
|
||||||
|
if random() <= self.mutationProbability:
|
||||||
|
child.mutation()
|
||||||
|
newPopulation.append(child)
|
||||||
|
|
||||||
|
population = newPopulation
|
||||||
|
theBestMatch = min(population, key=lambda x: x.fitness)
|
||||||
|
print("Generation: {} S: {} fitness: {}".format(i, theBestMatch, theBestMatch.fitness))
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
if self.stopCondition(i):
|
||||||
|
return theBestMatch
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,51 @@
|
|||||||
from random import randint, sample
|
from random import randint, sample
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
|
from src.AI.GaTravelingForHerbs.GeneticAlgorithm import GeneticAlgorithm
|
||||||
|
|
||||||
START_COORD = [(6, 2)]
|
START_COORD = [(6, 2)]
|
||||||
END_COORD = [(10, 7)]
|
END_COORD = [(10, 7)]
|
||||||
COORDS = [(12, 2), (16, 2), (17, 5), (14, 7), (17, 17), (13, 17), (5, 15), (2, 9), (8, 5), (11, 10)]
|
COORDS = [(12, 2), (16, 2), (17, 5), (14, 7), (17, 17), (13, 17), (5, 15), (2, 9), (8, 5), (11, 10)]
|
||||||
|
|
||||||
|
|
||||||
class Traveling:
|
class Traveling:
|
||||||
def __init__(self, coords):
|
def __init__(self, coords):
|
||||||
self.coords = coords
|
self.coords = coords
|
||||||
|
self.fitness = self.evaluate()
|
||||||
|
|
||||||
|
def evaluate(self):
|
||||||
|
sum = 0
|
||||||
|
for i, c in enumerate(self.coords):
|
||||||
|
if i + 1 > len(self.coords) - 1:
|
||||||
|
break
|
||||||
|
nextCoord = self.coords[i + 1]
|
||||||
|
# calculate distance
|
||||||
|
sum += sqrt((nextCoord[0] - c[0]) ** 2 + (nextCoord[1] - c[1]) ** 2)
|
||||||
|
return sum
|
||||||
|
|
||||||
|
def crossover(self, element2: 'Element') -> 'Element':
|
||||||
|
childCoords = self.coords[1:int(len(self.coords) / 2)]
|
||||||
|
for coord in element2.coords:
|
||||||
|
if coord not in childCoords and coord not in END_COORD + START_COORD:
|
||||||
|
childCoords.append(coord)
|
||||||
|
|
||||||
|
if len(childCoords) == len(element2.coords):
|
||||||
|
break
|
||||||
|
return Traveling(START_COORD + childCoords + END_COORD)
|
||||||
|
|
||||||
|
def mutation(self):
|
||||||
|
first = randint(1, len(self.coords) - 2)
|
||||||
|
second = randint(1, len(self.coords) - 2)
|
||||||
|
self.coords[first], self.coords[second] = self.coords[second], self.coords[first]
|
||||||
|
self.fitness = self.evaluate()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return str(self.coords)
|
||||||
|
|
||||||
|
|
||||||
|
firstGeneration = [Traveling(START_COORD + sample(COORDS, len(COORDS)) + END_COORD) for _ in range(100)]
|
||||||
|
mutationProbability = float(0.1)
|
||||||
|
|
||||||
|
ga = GeneticAlgorithm(firstGeneration, mutationProbability)
|
||||||
|
movementList = ga.run()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user