mutations geneticAlg
This commit is contained in:
parent
74fd6d9263
commit
a404e70058
@ -1,6 +1,9 @@
|
|||||||
|
import copy
|
||||||
import random
|
import random
|
||||||
import configparser
|
import configparser
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
import pygame
|
||||||
from domain.entities.entity import Entity
|
from domain.entities.entity import Entity
|
||||||
|
|
||||||
|
|
||||||
@ -9,6 +12,7 @@ config.read("config.ini")
|
|||||||
|
|
||||||
from domain.world import World
|
from domain.world import World
|
||||||
from AI_brain.rotate_and_go_aStar import RotateAndGoAStar, State
|
from AI_brain.rotate_and_go_aStar import RotateAndGoAStar, State
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
|
||||||
hits = 0
|
hits = 0
|
||||||
@ -44,9 +48,7 @@ class Path:
|
|||||||
permutation = generate_random_permutation(len(dusts))
|
permutation = generate_random_permutation(len(dusts))
|
||||||
self.permutation = permutation
|
self.permutation = permutation
|
||||||
|
|
||||||
self.walk = addStartAndStation(
|
self.walk = addStartAndStation(permutation)
|
||||||
permutation, config.getint("CONSTANT", "BananaFilling")
|
|
||||||
)
|
|
||||||
|
|
||||||
def calculate_distance(self, world: World):
|
def calculate_distance(self, world: World):
|
||||||
distance = 0
|
distance = 0
|
||||||
@ -145,8 +147,8 @@ def generate_random_permutation(n):
|
|||||||
|
|
||||||
|
|
||||||
# BUG solution: inverse direction at the last step
|
# BUG solution: inverse direction at the last step
|
||||||
def addStartAndStation(permutation: list[int], bananaFilling: int):
|
def addStartAndStation(permutation: list[int]):
|
||||||
frequency = math.ceil(100 / bananaFilling)
|
frequency = math.ceil(100 / config.getint("CONSTANT", "BananaFilling"))
|
||||||
numer_of_stops = math.ceil(len(permutation) / frequency)
|
numer_of_stops = math.ceil(len(permutation) / frequency)
|
||||||
walk = permutation.copy()
|
walk = permutation.copy()
|
||||||
|
|
||||||
@ -186,6 +188,16 @@ class GeneticAlgorytm:
|
|||||||
path.calculate_distance(self.world)
|
path.calculate_distance(self.world)
|
||||||
self.paths.append(path)
|
self.paths.append(path)
|
||||||
|
|
||||||
|
def print_top(self):
|
||||||
|
print(
|
||||||
|
"Best path: ",
|
||||||
|
self.best_path.walk,
|
||||||
|
"Distance: ",
|
||||||
|
self.best_path.distance,
|
||||||
|
)
|
||||||
|
for path in self.paths[1:]:
|
||||||
|
print(path.walk, path.distance)
|
||||||
|
|
||||||
def evaluate_population(self):
|
def evaluate_population(self):
|
||||||
self.paths.sort(key=lambda x: x.distance, reverse=False)
|
self.paths.sort(key=lambda x: x.distance, reverse=False)
|
||||||
|
|
||||||
@ -207,9 +219,7 @@ class GeneticAlgorytm:
|
|||||||
if item not in child.permutation:
|
if item not in child.permutation:
|
||||||
child.permutation.append(item)
|
child.permutation.append(item)
|
||||||
|
|
||||||
child.walk = addStartAndStation(
|
child.walk = addStartAndStation(child.permutation)
|
||||||
child.permutation, config.getint("CONSTANT", "BananaFilling")
|
|
||||||
)
|
|
||||||
|
|
||||||
child.calculate_distance(self.world)
|
child.calculate_distance(self.world)
|
||||||
|
|
||||||
@ -220,7 +230,6 @@ class GeneticAlgorytm:
|
|||||||
|
|
||||||
for i in range(self.iteration_number):
|
for i in range(self.iteration_number):
|
||||||
self.crossover()
|
self.crossover()
|
||||||
# self.mutate()
|
|
||||||
|
|
||||||
self.evaluate_population()
|
self.evaluate_population()
|
||||||
self.best_real_path = self.paths[0].get_real_path(self.world)
|
self.best_real_path = self.paths[0].get_real_path(self.world)
|
||||||
@ -229,6 +238,25 @@ class GeneticAlgorytm:
|
|||||||
|
|
||||||
print(hits / (misses + hits))
|
print(hits / (misses + hits))
|
||||||
|
|
||||||
|
def mutate(self, mutant: Path) -> Path:
|
||||||
|
random_number = randint(0, len(mutant.permutation) - 1)
|
||||||
|
random_number2 = random_number
|
||||||
|
while random_number == random_number2:
|
||||||
|
random_number2 = randint(0, len(mutant.permutation) - 1)
|
||||||
|
|
||||||
|
mutant.permutation[random_number], mutant.permutation[random_number2] = (
|
||||||
|
mutant.permutation[random_number2],
|
||||||
|
mutant.permutation[random_number],
|
||||||
|
)
|
||||||
|
|
||||||
|
if tuple(mutant.permutation) in self.checked_permutations:
|
||||||
|
return self.mutate(mutant)
|
||||||
|
|
||||||
|
mutant.walk = addStartAndStation(mutant.permutation)
|
||||||
|
|
||||||
|
mutant.calculate_distance(self.world)
|
||||||
|
return mutant
|
||||||
|
|
||||||
def crossover(self):
|
def crossover(self):
|
||||||
for i in range(self.descendants_number):
|
for i in range(self.descendants_number):
|
||||||
parent1 = self.paths[random.randint(0, self.population_size - 1)]
|
parent1 = self.paths[random.randint(0, self.population_size - 1)]
|
||||||
@ -244,4 +272,10 @@ class GeneticAlgorytm:
|
|||||||
self.checked_permutations[tuple(child.permutation)] = True
|
self.checked_permutations[tuple(child.permutation)] = True
|
||||||
self.paths.append(child)
|
self.paths.append(child)
|
||||||
|
|
||||||
|
mutant = Path()
|
||||||
|
mutant.permutation = child.permutation.copy()
|
||||||
|
mutant = self.mutate(mutant)
|
||||||
|
self.checked_permutations[tuple(mutant.permutation)] = True
|
||||||
|
self.paths.append(mutant)
|
||||||
|
|
||||||
self.evaluate_population()
|
self.evaluate_population()
|
||||||
|
14
config.ini
14
config.ini
@ -4,12 +4,12 @@ movement = robot
|
|||||||
#accept: human, robot
|
#accept: human, robot
|
||||||
|
|
||||||
[CONSTANT]
|
[CONSTANT]
|
||||||
NumberOfBananas = 5
|
NumberOfBananas = 15
|
||||||
NumberOfEarrings = 3
|
NumberOfEarrings = 0
|
||||||
NumberOfPlants = 5
|
NumberOfPlants = 5
|
||||||
BananaFilling = 25
|
BananaFilling = 25
|
||||||
RobotStartPosition = 1, 1
|
RobotStartPosition = 5, 5
|
||||||
DockStationStartPosition = 9, 8
|
DockStationStartPosition = 5, 6
|
||||||
#9,8
|
#9,8
|
||||||
|
|
||||||
[NEURAL_NETWORK]
|
[NEURAL_NETWORK]
|
||||||
@ -21,6 +21,6 @@ mode = full_clean
|
|||||||
|
|
||||||
[GENETIC_ALGORITHM]
|
[GENETIC_ALGORITHM]
|
||||||
PopulationSize = 20
|
PopulationSize = 20
|
||||||
DescendantsNumber = 5
|
DescendantsNumber = 6
|
||||||
MutationProbability = 0.1
|
MutationProbability = 0.3
|
||||||
IterationNumber = 100
|
IterationNumber = 1_000
|
||||||
|
@ -27,6 +27,7 @@ class VacuumMoveCommand(Command):
|
|||||||
if self.vacuum.get_container_filling() < 100:
|
if self.vacuum.get_container_filling() < 100:
|
||||||
self.vacuum.increase_container_filling()
|
self.vacuum.increase_container_filling()
|
||||||
self.world.delete_entities_at_Of_type(item.x, item.y, item.type)
|
self.world.delete_entities_at_Of_type(item.x, item.y, item.type)
|
||||||
|
self.world.dust[end_x][end_y].remove(item)
|
||||||
|
|
||||||
if self.world.is_docking_station_at(end_x, end_y):
|
if self.world.is_docking_station_at(end_x, end_y):
|
||||||
self.vacuum.dump_trash()
|
self.vacuum.dump_trash()
|
||||||
|
20
main.py
20
main.py
@ -70,11 +70,7 @@ class Main:
|
|||||||
genetic_searcher = GeneticAlgorytm(self.world)
|
genetic_searcher = GeneticAlgorytm(self.world)
|
||||||
genetic_searcher.run()
|
genetic_searcher.run()
|
||||||
|
|
||||||
print(
|
genetic_searcher.print_top()
|
||||||
str(genetic_searcher.best_path.walk)
|
|
||||||
+ ": "
|
|
||||||
+ str(genetic_searcher.best_distance)
|
|
||||||
)
|
|
||||||
|
|
||||||
robot_actions = genetic_searcher.best_path.real_path
|
robot_actions = genetic_searcher.best_path.real_path
|
||||||
|
|
||||||
@ -190,9 +186,15 @@ def generate_world(tiles_x: int, tiles_y: int) -> World:
|
|||||||
world.add_entity(Entity(9, 3, "PLANT3"))
|
world.add_entity(Entity(9, 3, "PLANT3"))
|
||||||
|
|
||||||
numberOfEarrings = config.getint("CONSTANT", "NumberOfEarrings")
|
numberOfEarrings = config.getint("CONSTANT", "NumberOfEarrings")
|
||||||
world.add_entity(Earring(9, 7))
|
for _ in range(numberOfEarrings):
|
||||||
world.add_entity(Earring(5, 5))
|
temp_x = randint(0, tiles_x - 1)
|
||||||
world.add_entity(Earring(4, 6))
|
temp_y = randint(0, tiles_y - 1)
|
||||||
|
|
||||||
|
while world.is_entity_at(temp_x, temp_y):
|
||||||
|
temp_x = randint(0, tiles_x - 1)
|
||||||
|
temp_y = randint(0, tiles_y - 1)
|
||||||
|
|
||||||
|
world.add_entity(Earring(temp_x, temp_y))
|
||||||
|
|
||||||
for _ in range(config.getint("CONSTANT", "NumberOfBananas")):
|
for _ in range(config.getint("CONSTANT", "NumberOfBananas")):
|
||||||
temp_x = randint(0, tiles_x - 1)
|
temp_x = randint(0, tiles_x - 1)
|
||||||
@ -248,7 +250,7 @@ def generate_world(tiles_x: int, tiles_y: int) -> World:
|
|||||||
if world.garbage_at(x, y):
|
if world.garbage_at(x, y):
|
||||||
world.costs[x][y] = 1
|
world.costs[x][y] = 1
|
||||||
else:
|
else:
|
||||||
world.costs[x][y] = 10
|
world.costs[x][y] = 2
|
||||||
return world
|
return world
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user