Scheduler errors when trying to graph agents

Hello,

I’ve created an agent-based model where depositor agents withdraw money from bank agents. I’m now trying to create a visual of the network by using Graphs.jl to show the banks as nodes and the depositors’ paths as the edges. The depositors can withdraw from several banks, which, I believe is why the “scheduler” error message keeps occurring. The messages include UnderVarError, scheduler not defined, and Argument Error pos when using space.

How would you suggest I fix? Or is it possible with Graphs.jl? Thank you.

Blockquote
#CREATE FUNCTION to INITIALIZE and SETUP MODEL#

Define the model initialization function

function initialize_model(; num_banks=500, num_depositors=250)
properties = Dict(
:num_banks => num_banks,
:num_depositors => num_depositors,
:num_failed_banks => 0,
:num_vulnerable_banks => 0,
:tick => 0,
)
space = GridSpace((10, 10), periodic=false)
scheduler = AgentSchedulers.fastest
model = ABM(Union{Bank, Depositor}, space; properties, scheduler=scheduler)

##Poisson distribution for x and y coordinates
xes = rand(Poisson(40), num_banks)
yes = rand(Poisson(75), num_banks)


 # Add banks to the model
for (i, (x, y)) in enumerate(zip(xes, yes))
    add_agent!(Bank(i, rand(Bool), rand(Bool), rand(), 2 * rand(), 100, rand(1:10), rand(1:3)), model; pos=(x, y))
end

# Add depositors to the model
for i in 1:num_depositors
    x, y = rand(1:10), rand(1:10)  # Random positions for depositors
    add_agent!(Depositor(num_banks + i, (x, y)), model)
end

return model

end

Initialize the model

model = initialize_model()

CREATE GRAPH WITH BANKS AS NODES AND DEPOSITORS AS EDGES

Collect all banks and depositors

banks = [a for a in allagents(model) if isa(a, Bank)]
depositors = [a for a in allagents(model) if isa(a, Depositor)]

Initialize the graph with the total number of banks

n_banks = length(banks)
g = SimpleGraph(n_banks)

Create a mapping from bank IDs to graph node indices

bank_id_to_index = Dict(bank.id => i for (i, bank) in enumerate(banks))

Add edges based on depositors

for depositor in depositors
find_bank = random_agent(model, a → isa(a, Bank) && a.vul == true && a.health == true)
if find_bank != nothing
depositor_index = bank_id_to_index[find_bank.id] # This should be the bank’s index
bank_index = bank_id_to_index[find_bank.id]
Graphs.add_edge!(g, depositor_index, bank_index)
end
end

Define the colors based on vulnerability

bank_colors = [bank.vul ? :orange : :blue for bank in banks]

Define the layout using spring_layout from GraphPlot

layout = spring_layout(g; C=1.0, MAXITER=100)

Plot the graph

gplot(g, layout=layout, nodefillc=bank_colors)

Please see Please read: make it easier to help you .

in particular format your post so that code is shown as code, and report actual error stactraces, not approximate ones.

Will do. I’ll close this post and report the error verbatim. Thank you.

In case your model primarily focuses on the bank/depositor network, it might be worth looking at Vahana.jl, where the model is expressed as a graph from the start, offering extensive functionality around the network structure.

For example, the code to create the network and its visualization would look like this:

using Vahana
import GraphMakie, GLMakie, NetworkLayout

struct Bank
    failed::Bool
    vulnerable::Bool
end

struct Depositor
end

struct Deposit
end

sim = ModelTypes() |>
    register_agenttype!(Bank) |>
    register_agenttype!(Depositor) |>
    register_edgetype!(Deposit) |>
    create_model("bank model") |>
    create_simulation()

banks = [ Bank(rand(Bool), rand(Bool))  for _ in 1:500 ]
bankids = add_agents!(sim, banks)

healthy = filter(b -> b[2].failed == false && b[2].vulnerable == false,
                 zip(bankids, banks) |> collect)

for d in add_agents!(sim, [ Depositor() for _ in 1:250 ])
    add_edge!(sim, d, rand(healthy)[1], Deposit())
end

finish_init!(sim)

modify_vis(state::Bank, _, _) =
    Dict(:node_color => state.vulnerable ? :orange : :blue,
         :node_marker => state.failed ? :rect : :circle)

modify_vis(state::Depositor, _, _) =
    Dict(:node_color => :black,
         :node_size => 8.0)

modify_vis(state::Deposit, _, _, _) = Dict(:edge_color => :lightgrey)

create_graphplot(sim, update_fn = modify_vis) |> display

Thank you very much, sfuerst! I will try it.