Agents.jl : Agent based modelling

Heyo people,

I am very happy to announce Agents.jl v2.0 (actually version 1 was never announced).

Agents.jl allows you to do agent based modelling. From our documentation:

An agent-based model is a computational simulation of autonomous agents that react to their environment (including other agents) given a predefined set of rules [1]. ABM has gained wide usage in a variety of research disciplines. One reason for its popularity is that it allows relaxing many simplifying assumptions usually made by mathematical models. Relaxing such assumptions of a “perfect world” can change a model’s behavior [2]. ABM is specifically an important tool for studying complex systems where a system’s behavior cannot be predicted and has to be explored.

Me and @Ali_Vahdati have been working intensely on it the past months, trying to drastically improve and simplify the user API. We are now safe to say that Agents.jl is not only 13 times faster than the Python competitor Mesa, but it has a truly much simpler API than Mesa (everything is achieved in less, but clearer, lines of code). Besides working on actual code we have done huge improvements in the documentation page.

Agents.jl is also part of JuliaDynamics, which means you can ask us questions about it on #dynamics-bridged on Slack or Gitter.

To give you an example of how much more simplified the interface is, here is a simple wealth exchange model, where agents randomly exchange wealth with nearby agents:

mutable struct WealthInSpace <: AbstractAgent
    id::Int
    pos::NTuple{2, Int}
    wealth::Int
end

function wealth_model_2D(;dims = (25,25), wealth = 1, M = 1000)
  space = Space(dims, periodic = true)
  model = ABM(WealthInSpace, space; scheduler = random_activation)
  for i in 1:M # add agents in random nodes
      add_agent!(model, wealth)
  end
  return model
end

function agent_step_2d!(agent, model)
    agent.wealth == 0 && return # do nothing
    agent_node = coord2vertex(agent.pos, model)
    neighboring_nodes = node_neighbors(agent_node, model)
    push!(neighboring_nodes, agent_node) # also consider current node
    rnode = rand(neighboring_nodes) # the node that we will exchange with
    available_agents = get_node_contents(rnode, model)
    if length(available_agents) > 0
        random_neighbor_agent = id2agent(rand(available_agents), model)
        agent.wealth -= 1
        random_neighbor_agent.wealth += 1
    end
end

Once you run this model and plot the results (see the wealth distribution example of the documentation), you find out that wealth gets more and more localized.


Logo made OBVIOUSLY in collab with @cormullion .

24 Likes