diff --git a/car.py b/car.py index d357ede..866098d 100644 --- a/car.py +++ b/car.py @@ -24,7 +24,7 @@ class Car(pygame.sprite.Sprite): self.rect = self.image.get_rect() self.vision_length = VISION_LENGTH # line liength self.vision_span = VISION_SPAN # degrees - self.draw_sensors = True + self.draw_sensors = False # lets add 3 sensors as a start # 1 straight ahead @@ -77,7 +77,7 @@ class Car(pygame.sprite.Sprite): self.rect.center = (self.speed * vec[0] / 2 + old_center[0], -self.speed * vec[1] / 2 + old_center[1]) self.update_sensors() self.distance_run += int(distance(old_center, self.rect.center)) - self.brain.fitness = math.sqrt(self.distance_run) + self.brain.fitness = int(math.sqrt(self.distance_run)) @@ -89,7 +89,8 @@ class Car(pygame.sprite.Sprite): ip = segments_intersection(sensor, line) # print(ip) if ip : - pygame.draw.circle(screen, (125,125,255), ip, 4, 2) + if self.draw_sensors : + pygame.draw.circle(screen, (125,125,255), ip, 4, 2) dist = int(distance(ip,self.rect.center)) self.probes[idx] = min(dist, self.probes[idx]) if dist < 1.2 * self.speed or self.speed < 0.01 : diff --git a/genetics.py b/genetics.py index 5653284..7fd2754 100644 --- a/genetics.py +++ b/genetics.py @@ -1,28 +1,54 @@ import numpy as np import random from brain import Neural_Network -from params import MUTATION_RATE +from params import MUTATION_RATE, SELECTION_ALG, KWAY_TOURNAMENT_PLAYERS + +def kway_selection(brains, exclude=None): + tourn_pool = [] + best_play = None + if exclude : + brains = [x for x in brains if x != exclude] + for x in range(KWAY_TOURNAMENT_PLAYERS): + new_play = random.choice(brains) + while new_play in tourn_pool : + new_play = random.choice(brains) + if not best_play or best_play.fitness < new_play.fitness : + best_play = new_play + return best_play def genetic_selection(brains): - # tot_fitness = sum ([int(b.fitness) for b in brains]) - - # does not seem very optimized... TBR - # constitute a list where every brain is represented - # proportionnally to its relative fitness - wheel = [] - for b in brains : - wheel += [b] * b.fitness - - - tot_fitness = len(wheel) + parents_pool = [] half_pop = int(len(brains)/2) - # selection of pool/2 pair of parents to reproduce - parents_pool = [] - for _ in range(half_pop): - parents_pool.append([ - wheel[round(random.random()*tot_fitness)], - wheel[round(random.random()*tot_fitness)] + if SELECTION_ALG == "kway": + for x in range(half_pop) : + p1 = kway_selection(brains) + p2 = kway_selection(brains, exclude=p1) + parents_pool.append([ + p1, + p2 + ]) + + + + elif SELECTION_ALG == "roulette" : + # does not seem very optimized... TBR + # constitute a list where every brain is represented + # proportionnally to its relative fitness + wheel = [] + for b in brains : + wheel += [b] * b.fitness + + + tot_fitness = len(wheel) + + # selection of pool/2 pair of parents to reproduce + for _ in range(half_pop): + idx1 = round(random.random()*tot_fitness - 1) + idx2 = round(random.random()*tot_fitness - 1) + parents_pool.append([ + wheel[idx1], + wheel[idx2] ]) return parents_pool diff --git a/main.py b/main.py index 7c65fa7..4d0f403 100755 --- a/main.py +++ b/main.py @@ -62,8 +62,8 @@ def run_round(all_cars): all_cars.empty() for b in new_brains : all_cars.add(Car(brain=b)) - print("Waiting 5 secs before new run") - for x in range(10) : + print("Waiting before new run") + for x in range(1) : time.sleep(0.5) pygame.display.flip() diff --git a/params.py b/params.py index 7437585..d8ff346 100644 --- a/params.py +++ b/params.py @@ -7,14 +7,16 @@ GX = 1000 GY = 1000 CELL_COLOR = (80,80,80) CAR_SIZE = 20 -CAR_MAX_SPEED = 6 -CAR_MAX_FITNESS = 5000 +CAR_MAX_SPEED = 100 +CAR_MAX_FITNESS = 100 CAR_STEERING_FACTOR = 10 VISION_LENGTH = 60 VISION_SPAN = 35 # degrees THROTTLE_POWER = 3 MUTATION_RATE = 0.01 +SELECTION_ALG = "kway" # roulette +KWAY_TOURNAMENT_PLAYERS = 3 pygame.init() screen = pygame.display.set_mode((GX, GY), FLAGS)