generate list of traveling by GA
This commit is contained in:
parent
d363120ef4
commit
80b7e32f47
@ -1,4 +1,38 @@
|
||||
from random import random, choice
|
||||
|
||||
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 math import sqrt
|
||||
|
||||
from src.AI.GaTravelingForHerbs.GeneticAlgorithm import GeneticAlgorithm
|
||||
|
||||
START_COORD = [(6, 2)]
|
||||
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)]
|
||||
|
||||
|
||||
class Traveling:
|
||||
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