Skip to content

Commit

Permalink
all
Browse files Browse the repository at this point in the history
  • Loading branch information
basil-cow committed Sep 29, 2018
1 parent 818f333 commit 0d1f503
Show file tree
Hide file tree
Showing 4 changed files with 472 additions and 78 deletions.
76 changes: 63 additions & 13 deletions evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import multiprocessing
import itertools
from statistics import mean
from math import exp
import math


def can_connect(bacteria, plant, neural_net, threshold):
Expand All @@ -11,7 +13,6 @@ def can_connect(bacteria, plant, neural_net, threshold):
return True
return False


def ev_basic(bacteria_pop, plant_pop, neural_net, threshold):
new_bacteria_pop = copy.deepcopy(bacteria_pop)
new_plant_pop = copy.deepcopy(plant_pop)
Expand All @@ -36,30 +37,79 @@ def ev_basic(bacteria_pop, plant_pop, neural_net, threshold):
new_plant_pop = list(np.random.choice(new_plant_pop, len(plant_pop), False))
return [new_bacteria_pop, new_plant_pop]

def get_probs(mean_dists):
probs = np.array([(10 - 9 * (x ** 0.5)) if x < 1 else 1 for x in mean_dists])
#probs = np.array([0.7 + exp(-x) for x in mean_dists])
probs = probs / sum(probs)
return probs

def ev_pooling(bacteria_pop, plant_pop, transformed_genes):
def ev_stochastic(bacteria_pop, plant_pop, t_bact_genes, t_plant_genes):
new_bacteria_pop = copy.deepcopy(bacteria_pop)
new_plant_pop = []
# copy.deepcopy(plant_pop)
new_bacteria_pop.extend([bacteria.offspring() for bacteria in bacteria_pop])
new_plant_pop.extend([plant.offspring() for plant in plant_pop])

new_bacteria_pop = list(np.random.choice(new_bacteria_pop, len(bacteria_pop), False))
new_plant_pop_ind = list(np.random.choice(range(len(plant_pop)), len(plant_pop), True))
new_plant_pop = [plant_pop[i].offspring() for i in new_plant_pop_ind]

return new_bacteria_pop, new_plant_pop, 0

def ev_pooling(bacteria_pop, plant_pop, t_bact_genes, t_plant_genes):
new_bacteria_pop = copy.deepcopy(bacteria_pop)
# new_plant_pop = copy.deepcopy(plant_pop)
new_bacteria_pop.extend([bacteria.offspring() for bacteria in bacteria_pop])
# new_plant_pop.extend([plant.offspring() for plant in plant_pop])

close_bact_num = 3
reproduction_bonus = 3

pool_size = len(bacteria_pop) // len(plant_pop)
mean_dists = []
for i in range(len(plant_pop)):
slc = [-np.linalg.norm(gene - plant_pop[i].gene)
for gene in transformed_genes[pool_size * i:pool_size * (i + 1)]]
ind = np.argpartition(slc, -4)[-4:]
slc = [np.linalg.norm(gene - t_plant_genes[i])
for gene in t_bact_genes[pool_size * i:pool_size * (i + 1)]]
ind = list(np.argpartition(slc, close_bact_num)[:close_bact_num])
mean_dist = 0.0
for x in ind:
mean_dist += -slc[x]
mean_dists.append(mean_dist / 4)
mean_dists.append(mean_dist / len(ind))
# ind = np.random.randint(0, pool_size, 5)
indices = [pool_size * i + j for j in ind]
indices = [pool_size * i + j for j in ind if slc[x] < 1] #remove

for j in indices:
new_bacteria_pop.extend(bacteria_pop[j].offspring() for _ in range(4))
new_bacteria_pop.extend(bacteria_pop[j].offspring() for _ in range(reproduction_bonus))

