Skip to content

Commit 2eb7f22

Browse files
author
Louis Weyland
committed
- updated
1 parent ecfa203 commit 2eb7f22

File tree

4 files changed

+94
-13
lines changed

4 files changed

+94
-13
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,23 @@ Gathering the required packages
4646
pip3 install -r requirements.txt
4747
```
4848
The code for the model is located in `src/lattice.py` and the graphs can be generated by calling the different functions in `src/main.py`. The file `results_presentation.ipynb` that was used to create the presentation of this project shows how the result figures as shown above can be generated.
49-
49+
Running the lattice.py function in the bash shell will create a Bak-Sneppen model with a grid size of 20X20
50+
and will plot the average fitness, avalanche time,the cluster size distribution and
51+
a visualisation of the grid itself
52+
```
53+
./lattice.py
54+
```
55+
In the file main.py various statistical analysis are generated. The various function can
56+
be called using the following command where itr represent the number of steps in
57+
the Bak-Sneppen Model.
58+
```
59+
./main.py -func function_example -itr=200
60+
```
61+
For further details please run the following command which shows which function
62+
can be called and what other paramters can be tuned from the command line
63+
```
64+
./main.py --help
65+
```
5066
Generating the presentation from the `results_presentation.ipynb` Jupyter notebook
5167
```
5268
jupyter nbconvert results_presentation.ipynb --to slides --post serve
-1.53 KB
Loading

