diff --git a/agent.py b/agent.py index 7aac9bd..b90e388 100644 --- a/agent.py +++ b/agent.py @@ -14,7 +14,7 @@ kitchen = Kitchen([0, 0], 0, SQUARE_SIZE, SCREEN_SIZE, store) engine = Engine(SCREEN_SIZE, SQUARE_SIZE, kitchen, waiter, ACTION_DURATION) layout = LayoutController(engine, store) -params = layout.train_loop(10) +params = layout.train_loop(12) layout.create_and_subscribe( params['radius'], diff --git a/src/Engine.py b/src/Engine.py index eb1bbfe..268d655 100644 --- a/src/Engine.py +++ b/src/Engine.py @@ -179,6 +179,7 @@ class Engine: def unattainable_goal(self): if not self.is_simulation: print(colored("Object unattainable", "red")) + self.objects.remove(self.goal.parent) self.clock_increment(1000) self.revoke_goal() diff --git a/src/controller/LayoutController.py b/src/controller/LayoutController.py index 72d6471..57cad55 100644 --- a/src/controller/LayoutController.py +++ b/src/controller/LayoutController.py @@ -48,7 +48,7 @@ class LayoutController(): return action_clock < 1000 population = PriorityQueue() - for i in range(20): + for i in range(15): params = ( child_params[i] if child_params @@ -89,35 +89,62 @@ class LayoutController(): def reproduction(self, parents): parents.queue = parents.queue[:5] children = [] - while len(children) < 20: + while len(children) < 10: p1 = random.choice(parents.queue) p2 = random.choice(parents.queue) + mask = { + 'radius': random.randint(0, 1), + 'neighbors_count': random.randint(0, 1), + 'block_probability': random.randint(0, 1) + } + + child1 = { + 'radius': p1.o()['radius'] if mask['radius'] else p2.o()['radius'], + 'neighbors_count': p1.o()['neighbors_count'] if mask['neighbors_count'] else p2.o()['neighbors_count'], + 'block_probability': p1.o()['block_probability'] if mask['block_probability'] else p2.o()['block_probability'], + } + child2 = { + 'radius': p1.o()['radius'] if not mask['radius'] else p2.o()['radius'], + 'neighbors_count': p1.o()['neighbors_count'] if not mask['neighbors_count'] else p2.o()['neighbors_count'], + 'block_probability': p1.o()['block_probability'] if not mask['block_probability'] else p2.o()['block_probability'], + } + + children.append(child1) + children.append(child2) + + for p in parents.queue[:5]: child = { - 'radius': random.choice([p1.o()['radius'], p2.o()['radius']]), - 'neighbors_count': random.choice([p1.o()['neighbors_count'], p2.o()['neighbors_count']]), - 'block_probability': random.choice([p1.o()['block_probability'], p2.o()['block_probability']]) + 'radius': p.o()['radius'], + 'neighbors_count': p.o()['neighbors_count'], + 'block_probability': p.o()['block_probability'] } children.append(child) return children def mutation(self, params): - for _ in range(5): - unit = random.choice(params) - mutation_type = random.choice( - [ - 'radius', - 'neighbors_count', - 'block_probability' - ] - ) - if mutation_type == 'radius': - unit[mutation_type] = self.get_random_radius() - elif mutation_type == 'neighbors_count': - unit[mutation_type] = self.get_random_neighbors_count() - elif mutation_type == 'block_probability': - unit[mutation_type] = self.get_random_block_probability() + MUTATION_CHANCE = 10 + + for _ in range(10): + if random.randint(0, 100) <= MUTATION_CHANCE: + + unit = random.choice(params) + mutation_type = random.choice( + [ + 'radius', + 'neighbors_count', + 'block_probability' + ] + ) + if mutation_type == 'radius': + unit[mutation_type] += self.get_random_radius() + elif mutation_type == 'neighbors_count': + unit[mutation_type] += self.get_random_neighbors_count() + elif mutation_type == 'block_probability': + unit[mutation_type] += self.get_random_block_probability() + + unit[mutation_type] //= 2 return params @@ -129,6 +156,7 @@ class LayoutController(): while best < goal: generation += 1 population = self.simulation(params) + print( colored(f"generation #{generation}", "yellow"), colored("best fit:", "blue"),