diff --git a/03_euler_gen_alg/__pycache__/utils.cpython-312.pyc b/03_euler_gen_alg/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000..e10f3cb Binary files /dev/null and b/03_euler_gen_alg/__pycache__/utils.cpython-312.pyc differ diff --git a/03_euler_gen_alg/main.py b/03_euler_gen_alg/main.py index 9dbd273..26926fa 100644 --- a/03_euler_gen_alg/main.py +++ b/03_euler_gen_alg/main.py @@ -17,27 +17,33 @@ import utils POPULATION_SIZE = 10 SELECTION_SIZE = (POPULATION_SIZE * 7) // 10 # 70% of population, rounded down for selection -CROSSOVER_PAIR_SIZE = (POPULATION_SIZE - SELECTION_SIZE) // 2 # pairs needed for crossover +XOVER_PAIR_SIZE = (POPULATION_SIZE - SELECTION_SIZE) // 2 # pairs needed for crossover XOVER_POINT = 3 # 4th position MUTATION_BITS = POPULATION_SIZE * 1 -fitness = 0.01 -pop_grey = [] -pop_bin = [] # 32 Bit Binary -pop_bin_params = [] -pop_new = [] # 32 Bit Grey-Code as String +fitness = 1 +grey_pop = [] +bin_pop = [] # 32 Bit Binary +bin_pop_params = [] +new_pop = [] # 32 Bit Grey-Code as String e_func = lambda x: np.e**x -def generate_random_population(): +def generate_random_population(num=POPULATION_SIZE): """ Puts random 32 Bit binary strings into 4 * 8 Bit long params. """ - # Random population array - for i in range(POPULATION_SIZE): - pop_grey[i] = format(random.getrandbits(32), '32b') - pop_bin[i] = utils.grey_to_bin(pop_grey[i]) - pop_bin_params[i] = [pop_bin[i][0:7], pop_bin[i][8:15], pop_bin[i][16:23], pop_bin[i][24:31]] + + # Generate new population + for _ in range(num): + grey = format(random.getrandbits(32), '32b') + grey_pop.append(grey) + + bin_str = utils.grey_to_bin(grey) + bin_pop.append(bin_str) + + params = [bin_str[i:i+7] for i in range(0, 31, 8)] + bin_pop_params.append(params) - return pop_bin_params + return bin_pop_params def quadratic_error(original_fn, approx_fn, n): error = 0.0 @@ -47,10 +53,10 @@ def quadratic_error(original_fn, approx_fn, n): return error -def eval_fitness(pop_bin_values): +def eval_fitness(bin_pop_values): """ Returns an array with fitness value of every individual in a population. """ fitness_arr = [] - for params in pop_bin_values: + for params in bin_pop_values: # Convert binary string to parameters for bin_values a, b, c, d = [utils.bin_to_param(param) for param in params] # assign params to batch of population @@ -60,7 +66,7 @@ def eval_fitness(pop_bin_values): print(fitness) # debugging fitness_arr.append(fitness) # save fitness - # save params # already saved in pop_grey + # save params # already saved in grey_pop return fitness_arr @@ -76,7 +82,7 @@ def select(population, fitness_arr): cumulative_p += fitness / sum_of_fitness if roulette_num < cumulative_p: # Add the 32 Bit individual in grey code to population - population.append(pop_grey[i]) + population.append(grey_pop[i]) # Calc new sum of fitness fitness_arr.pop(i) @@ -84,12 +90,13 @@ def select(population, fitness_arr): is_chosen = True # break while loop break # break for loop + return population -def xover(population, xover_rate): +def xover(population, xover_rate=XOVER_PAIR_SIZE): """Performs crossover on pairs of individuals from population.""" offspring = [] - # Process pairs while we have enough individuals and haven't reached CROSSOVER_PAIR_SIZE + # Process pairs while we have enough individuals and haven't reached xover_rate pair_count = 0 i = 0 while i < len(population) - 1 and pair_count < xover_rate: @@ -118,26 +125,34 @@ def mutate(population, mutation_rate): bits[bit_pos] = '1' if bits[bit_pos] == '0' else '0' # Convert back to string and update population - population[random_num] = ''.join(bits) + population[random_num] = ''.join(bits) # will work because lists are passed by reference def main(): - pop_bin_values = generate_random_population(10) + bin_pop_values = generate_random_population(POPULATION_SIZE) + print(bin_pop_values) while fitness > 0.01: - # Evaluate fitness - fitness_arr = eval_fitness(pop_bin_values) - + fitness_arr = eval_fitness(bin_pop_values) + # Selection - select(pop_new, fitness_arr) # Alters pop_new + new_pop = select(new_pop, fitness_arr) # Alters new_pop + print(new_pop) + time.sleep(1) - # Crossover - offspring = xover(pop_new, CROSSOVER_PAIR_SIZE) - pop_new.extend(offspring) # .extend needed + """# Crossover + offspring = xover(new_pop, XOVER_PAIR_SIZE) + new_pop.extend(offspring) # .extend needed # Mutation - mutate(pop_new, MUTATION_BITS) + mutate(new_pop, MUTATION_BITS) - pop_grey = pop_new + # Update populations for next generation + grey_pop = new_pop.copy() + bin_pop_values = [] + for grey_bin_string in grey_pop: + bin_str = utils.grey_to_bin(grey_bin_string) + params = [bin_str[i:i+7] for i in range(0, 31, 8)] + bin_pop_values.append(params)""" return 0 if __name__ == "__main__":