def simulate(population_size: int, num_generations: int, folder_name="test"): if os.path.exists(f"sim/x_rmg/{folder_name}"): raise Exception("Folder exists") else: os.makedirs(f"sim/x_rmg/{folder_name}") population = [] for _ in range(population_size): population.append(Organism()) for generation_number in range(1, num_generations + 1): found_no_loss = False to_mate = select(make_wheel(population), population_size // 2) after_mating = population_after_mating(to_mate) after_mutation = population_after_mutation(after_mating) population = next_generation(population, after_mating, after_mutation, population_size) with open(f"sim/x_rmg/{folder_name}/{generation_number}.csv", "w") as file: file.write("Genome, Fitness, Wins (X), Losses (X), Draws (X)\n") for organism in population: if organism.get_fitness() == 0: found_no_loss = True file.write( f"{organism.genome}, {organism.get_fitness()}, {organism.win_x}, {organism.loss_x}, {organism.draw_x}\n" ) print(population[0].get_fitness()) if found_no_loss: return population return population
def next_generation(population_before_selection, population_after_mating, population_after_mutation, population_size=100): UMG = UnbeatableMoveGenerator(2) combined_list = [] for organism in population_before_selection: insort(combined_list, (mg_result(organism, UMG), organism)) for organism in population_after_mating: insort(combined_list, (mg_result(organism, UMG), organism)) for organism in population_after_mutation: insort(combined_list, (mg_result(organism, UMG), organism)) ret_list = [] for i in range(1, population_size + 1): j = int(i + (2 * population_size) * (((i - 1) * (i - 2)) / ((population_size - 1) * (population_size - 2)))) ret_list.append(combined_list[j - 1][1]) return sorted(ret_list) if __name__ == "__main__": print( next_generation( [Organism(), Organism(), Organism()], [Organism(), Organism(), Organism()], [Organism(), Organism(), Organism()], 3))
def fitness(organism: Organism, m: int): if m == 0: return 1 - organism.get_fitness() else: return (1 / m) * (1 - organism.get_fitness())
def bin_search(wheel, num): mid = len(wheel) // 2 low, high, answer = wheel[mid] if low <= num <= high: return answer elif high < num: return bin_search(wheel[mid + 1:], num) else: return bin_search(wheel[:mid], num) def select(wheel, N): stepSize = 1.0 / N answer = [] r = random.random() answer.append(bin_search(wheel, r)) while len(answer) < N: r += stepSize if r > 1: r %= 1 answer.append(bin_search(wheel, r)) return answer if __name__ == "__main__": pop = [] for i in range(10): pop.append(Organism()) print(select(make_wheel(pop), 2))