probs = get_probs(mean_dists)
new_bacteria_pop = list(np.random.choice(new_bacteria_pop, len(bacteria_pop), False))
new_plant_pop = list(np.random.choice(new_plant_pop, len(plant_pop), False))
return new_bacteria_pop, new_plant_pop, mean(mean_dists)
new_plant_pop_ind = list(np.random.choice(range(len(plant_pop)), len(plant_pop), True, p=probs))
new_plant_pop = [plant_pop[i].offspring() for i in new_plant_pop_ind]

return new_bacteria_pop, new_plant_pop, np.mean(mean_dists)

def glob_disaster(population, pop_genes, cls):
org_ind = np.random.randint(0, len(population))
surv_pop_size = int(0.1 * len(population))
dists = [np.linalg.norm(pop_genes[i] - pop_genes[org_ind]) for i in range(len(population))]
inds = list(np.argpartition(dists, surv_pop_size)[:surv_pop_size])
new_pop = [population[i] for i in inds]

inds = np.random.randint(0, surv_pop_size, len(population) - surv_pop_size)
for i in range(len(population) - surv_pop_size):
new_pop.append(new_pop[inds[i]].offspring())

return new_pop


def local_surv(population, pop_genes, cls):
org_ind = np.random.randint(0, len(population))
surv_pop_size = int(0.5 * len(population))

new_pop = list(np.random.choice(population, surv_pop_size))

vec = np.random.random(len(pop_genes[0]))
vec = vec / np.linalg.norm(vec) * np.random.normal(0, 0.001 * 20)

new_gene = pop_genes[0] + vec

new_pop = new_pop + [cls(new_gene, [], cls.last_id + 1) for _ in range(len(population) - surv_pop_size)]

return new_pop
174 changes: 128 additions & 46 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,55 +10,124 @@
import fourier
import utils
import multiprocessing
import os.path
import os
import matplotlib
import inspect
import collections
import scipy.spatial

