Agent-based modelling, Konstanz, 2024
25 June 2024
rand([])
rand([])
try ... catch ... end
block:Trying to draw from an empty container!
try
and catch
keywordscatch
and end
keywords is executed, without crashingrandom_nearby_agent
returned the 8 agents surrounding agent
in the GridSpace
random_nearby_agent
also has a method for GraphSpace
sstep!
function from Agents.jl to evolve our modelrun!
and ensemblerun!
run!
to collect datarun!
is like step!
, except it also collects the model’s state and returns it as a DataFrame
DataFrame
s are tables that are used to represent datarun!(model, n; adata)
, where
n
is the number of time steps we want to run the model foradata
is a keyword argument that specifies what data (“agent data”) is gatheredrun!
has two return values, two DataFrame
s
run!
to collect datap
field (their weight for grammar \(G_1\)) at each time step, over 4000 model iterations (each agent is updated 4000 times)._
variable (think of this as a trash bin)p
is prefixed with a colon (:p
) – this is crucial!adata
is a vector (this means you can specify more than one agent field to be collected, should you wish to do so)run!
to collect datadata
now contains a DataFrame
with three columns: the time step, the agent’s ID, and the agent’s p
:Row | time | id | p |
---|---|---|---|
Int64 | Int64 | Float64 | |
1 | 0 | 1 | 0.01 |
2 | 0 | 2 | 0.01 |
3 | 0 | 3 | 0.01 |
4 | 0 | 4 | 0.01 |
5 | 0 | 5 | 0.01 |
6 | 0 | 6 | 0.01 |
7 | 0 | 7 | 0.01 |
8 | 0 | 8 | 0.01 |
9 | 0 | 9 | 0.01 |
10 | 0 | 10 | 0.01 |
11 | 1 | 1 | 0.0099 |
12 | 1 | 2 | 0.0099 |
13 | 1 | 3 | 0.0099 |
⋮ | ⋮ | ⋮ | ⋮ |
39999 | 3999 | 9 | 0.999996 |
40000 | 3999 | 10 | 1.0 |
40001 | 4000 | 1 | 1.0 |
40002 | 4000 | 2 | 1.0 |
40003 | 4000 | 3 | 0.999999 |
40004 | 4000 | 4 | 0.999999 |
40005 | 4000 | 5 | 1.0 |
40006 | 4000 | 6 | 1.0 |
40007 | 4000 | 7 | 1.0 |
40008 | 4000 | 8 | 1.0 |
40009 | 4000 | 9 | 0.999996 |
40010 | 4000 | 10 | 1.0 |
run!
to collect data.
)group
keyword argument on plot
so that each agent gets its own trajectory in the plotrun!
to collect datap
evolvesrun!
: all we need to do is to feed the adata
keyword argument with the tuple (:p, mean)
instead of plain :p
mean
, you can put any function that you want to aggregate over the agentsmean_p
column:Row | time | mean_p |
---|---|---|
Int64 | Float64 | |
1 | 0 | 0.01 |
2 | 1 | 0.0099 |
3 | 2 | 0.009801 |
4 | 3 | 0.00970299 |
5 | 4 | 0.00960596 |
6 | 5 | 0.0105099 |
7 | 6 | 0.0104048 |
8 | 7 | 0.0103008 |
9 | 8 | 0.0101977 |
10 | 9 | 0.0100958 |
11 | 10 | 0.00999481 |
12 | 11 | 0.00989486 |
13 | 12 | 0.00979591 |
⋮ | ⋮ | ⋮ |
3990 | 3989 | 0.998819 |
3991 | 3990 | 0.998831 |
3992 | 3991 | 0.998842 |
3993 | 3992 | 0.998854 |
3994 | 3993 | 0.998865 |
3995 | 3994 | 0.998877 |
3996 | 3995 | 0.998888 |
3997 | 3996 | 0.998899 |
3998 | 3997 | 0.99891 |
3999 | 3998 | 0.998921 |
4000 | 3999 | 0.998932 |
4001 | 4000 | 0.998942 |
watts_strogatz(n, k, beta)
, takes three arguments:
n
: number of nodesk
: initial degreebeta
: rewiring probabilitybeta
affects the evolution of mean p
p
: 0.01gamma
: 0.01P1
: 0.2P2
: 0.1n
: 50k
: 8beta
: 0.1 versus 0.5ensemblerun!
ensemblerun!
functionrun!
but, instead of a single model, takes a vector of models as inputensemblerun!
ensemblerun!
Row | time | mean_p | ensemble |
---|---|---|---|
Int64 | Float64 | Int64 | |
1 | 0 | 0.01 | 1 |
2 | 1 | 0.0101 | 1 |
3 | 2 | 0.010199 | 1 |
4 | 3 | 0.010297 | 1 |
5 | 4 | 0.010194 | 1 |
6 | 5 | 0.0100921 | 1 |
7 | 6 | 0.00999118 | 1 |
8 | 7 | 0.00989127 | 1 |
9 | 8 | 0.00999235 | 1 |
10 | 9 | 0.00989243 | 1 |
11 | 10 | 0.00979351 | 1 |
12 | 11 | 0.00969557 | 1 |
13 | 12 | 0.00979862 | 1 |
⋮ | ⋮ | ⋮ | ⋮ |
99999 | 9989 | 0.989517 | 10 |
100000 | 9990 | 0.989622 | 10 |
100001 | 9991 | 0.989326 | 10 |
100002 | 9992 | 0.989433 | 10 |
100003 | 9993 | 0.989538 | 10 |
100004 | 9994 | 0.989643 | 10 |
100005 | 9995 | 0.989747 | 10 |
100006 | 9996 | 0.989649 | 10 |
100007 | 9997 | 0.989753 | 10 |
100008 | 9998 | 0.989855 | 10 |
100009 | 9999 | 0.989957 | 10 |
100010 | 10000 | 0.990057 | 10 |
ensemblerun!
ensemblerun!
ensemblerun!