src/lattice.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
Created on Tuesday June 16 2020
66
This code was implemented by
77
Louis Weyland, Hildebert Mouilé, Philippe Nicolau & Binjie Zhou.
8+
This code creates a Networkx object incorporating the Bak-Sneppen model
89
"""
910

1011
from os import path
@@ -27,7 +28,6 @@
2728
from pylab import arange
2829
from scipy.ndimage import measurements
2930
import matplotlib.animation as animation
30-
import seaborn as sns
3131

3232
# Automatically setting the local path to this repo for easy file writing and saving
3333
dir_path = path.dirname(path.realpath(__file__))
@@ -252,7 +252,8 @@ def mutation(self):
252252

253253
def move(self):
254254
"""
255-
The node with lowest fitness get moved to free place when the mean fitness of its neighbors is above the total average while lower than new neighbors
255+
The node with lowest fitness get moved to free place when the mean fitness
256+
of its neighbors is above the total average while lower than new neighbors
256257
"""
257258
free_nodes = list(dict(filter(lambda elem: elem[1], self.free_dict.items())).keys())
258259
shuffle(free_nodes)
@@ -391,7 +392,7 @@ def run(self, things_to_collect):
391392

392393
def plot(self, label='fitness'):
393394
"""
394-
Visualise the graph and plot labels it labels = True
395+
Visualise the graph with the respective attribute fitness or age
395396
"""
396397
if label == 'fitness':
397398
values = set(self.fitness_dict.values())

src/main.py

100644100755
Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,39 @@
2323
import powerlaw
2424
import warnings
2525
import matplotlib.patches as mpatches
26-
import seaborn as sns
26+
import argparse
27+
from termcolor import colored
2728

2829
# Automatically setting the local path to this repo for easy file writing and saving
2930
dir_path = path.dirname(path.realpath(__file__))
3031
# Only keep the warnings printed in the output
3132
warnings.filterwarnings("ignore")
3233

3334

35+
36+
37+
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
38+
description='Uses the lattice object from lattice.py to perform different experiments.\n\
39+
Call functions by their name!\n\
40+
func \'comp_average_fitness\' runs the model and plots the evolution of average fitness and the threshold at the end\n\
41+
func \'comp_avalanche_time\' compares the avalanche time between fintess generated unifromly or by the gaussin random generator\n\
42+
func \'comp_mutation_dist\' compares the distribution of the distance between mutations for models using gaussin/uniform random generator\n\
43+
func \'is_free_variation\' compares the impact of the density on the avalanche time \n\
44+
func \'comp_cluster_sizes\' compares the cluster size distribution for different grid sizes \n\
45+
func \'comp_moving_vs_stationary\' compares the cluster sizes and avalanche time between a \n\
46+
func \'comp_diff_dim\' the cluster size for 2D/3D model \n\
47+
func \'get_fitness_dist\' the fitness distribution after n iterations ')
48+
49+
50+
51+
parser.add_argument("-func",type = str, help='Defines which function to execute')
52+
parser.add_argument('-itr', type=int,default=200, help='Number of iteration for the model (default : 50)')
53+
parser.add_argument('-rep', type=int,default=10, help='Number of repetition (default : 10)')
54+
parser.add_argument('-std', type=float,default=0.3, help='Standard deviation for gaussian random generator (default : 0.3)')
55+
parser=parser.parse_args()
56+
57+
58+
3459
def print_statement(alpha, r, p, name):
3560

3661
print("The slope of {} disrtibution is {}".format(name, round(alpha, 4)))
@@ -42,7 +67,8 @@ def print_statement(alpha, r, p, name):
4267

4368
def comp_average_fitness(size=(20, 20), iteration=2000, repetition=10, std=0.3):
4469
"""
45-
Plots the average fitness for different distribution and the threshold
70+
Plots the average fitness for different distribution and the threshold for a model
71+
using uniform/gaussian random generator
4672
:param : number of iterations, number of repetition and standard deviation for gaussian distribution
4773
"""
4874

@@ -104,7 +130,7 @@ def comp_average_fitness(size=(20, 20), iteration=2000, repetition=10, std=0.3):
104130

105131
def comp_avalanche_time(size=(20, 20), iteration=2000, repetition=10, std=0.2):
106132
"""
107-
Plots the avalanche distribution in a log-log plot
133+
Plots the avalanche distribution in a log-log plot for a model using uniform/gaussian random generator
108134
:param : number of iterations, number of repetition and standard deviation for gaussian distribution
109135
110136
"""
@@ -158,7 +184,7 @@ def comp_avalanche_time(size=(20, 20), iteration=2000, repetition=10, std=0.2):
158184

159185
def comp_mutation_dist(size=(20, 20), iteration=2000, repetition=10, std=0.2):
160186
"""
161-
Plots the distribution between distances between mutations
187+
Plots the distribution between distances between mutations for a model using uniform/gaussian random generator
162188
:param : size of the grid,number of iterations, number of repetition and standard deviation for gaussian distribution
163189
"""
164190

@@ -215,7 +241,7 @@ def comp_mutation_dist(size=(20, 20), iteration=2000, repetition=10, std=0.2):
215241

216242
def comp_diff_neighbours(size=(20, 20), iteration=2000, repetition=10):
217243
"""
218-
Plots the avalanche distribution in a log-log plot
244+
Plots the avalanche distribution in a log-log plot for a model using Moore/van Neumann Neighbourhood
219245
:param : number of iterations, number of repetition and standard deviation for gaussian distribution
220246
221247
"""
@@ -388,7 +414,13 @@ def is_free_variation(i_min=0, i_max=1, i_iter=6, iterations=2000):
388414

389415

390416
def comp_cluster_sizes(iterations=2000):
391-
# Compares the cluster sizes of different sizes of grid
417+
"""
418+
Compares the cluster sizes of different sizes of grid using uniform random generator for the fitness
419+
:param iterations: number of steps to run for the Bak-Sneppen model
420+
"""
421+
422+
423+
print(colored("Warning this function might take long (2000 itr ~ 40 min)",'red'))
392424

393425
small = Lattice(size=(20, 20), torus_mode=True, rand_dist=('uniform',), free_percent=0, iterations=iterations,
394426
age_fraction=1 / 10)
@@ -437,8 +469,9 @@ def comp_cluster_sizes(iterations=2000):
437469

438470
def comp_moving_vs_stationary(size=(20, 20), iteration=2000, repetition=10):
439471
"""
440-
Compares the cluster sizes and avalanche time
441-
472+
Compares the cluster sizes and avalanche time between a stationary model and a model where the nodes
473+
can move to free space
474+
:param : number of iterations, number of repetition and standard deviation for gaussian distribution
442475
"""
443476
# Get a comparison between the different random distribution
444477
iterations = iteration
@@ -493,7 +526,7 @@ def comp_moving_vs_stationary(size=(20, 20), iteration=2000, repetition=10):
493526

494527
def comp_diff_dim(iterations=2000):
495528
"""
496-
Compares
529+
Compares the cluster size distribution for 2 Dimensions and 3 Dimensions
497530
"""
498531
# Compares the cluster sizes of different sizes of grid
499532

@@ -552,3 +585,34 @@ def get_fitness_dist(iterations=20000):
552585
plt.legend()
553586
plt.savefig(path.join(dir_path, 'figures/fitness_distance_itr={}.png'.format(iterations)), dpi=300)
554587
plt.show()
588+
589+
590+
591+
592+
if len(sys.argv) >= 1:
593+
594+
if parser.func == 'comp_average_fitness':
595+
comp_average_fitness(iteration = parser.itr,repetition =parser.rep,std= parser.std)
596+
597+
elif parser.func == 'comp_average_fitness':
598+
comp_average_fitness(iteration = parser.itr,repetition =parser.rep,std= parser.std)
599+
600+
elif parser.func == 'comp_avalanche_time':
601+
comp_avalanche_time(iteration = parser.itr,repetition =parser.rep,std= parser.std)
602+
603+
elif parser.func == 'comp_mutation_dist' :
604+
comp_mutation_dist(iteration = parser.itr,repetition =parser.rep,std= parser.std)
605+
elif parser.func == 'is_free_variation' :
606+
is_free_variation(iterations = parser.itr)
607+
608+
elif parser.func == 'comp_cluster_sizes':
609+
comp_cluster_sizes(iterations = parser.itr)
610+
611+
elif parser.func == 'comp_moving_vs_stationary':
612+
comp_moving_vs_stationary(iteration = parser.itr,repetition =parser.rep)
613+
614+
elif parser.func == 'comp_diff_dim':
615+
comp_diff_dim(iterations = parser.itr)
616+
617+
elif parser.func == 'get_fitness_dist':
618+
get_fitness_dist(iterations = parser.itr)

0 commit comments

Comments
 (0)