# Agent Based Modeling in Julia

**URL:** <https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431>\
**Category:** New to Julia\
**Created:** [July 17, 2018, 11:07am UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431 "2018-07-17T11:07:50Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![sbacelar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sbacelar/32/4359_2.png) [@sbacelar](https://discourse.julialang.org/u/sbacelar)\
**Post date:** [July 17, 2018, 11:07am UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/1 "2018-07-17T11:07:51Z")

</div>

I couldn’t find “established” packages on Agent-Based Modeling (ABM) in Julia. Is there any work that it is interesting to follow on this subject?

And also, is there any Julia interface to `[NetLogo](https://ccl.northwestern.edu/netlogo/)` similar to `[RNetLogo](http://rnetlogo.r-forge.r-project.org/)` (in `R`) or `[PyNetLogo](https://github.com/quaquel/pyNetLogo)` (in `Python`)?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 17, 2018, 11:28am UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/2 "2018-07-17T11:28:27Z")

</div>

Not that I know of, but since [multiple dispatch](https://docs.julialang.org/en/latest/manual/methods/) is one of the defining features of the language, you should be able to program ABMs very easily from scratch. I would even argue that this is easier than investing in a “framework”.

---

<div class="post-metadata">

**Author:** ![sbacelar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sbacelar/32/4359_2.png) [@sbacelar](https://discourse.julialang.org/u/sbacelar)\
**Post date:** [July 17, 2018, 3:09pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/3 "2018-07-17T15:09:32Z")

</div>

I think that programming ABMs from scratch is way beyond my programming expertise. ABM frameworks like `NetLogo`, `Mason`, `Repast`, `Mesa` are the result of years of hard work of several developers.  
Nonetheless, I wonder the reason why you said that `multiple dispatch` eases this work…

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 17, 2018, 3:35pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/4 "2018-07-17T15:35:47Z")

</div>

> [@sbacelar](#):
>
> ABM frameworks like `NetLogo` , `Mason` , `Repast` , `Mesa` are the result of years of hard work of several developers.

I am not familiar with these projects, but a cursory look at NetLogo suggests that it is a GUI-based model definition environment. Which indeed must have been very time consuming to develop, but if you are willing to write code and understand your models, just programming the underlying algorithm in Julia without the GUI part should be significantly easier.

Multiple dispatch helps because it solves the [expression problem](https://en.wikipedia.org/wiki/Expression_problem). In particular, you can think of ABMs as a collection of mutable objects (agents) which interact. You can define the agents as Julia objects (eg `mutable struct`), and then the interactions as functions with the relevant methods. This should give you a very flexible way of coding these models.

If you describe a simple algorithm that you want to implement, and show what you have attempted so far, you are very likely to get help here.

---

<div class="post-metadata">

**Author:** ![sbacelar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sbacelar/32/4359_2.png) [@sbacelar](https://discourse.julialang.org/u/sbacelar)\
**Post date:** [July 17, 2018, 4:16pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/5 "2018-07-17T16:16:58Z")

</div>

Well, when I think in a simple ABM algorithm, the first idea that comes to my mind is the Shelling’s segregation model. It’s not what I want to study but it is, in fact, a classic example.

Googling it I found that (for me one of best disseminators of Julia), Sargent & Stachurski have already done it in Julia. It can be read in [Shelling’s segregation model](https://lectures.quantecon.org/jl/schelling.html) in `Lectures in Quantitative Economics` (QuantEcon).

It is possible to find there a reference to what you said about `mutable struct`:

`mutable struct Agent{TI<:Integer, TF<:AbstractFloat}`

---

<div class="post-metadata">

**Author:** ![ElOceanografo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eloceanografo/32/624_2.png) [@ElOceanografo](https://discourse.julialang.org/u/ElOceanografo)\
**Post date:** [July 17, 2018, 4:33pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/6 "2018-07-17T16:33:50Z")

</div>

I’ll second that–for part of my dissertation I implemented a fairly complex agent-based simulation in Julia, and multiple dispatch made it pretty straightforward to structure. The basic pattern I used was something like this:

```julia
abstract type AbstractAnimal end

mutable struct Species1 <: AbstractAnimal
    # put your state variables here
end

mutable struct Species2 <: AbstractAnimal
    # put some (possibly different) state variables here
end

function update!(animal::Species1, group::Array{AbstractAnimal})
    # change animal's state based on some interaction with group
end

function update!(animal::Species2, group::Array{AbstractAnimal})
    # change animal's state based on some (different) interaction with group
end

function update!(group::Array{AbstractAnimal})
    for animal in group
        update!(animal, group)
    end
end

```

If you decide you want to add different species or behaviors, you can just define a new species type and `update!` method to go with it. I haven’t used NetLogo either, but from skimming some of the example code on the website, this approach doesn’t seem any more conceptually complicated…

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [July 17, 2018, 4:48pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/7 "2018-07-17T16:48:45Z")

</div>

I have tried developing agent based models with Julia, but ran into performance issues with a design pattern like yours, which seemed like a natural way to approach the problem. Here is a very simple example illustrating poor performance with a heterogeneous vector of agents. Note that the performance is poor even though the methods are performing the same action. Does anyone have any advice?

```julia
using BenchmarkTools
abstract type A; end 

mutable struct B <: A
    x::Int 
end 

mutable struct C <: A 
    x::Int 
end 

incrementSuper(v::A) = v.x += 1 
incrementSub(v::B) = v.x += 1
incrementSub(v::C) = v.x += 1

a = A[B(1) for i in 1:10^5]
b = A[C(1) for i in 1:10^5]
mixed = [a;b]
same = [B(1) for i in 1:(2*10^5)]

@btime incrementSuper.(mixed)
@btime incrementSuper.(same)
@btime incrementSub.(mixed)
@btime incrementSub.(same)

```

Results:

```julia
27.589 ms (35 allocations: 1.53 MiB)
403.286 μs (26 allocations: 1.53 MiB)
3.208 ms (200032 allocations: 4.58 MiB)
401.495 μs (26 allocations: 1.53 MiB)

```

---

<div class="post-metadata">

**Author:** ![aaowens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aaowens/32/12101_2.png) [@aaowens](https://discourse.julialang.org/u/aaowens)\
**Post date:** [July 17, 2018, 4:48pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/8 "2018-07-17T16:48:55Z")

</div>

Is the performance good when relying so much on multiple dispatch here? I’d worry that since the output of the group array is not type stable, this would not perform well relative to a code which does conditional dispatch based on the value of an integer. Perhaps the 0.7 optimizations for small unions will help here.

Edit: I have the same concern as the previous post.

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [July 17, 2018, 4:53pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/9 "2018-07-17T16:53:32Z")

</div>

Indeed. I also hope there will be optimizations for these use cases.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 17, 2018, 6:05pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/10 "2018-07-17T18:05:50Z")

</div>

Check out [https://github.com/tkoolen/TypeSortedCollections.jl](https://github.com/tkoolen/TypeSortedCollections.jl) and/or [https://github.com/rdeits/ConcreteInterfaces.jl](https://github.com/rdeits/ConcreteInterfaces.jl)

---

<div class="post-metadata">

**Author:** ![ElOceanografo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eloceanografo/32/624_2.png) [@ElOceanografo](https://discourse.julialang.org/u/ElOceanografo)\
**Post date:** [July 17, 2018, 6:13pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/11 "2018-07-17T18:13:29Z")

</div>

Interesting…I just checked my dissertation code, and realized I didn’t actually use arrays of mixed agent types anywhere–each kind of agent was run in its own simulation (i.e. your `incrementSuper.(same)` example), so I didn’t run into the performance issue. (At least, not before confidently posting hastily-written pseudocode in a public forum 🙃) Good to know about.

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [July 17, 2018, 7:42pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/12 "2018-07-17T19:42:56Z")

</div>

Thanks these packages look useful. Do you have any idea whether one of these ideas will get implemented “under the hood” in base Julia? It would be nice to have Julia take care of those details.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 17, 2018, 7:50pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/13 "2018-07-17T19:50:40Z")

</div>

I don’t think there are any plans to do so, especially since there would be no performance advantage to having them in base Julia vs. being in a package.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [July 17, 2018, 8:14pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/14 "2018-07-17T20:14:34Z")

</div>

Together with @pszufe I will be running a tutorial on writing ABMs in Julia, [Programme « Social Simulation Conference 2018](http://ssc2018.dsv.su.se/programme) (Monday August 20, 13:00 to 17:00).

In particular we have WIP to translate [https://github.com/bkamins/EventSimulation.jl](https://github.com/bkamins/EventSimulation.jl) into a more ABM like framework similar to Mason (with any custom scheduling - not only tick-based, libraries supporting grids etc.). An interesting thing you might want to look up in the documentation is that you do not need `update!` method as above, as in Julia you can program agent structure to be a functor ([https://docs.julialang.org/en/latest/manual/methods/#Function-like-objects-1](https://docs.julialang.org/en/latest/manual/methods/#Function-like-objects-1)) so you then just “call” an object.

As for performance abstract collections are of course bad, but they impact the speed of simulation only if agents do very little work (i.e. when looping itself takes a significant proportion of time). In complex ABMs this is often negligible as agents do computing-intensive work in their `update!` step anyway.

The issue with [https://github.com/tkoolen/TypeSortedCollections.jl](https://github.com/tkoolen/TypeSortedCollections.jl) is I think that in ABMs you often have to iterate over agents in a random (or some specific order). In the worst case you can do what was already mentioned - have a single concrete type that is responsible for scheduling which points (e.g. via an `Int`) to what type of agent you actually have to handle and store separate types in separate collections (admittedly this is not a “clean” solution).

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [July 17, 2018, 8:17pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/15 "2018-07-17T20:17:59Z")

</div>

Note that operations on heterogeneous arrays have gotten much faster in 0.7. On my machine, in v0.6.3, the timings for your operations are

```julia
incrementSuper.(mixed) => 48.440 ms (800018 allocations: 13.73 MiB)
incrementSuper.(same) => 512.013 μs (2 allocations: 1.53 MiB)
incrementSub.(mixed) => 4.904 ms (200002 allocations: 4.58 MiB)
incrementSub.(same) => 513.724 μs (2 allocations: 1.53 MiB)

```

and in v0.7-beta2:

```julia
incrementSuper.(mixed) => 10.282 ms (399497 allocations: 7.62 MiB)
incrementSuper.(same) => 293.553 μs (2 allocations: 1.53 MiB)
incrementSub.(mixed) => 325.503 μs (2 allocations: 1.53 MiB)
incrementSub.(same) => 272.394 μs (2 allocations: 1.53 MiB)

```

---

<div class="post-metadata">

**Author:** ![sbacelar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sbacelar/32/4359_2.png) [@sbacelar](https://discourse.julialang.org/u/sbacelar)\
**Post date:** [July 17, 2018, 9:47pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/16 "2018-07-17T21:47:01Z")

</div>

It would be of great interest if you publish this or a similar tutorial on ABM in Julia.

---

<div class="post-metadata">

**Author:** ![pszufe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pszufe/32/23452_2.png) [@pszufe](https://discourse.julialang.org/u/pszufe)\
**Post date:** [July 18, 2018, 12:23am UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/17 "2018-07-18T00:23:06Z")

</div>

Regarding `EventSimulation.jl` you can see some tutorial examples here:  
[https://github.com/bkamins/EventSimulation.jl/blob/master/docs/src/tutorial.md](https://github.com/bkamins/EventSimulation.jl/blob/master/docs/src/tutorial.md)

We also plan to rewrite some classical MASON simulations (such as Flockers) to Julia. Rewriting the logic is easy, however doing the graphics (which I think is important to understand ABM by beginners) is more work.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [July 18, 2018, 12:45am UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/18 "2018-07-18T00:45:02Z")

</div>

Julia 0.7 small unions optimisation should help with heterogeneous arrays.  
I think

Though one might need to trigger the restriction from vector Any down to vector union manually

---

<div class="post-metadata">

**Author:** ![nicolaspayette](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicolaspayette/32/4083_2.png) [@nicolaspayette](https://discourse.julialang.org/u/nicolaspayette)\
**Post date:** [July 22, 2018, 12:44pm UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/19 "2018-07-22T12:44:01Z")

</div>

> [@sbacelar](#):
>
> And also, is there any Julia interface to [NetLogo](https://ccl.northwestern.edu/netlogo/) similar to [RNetLogo](http://rnetlogo.r-forge.r-project.org/) (in `R` ) or [PyNetLogo](https://github.com/quaquel/pyNetLogo) (in `Python` )?

Well, I didn’t think it was quite ready to go public, but since you’re asking, here you go:

> **[GitHub - nicolaspayette/NetLogo.jl: A Julia package for controlling NetLogo](https://github.com/nicolaspayette/NetLogo.jl)**
>
> A Julia package for controlling NetLogo. Contribute to nicolaspayette/NetLogo.jl development by creating an account on GitHub.

It’s very limited, and very raw, but it might be something to build on if there is interest in the community.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [July 31, 2018, 10:36am UTC](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431/20 "2018-07-31T10:36:49Z")

</div>

> [@sbacelar](#):
>
> It would be of great interest if you publish this or a similar tutorial on ABM in Julia.

Here is a write-up of what I think is the simplest (by which I understand using only Base and relatively easy to understand) approach at current state of Julia compiler [Julia snippets: ABC of ABM in Julia](https://juliasnippets.blogspot.com/2018/07/abc-of-abm-in-julia.html).

[Next page](https://discourse.julialang.org/t/agent-based-modeling-in-julia/12431.md?page=2)
