Created
December 11, 2017 15:53
-
-
Save fedden/9f8420db981999bc24bf300a5b4b6137 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def create_random_population(size): | |
| return np.random.randint(10, size=(size, 8)) | |
| def get_fitness(dna): | |
| return (dna[0] + dna[1]) - (dna[2] + dna[3]) + (dna[4] + dna[5]) - (dna[6] + dna[7]) | |
| def mutate(dna, mutation_rate): | |
| for i in range(len(dna)): | |
| if np.random.random_sample() < mutation_rate: | |
| dna[i] = np.random.randint(10) | |
| return dna | |
| def crossover(dna1, dna2): | |
| new_dna = np.copy(dna1) | |
| indices = np.where(np.random.randint(2, size=new_dna.size)) | |
| new_dna[indices] = dna2[indices] | |
| return new_dna | |
| def run_experiments(population_size, | |
| mutation_rate, | |
| elitism, | |
| amount_iteration, | |
| amount_experiements): | |
| experiment_data = [] | |
| for experiment in range(amount_experiements): | |
| population = create_random_population(population_size) | |
| prev_fitness = -1 | |
| completed = False | |
| for iteration in range(amount_iterations): | |
| fitnesses = np.array([get_fitness(dna) for dna in population]) | |
| fitnesses_indices = fitnesses.argsort()[::-1] | |
| fitnesses_total = fitnesses.sum() | |
| sorted_fitnesses = fitnesses[fitnesses_indices] | |
| fitnesses_weighting = sorted_fitnesses / fitnesses_total | |
| fitnesses_weighting = np.maximum(0, fitnesses_weighting) | |
| fitnesses_weighting /= fitnesses_weighting.sum() | |
| sorted_population = population[fitnesses_indices] | |
| if sorted_fitnesses[0] > prev_fitness: | |
| print("iter:", iteration, "fitness:", sorted_fitnesses[0], "best solution:", sorted_population[0]) | |
| prev_fitness = sorted_fitnesses[0] | |
| # Done? | |
| if sorted_fitnesses[0] == 36: | |
| completed = True | |
| best_result = sorted_population[0] | |
| completed_iteration = iteration | |
| break | |
| amount_new = int((1 - elitism) * population_size) | |
| new_population = [] | |
| for _ in range(amount_new): | |
| i0 = np.random.choice(sorted_population.shape[0], p=fitnesses_weighting) | |
| i1 = np.random.choice(sorted_population.shape[0], p=fitnesses_weighting) | |
| new_dna = crossover(population[i0], population[i1]) | |
| new_dna = mutate(new_dna, mutation_rate) | |
| new_population.append(new_dna) | |
| amount_old = population_size - amount_new | |
| new_population = np.array(new_population + sorted_population[:amount_old].tolist()) | |
| assert new_population.shape == population.shape | |
| population = new_population | |
| if not completed: | |
| best_result = sorted_population[0] | |
| completed_iteration = iteration | |
| experiment_data.append((completed, completed_iteration, best_result)) | |
| return experiment_data | |
| population_size = 5000 | |
| mutation_rate = 1.0 | |
| amount_iterations = 1000 | |
| amount_experiments = 1 | |
| elitism = 0.1 | |
| data = run_experiments(population_size, | |
| mutation_rate, | |
| elitism, | |
| amount_iterations, | |
| amount_experiments) | |
| # Potential Output: | |
| # iter: 0 fitness: 27 best solution: [5 9 1 3 9 9 1 0] | |
| # iter: 3 fitness: 28 best solution: [9 9 0 4 6 9 0 1] | |
| # iter: 5 fitness: 29 best solution: [9 8 1 1 9 7 1 1] | |
| # iter: 19 fitness: 30 best solution: [8 9 3 0 8 9 0 1] | |
| # iter: 47 fitness: 31 best solution: [7 9 0 0 8 8 1 0] | |
| # iter: 156 fitness: 32 best solution: [8 9 1 1 9 9 1 0] | |
| # iter: 187 fitness: 35 best solution: [9 8 0 0 9 9 0 0] | |
| # iter: 521 fitness: 36 best solution: [9 9 0 0 9 9 0 0] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment