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