-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevolutionary_model_more_players.py
140 lines (108 loc) · 5.33 KB
/
evolutionary_model_more_players.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from fisherman import *
from fish_stock import *
from simulation_of_fish import update_effort
from plot_functions import *
from simulation_config import *
import numpy as np
import matplotlib.pyplot as plt
import warnings
import random
import sys
import copy
def evolutionary_dynamics(population_size,
mutation_rate=MUTATION_RATE,
#t_max=500,
n_generations = MAX_SIM_TIME,
crossover=False):
effort_max = EFFORT_MAX
effort_min = EFFORT_MIN
effort_resolution = 2
step_size = (effort_max - effort_min) / population_size
efforts = [step_size * ii for ii in range(population_size)]
efforts = np.round(efforts, effort_resolution)
base_effort = 1.0 / population_size
genes = [[(np.random.rand() - 0.5) * 6, (np.random.rand() - 0.5) * 6] for ii in range(population_size)]
# init population
population = [Fisherman(gene=genes[i]) for i in range(population_size)]
population_fitness = {population[ii]:INIT_POP_FITNESS for ii in range(population_size)}# keeps track of the number
# of individuals of each genotype
# init fish stock
stock = FishStock(init_stock_size=5000)
stock.X_history.append(stock.X)
for t in range(n_generations):
# check that population and counter is consistent
if len(population) != len(population_fitness):
import pdb; pdb.set_trace()
raise Exception('population and population_fitness inconsistent')
# update efforts depending on others effort at t-1
update_effort(stock=stock, list_of_fishers=population)
for fisher in population:
population_fitness[fisher] += -1
# update harvest for every fisher and change stock size
stock.fish_stock_change_update_fisher_harvest(population)
stock.X_history.append(stock.X)
if stock.X < 1.0:
print(f'Stock depleated at {t}')
break
# calculate profit
profits = [fisher.calculate_profit() for fisher in population]
population, population_fitness = calc_new_population(profits, population, population_fitness, stock, effort_resolution)
if len(population) < 2:
import pdb; pdb.set_trace()
pass
sys.stdout.write(f'\r generation: {t}\t nof species: {len(population)}')
sys.stdout.flush()
plot_histogram(population, population_fitness, t, stock)
print('done')
def calc_new_population(profits, population, population_fitness,
stock, effort_resolution, mutation_rate=MUTATION_RATE):
scaling_factor = POPULATION_SCALING_FACTOR
sigma = MUTATION_VARIANCE
nbr_players = len(population)
profits_mean = np.mean(profits)
for i, fisher in enumerate(population):
# calculate steady state if all players played like fisher i
steady_all_fisher_i = stock.carrying_cap*(1-(stock.catch_coeff/stock.growth_rate)*fisher.effort*nbr_players)
population_fitness[fisher] += int(scaling_factor*(fisher.profit - profits_mean) +
(0.2*min(steady_all_fisher_i, 0)))
fisher.population_history.append(population_fitness[fisher])
p = max(len(population)//10, 1)
pop_fitness_list = [population_fitness[fisher] for fisher in population]
mean_fitness = np.mean(pop_fitness_list)
fitness_sort_idx = np.argsort(pop_fitness_list)
for idx in range(p):
good_fisher = copy.deepcopy(population[fitness_sort_idx[-(idx + 1)]])
good_fisher.gene[0] += np.round(sigma * np.random.randn(), effort_resolution)
good_fisher.gene[1] += np.round(sigma * np.random.randn(), effort_resolution)
population_fitness[good_fisher] = population_fitness[population[idx]]
shit_fisher = population[fitness_sort_idx[idx]]
del population_fitness[shit_fisher]
population.remove(shit_fisher)
population.append(good_fisher)
for idx in range(p, nbr_players - p):
if np.random.random() < mutation_rate:
population[idx].gene[0] += np.round(sigma * np.random.randn(), effort_resolution)
population[idx].gene[1] += np.round(sigma * np.random.randn(), effort_resolution)
if len(population) != len(population_fitness):
import pdb; pdb.set_trace()
raise Exception('population and population_fitness inconsistent')
# population, population_fitness = mutate_population(population, population_fitness)
return population, population_fitness
def mutate_population(population, population_fitness, mutation_rate=MUTATION_RATE):
sigma = 0.5
new_fishers = []
for fisher in population:
if random.random() < mutation_rate:
new_fisher = copy.deepcopy(fisher)
new_fisher.gene[0] += np.round(sigma * np.random.randn(), 2)
# if random.random() < mutation_rate:
new_fisher.gene[1] += np.round(sigma * np.random.randn(), 2)
new_fishers.append(new_fisher)
population += new_fishers
for fisher in new_fishers:
population_fitness[fisher] = INIT_POP_FITNESS
return population, population_fitness
if __name__ == '__main__':
initialize_plot()
evolutionary_dynamics(POPULATION_SIZE)
plt.show()