def simulate_float(pop_sizes, gene_sizes, generations, mut_params,
ev_alg=evolution.ev_basic, fitness=None, generator=utils.gen_random,statistics_func=[],
def simulate_float(pop_sizes, gene_sizes, inter_size, generations, mut_params,
ev_alg=evolution.ev_basic, bact_fitness=None, plant_fitness=None,
generator=utils.gen_random,
init_seed=0, ev_seed=0, n_threads=1):
Bacteria.mut_v = mut_params[0][0]
Bacteria.mut_m = mut_params[0][1]
Plant.mut_v = mut_params[1][0]
Plant.mut_m = mut_params[1][1]

if fitness is None:
fitness = nnet.NeuralNetFitness(*gene_sizes)
bacteria_pop, plant_pop = generator(pop_sizes, fitness)
dist_epochs = 100
Bacteria.dist_epochs = dist_epochs
Plant.dist_epochs = dist_epochs

cnt = 0
#try to generate populations with necesserary distance between them
while (1):
cnt += 1
bacteria_pop, plant_pop = generator(pop_sizes, gene_sizes)
d = np.linalg.norm(bact_fitness.run(bacteria_pop[0].gene) - plant_fitness.run(plant_pop[0].gene))
if ((d > 1.26 and d < 1.36) or cnt > 100000):
break
np.random.seed(init_seed)
if (generator == utils.gen_same_bacteria):
ancestral = copy.deepcopy(bacteria_pop[0])

one_percent = max(1, generations // 100)
time_sum = 0

np.random.seed(ev_seed)
stat_res = [[] for _ in range(len(statistics_func))]
print(1)
mean_dist = 8
picname = os.path.join("pic", str(mut_params) + "_" + str(ev_seed))
if not os.path.exists(picname):
os.mkdir(picname)
print(picname)

probs_lines = inspect.getsource(evolution.get_probs)

bact_db, plant_db = dict(), dict()
t_bact_db, t_plant_db = dict(), dict()

fout = open(os.path.join(picname, "statistics.txt"), "w")
print("bact_speed", "plant_speed", "inter_sim", "bact_div", "plant_div", "bact_ent", "plant_ent", file = fout)

print(np.linalg.norm(bact_fitness.run(bacteria_pop[0].gene) - plant_fitness.run(plant_pop[0].gene)))

dlog = open(os.path.join(picname, "log.txt"), "w")

for epoch in range(generations):
start_time = time.time()
bacteria_genes = [bacteria.gene for bacteria in bacteria_pop]
print(epoch)

bact_db, plant_db = utils.update_db(bacteria_pop, plant_pop, bact_db, plant_db, epoch, dist_epochs)
b_d, p_d = utils.normed_distance_db(bacteria_pop, plant_pop, bact_db, plant_db)
print(b_d, file = fout, end = " ")
print(p_d, file = fout, end = " ")

bact_genes = np.array([bacteria.gene for bacteria in bacteria_pop])
plant_genes = np.array([plant.gene for plant in plant_pop])
t_bact_genes, t_bact_db = utils.update_t_db(bacteria_pop, t_bact_db, bact_fitness, epoch)
t_plant_genes, t_plant_db = utils.update_t_db(plant_pop, t_plant_db, plant_fitness, epoch)

t_b_probs, t_p_probs = utils.inter_labeling(t_bact_genes, t_plant_genes, 12)
b_probs, p_probs = utils.intra_labeling(bact_genes, 12), utils.intra_labeling(plant_genes, 12)

inter_dist = utils.hell_dist(t_b_probs, t_p_probs)
print(inter_dist, file = fout, end = " ")

bact_div, plant_div = utils.mc_diversity(bacteria_pop, 10000), utils.mc_diversity(plant_pop, 10000)
print(bact_div, file = fout, end = " ")
print(plant_div, file = fout, end = " ")

bact_ent, plant_ent = utils.pop_entropy(b_probs), utils.pop_entropy(p_probs)
print(bact_ent, file = fout, end = " ")
print(plant_ent, file = fout)

transformed_genes = [fitness.run(gene) for gene in bacteria_genes]
utils.flush_file(fout)

if epoch % 50 == 0:
for j in range(len(statistics_func)):
stat_res[j].append(statistics_func[j](**locals()))
print(Bacteria.mut_v, Bacteria.mut_m, Plant.mut_v, Plant.mut_m)
if (inter_size == 2):
utils.save_2d(t_bact_genes, t_plant_genes, epoch, picname, str(gene_sizes) + " " + str(pop_sizes) + " " + str(mut_params) + "\n" + probs_lines)

bacteria_pop, plant_pop, mean_dist = ev_alg(bacteria_pop, plant_pop, t_bact_genes, t_plant_genes)

if (epoch % 1000 == 0 and epoch != 0):
orgType = np.random.randint(0, 2)
funcType = np.random.randint(0, 2)

funcTypes = [evolution.glob_disaster, evolution.local_surv]
orgPops = [bacteria_pop, plant_pop]
orgCls = [Bacteria, Plant]
orgName = ["bacteria", "plant"]
funcName = ["disaster", "local_surv"]

print(epoch, funcName[funcType], orgName[orgType], file=dlog)
if (orgType == 0):
bacteria_pop = funcTypes[funcType](bacteria_pop, bact_genes, Bacteria)
else:
plant_pop = funcTypes[funcType](plant_pop, plant_genes, Plant)

utils.flush_file(dlog)

bacteria_pop, plant_pop, mean_dist = ev_alg(bacteria_pop, plant_pop, transformed_genes)
elapsed = time.time() - start_time
time_sum += elapsed
if epoch % one_percent == 0:
print(str(int(((epoch + 1) / generations * 100))) + str("%"), end=" ")
print("%0.3f" % (time_sum / (epoch + 1) * (generations - epoch - 1)))

bacteria_genes = [bacteria.gene for bacteria in bacteria_pop]
transformed_genes = [fitness.run(gene) for gene in bacteria_genes]
for j in range(len(statistics_func)):
stat_res[j].append(statistics_func[j](**locals()))
print(str(int(((epoch + 1) / generations * 100))) + str("%"), end=" ")
print("%0.3f" % (time_sum / (epoch + 1) * (generations - epoch - 1)))

t_bact_genes = np.array([bact_fitness.run(bacteria.gene) for bacteria in bacteria_pop])
t_plant_genes = np.array([plant_fitness.run(plant.gene) for plant in plant_pop])


return [np.array([bacteria.gene for bacteria in bacteria_pop]),
np.array(transformed_genes),
np.array([plant.gene for plant in plant_pop])], stat_res
t_bact_genes, t_plant_genes,
np.array([plant.gene for plant in plant_pop])]

def print_to_csv(mut_params, statistics, ev_seed, statistics_desc):
stat_transposed = [np.array(i).T for i in statistics]
Expand All @@ -68,30 +137,43 @@ def print_to_csv(mut_params, statistics, ev_seed, statistics_desc):
np.savetxt(name, stat_to_csv.T, delimiter=',', fmt="%.10f", header="epoch," + ",".join(statistics_desc))

def run_proc(b_mut_m, p_mut_m, id):
mut = ((0.004, b_mut_m), (0.04, p_mut_m))
bacteria_pop_size = 10000
plant_pop_size = 50
gene_sizes = (20, 20)
generations = 500
statistics_func = [utils.stat_av_dist_to_anc, utils.stat_av_dist_to_closest, utils.stat_plant_percentage,
utils.stat_mean_dist]
statistics_desc = ["mean dist to ancestor bacteria", "mean dist to closest plant", "percentage of reacting plants",
"mean dist to own bacteria"]
statistics_ylabels = ["distance", "distance", "percentage", "distance"]
np.random.seed(30)
cnt = int(10 * b_mut_m + 10 * p_mut_m * id * 1000)
print(cnt)
mut = ((0.05, b_mut_m), (0.05, p_mut_m))
bacteria_pop_size = 100000
plant_pop_size = 1000
gene_sizes = (5, 5)
inter_size = 2
generations = 10001

seed = int(id + b_mut_m * 1000 + p_mut_m * 1000000)
np.random.seed(seed)

#pop_sizes - population sizes
#mut_params - pair of (variation, probabilty) for both species
#inter_size - common space dimension number
#gene_size - gene space dimension sizes
#ev_alg - function, that calculates next generations based on previous generation
#bact_plant_fitness - fitness functions
#generator - function that generates fiest generation
#insit_seed - generator random seed
#ev_seed - evolution random seed

simulation_results = simulate_float(pop_sizes=(bacteria_pop_size, plant_pop_size),
mut_params=mut,
mut_params=mut, inter_size=inter_size,
gene_sizes=gene_sizes, generations=generations, ev_alg=evolution.ev_pooling,
fitness=fourier.FourierFitness(gene_sizes, alpha=1.5, tau=1, func_num=30),
bact_fitness=fourier.FourierFitness((gene_sizes[0], inter_size), alpha=1.2, tau=1, func_num=30),
plant_fitness=fourier.FourierFitness((gene_sizes[1], inter_size), alpha=1.2, tau=1, func_num=30),
generator=utils.gen_same_bacteria,
statistics_func=statistics_func,
init_seed=30, ev_seed=cnt)
print_to_csv(mut, simulation_results[1], cnt, statistics_desc)
init_seed=seed, ev_seed=seed)

if __name__ == "__main__":
hyperlul = list(itertools.product([0.1, 0.2, 0.4], [0.1, 0.2, 0.4], [6, 7]))
with multiprocessing.Pool(2) as workers:
workers.starmap(run_proc, hyperlul)
for i in range(30):
f = fourier.FourierFitness((4, 2), alpha=1.2, tau=1, func_num=30)
utils.fitness_vis(f, 4, 2, "fvis" + str(i) + ".svg")

#multiprocessing support

#hyperlul = list(itertools.product([0.08], [0.08], list(map(float, range(10, 16)))))

#with multiprocessing.Pool(6) as workers:
# workers.starmap(run_proc, hyperlul)
#run_proc(0.05, 0.05, 1)
Loading

0 comments on commit 0d1f503

Please sign in to comment.