Skip to content

Agent-based

12 of the bundled models. The numbers are from a run made when this page was generated: see how.

Boids flock (continuous, heading)

Reynolds/Vicsek-style flocking: 150 Boid agents in a 100x100 wrapped continuous space, each turning each tick toward NEAR_HEADING (the circular mean heading of neighbours within Radius) plus a little noise, then stepping Speed forward -- alignment only, so the effect measured is alignment alone. Each boid keeps its unit heading vector (ux, uy) = (COS(RAD(heading)), SIN(RAD(heading))) and polar, the textbook POLARISATION order parameter: the norm of the flock's mean unit heading, SQRT(MEAN(ux)^2 + MEAN(uy)^2) -- about 1/SQRT(N) (0.07 for 150) for random headings, 1 for a perfectly aligned flock. A synchronous tick reads the tick-start snapshot, so polar after tick k measures the headings of tick k - 1. With Align gain 0.3 and Noise sd 6 degrees it climbs from the random baseline past 0.9 within 60 ticks. Radius, Align gain, Noise sd and Speed are this instance's own.

naga run abm_boids_flock

1 replication, seed 0:

KPI Mean 95% half-width
agent/boids_flock_1/Boids/Alive/Avg Count 150

Nagel-Schreckenberg traffic (ring)

The Nagel-Schreckenberg traffic cellular automaton on a 60-cell ring (a 1-D torus grid, size: [60, 1]), its three rules written once as tick-local let values: gap (the free cells ahead, read by CELL_COUNT('$Cars', k, 0) for k = 1..5 -- an arbitrary-offset grid read), v1 = min(v + 1, Vmax, gap) (accelerate, then brake for the car ahead) and vn, v1 minus 1 with probability P when v1 > 0 -- ONE slowdown draw per car per tick, shared by the action that moves the car vn cells, the one that stores its speed and the one that records flow_contrib = density * vn, whose population mean IS the flow, with no derived-KPI step. Cars act in index order, which is ring order, so each reads the cells ahead before the car there moves (the parallel update NS defines); only the last car reads the first car's new cell across the wrap. With Vmax 5 and P 0.15 the flow-density curve peaks near density 0.1 (6 cars) and is far lower at density 0.8 (48 cars) -- the published shape. Vmax and P are this instance's own; the ring length and car count are fixed so the built-in oracle stays exact.

naga run abm_nagel_schreckenberg

1 replication, seed 0:

KPI Mean 95% half-width
agent/nagel_schreckenberg_1/Cars/Alive/Avg Count 6

Schelling segregation (grid)

Schelling's 1971 tipping-point model: 320 Person agents (160 Red, 160 Blue -- colour IS the state, since only NEIGHBOURS(pop, state) can count a neighbourhood by category) scattered over 80% of a 20x20 torus grid. Each tick, an agent computes the SHARE of its 8 Moore neighbours that share its own colour (like_frac, an ordinary attribute so it shows up in Agent attributes/End Mean) and, if that share is below Tolerance, jumps to a uniformly drawn EMPTY cell (move_random(free=True), Schelling's own move rule -- no other feature needed). With Tolerance in the classic 0.3-0.5 band the population-wide like_frac climbs from its random-mixing baseline (~0.5, two colours) to a segregated plateau around 0.6-0.7 within a few dozen ticks, even though every individual agent is only mildly colour-prejudiced -- the model's own point. The grid and the 320 starting cells are fixed (a fixed shuffle, so the run is exactly reproducible); Tolerance is this instance's own.

naga run abm_schelling_segregation

1 replication, seed 0:

KPI Mean 95% half-width
agent/schelling_segregation_1/Schelling People/Red/Avg Count 160
agent/schelling_segregation_1/Schelling People/Blue/Avg Count 160

SIR on a small-world network

SIR spreading over a Watts-Strogatz network (Population Person agents, network: "small_world", degree K, rewiring Beta): a Susceptible only ever becomes Infected by MESSAGE from a linked neighbour, sent the instant that neighbour recovers (send("infect", "links") on its own I->R transition) -- so infection rides the network structure itself, not a mean-field rate. Beta=0 collapses the network to a plain ring (each agent linked to its K nearest) and, with a CONSTANT recovery time instead of an exponential one, the outbreak becomes a deterministic wavefront: node at ring-distance d recovers at exactly (d + 1) * Recovery time, so Recovered(t) is an EXACT closed form, not a Monte Carlo estimate -- the oracle this asset ships with. The default instance (Beta 0.1) is an ordinary small-world outbreak, faster and larger than the pure ring since the rewired long-range links shortcut the front; Degree, Beta, Recovery time, Population and Initial infected are this instance's own.

naga run abm_sir_small_world

1 replication, seed 0:

KPI Mean 95% half-width
agent/sir_small_world_1/SIR SW People/S/Avg Count 132
agent/sir_small_world_1/SIR SW People/I/Avg Count 16.7
agent/sir_small_world_1/SIR SW People/R/Avg Count 51.1

Sugarscape with regrowth (grid, patches)

Epstein and Axtell's Sugarscape rule G1 on one sugar hill: 120 Ant agents on a 30x30 bounded grid; the sugar patch starts at each cell's capacity (10 at the centre, falling by 1 per step of Manhattan distance) and GROWS BACK 1 per tick up to that capacity (grow: {rate: 1}, max defaulting to the initial landscape). Each tick an ant steps to the best of its 4 von Neumann neighbours and its own cell (a 5-way PATCH comparison: vision 1), harvests the whole cell and pays Metabolism; it starves at zero wealth. The population falls from 120 to about 24 by t=40 as the ants that cannot see the hill starve, then HOLDS for good: the hill's 181 cells regrow 1 sugar each per tick, more than its survivors burn, so regrowth balances consumption (the oracle checks t=40 and t=120; the same ants with no regrowth all starve by about t=110). Metabolism and the wealth range are this instance's own; the grid and the hill are fixed.

naga run abm_sugarscape_lite

1 replication, seed 0:

KPI Mean 95% half-width
agent/sugarscape_lite_1/Ants/Alive/Avg Count 74.7

Wolf-Sheep predation with grass (grid)

NetLogo's 'Wolf Sheep Predation' in its sheep-wolves-grass version, with NetLogo's own parameters: 35 Sheep and 17 Wolves (NetLogo's 100/50 scaled to this 30x30 torus, about a third of its 51x51 world) wander one Moore cell per tick in random order and lose 1 energy a tick. GRASS is a patch that regrows (grow: {rate: 1, max: 30}): a cell at 30 is green, a sheep on it gains Sheep gain from food and sets it to 0, and it is green again exactly 30 ticks later -- NetLogo's grass-regrowth-time countdown, counted up. A Wolf eats ONE sheep on its cell, drawn from its own stream (the one-to-one claim: remove: {population: Sheep, where: <same cell as sender>, random: true}), and gains Wolf gain from food only then; two wolves on one sheep cannot both eat it. Either species reproduces with its probability each tick (halving its energy with the newborn) and dies below zero energy. Oracle (seed 1, 300 ticks, statistics after a 50-tick warm-up): sheep, wolves AND grass coexist through repeated boom-bust oscillations -- a sheep starts with under 8 energy and pays 1 a tick, so sheep still alive at t=300 can only be eating regrown grass. A qualitative oracle on the Min/Max/Final columns: a small predator-prey system is chaotic, and averaging replications would average away the cycles. Known deviation: a newborn is placed at a random cell (the population's placement rule), not beside its parent.

naga run abm_wolf_sheep

1 replication, seed 0:

KPI Mean 95% half-width
agent/wolf_sheep_1/Sheep/Alive/Avg Count 61.2
agent/wolf_sheep_1/Wolves/Alive/Avg Count 16.8

Bass diffusion (agents)

The individual-based twin of the System dynamics library's Bass diffusion asset: 2000 Prospect agents, each moving from Potential to Adopter at the SHARED hazard p + q * Adopters/m (innovation p plus imitation q proportional to the fraction already adopted) -- no self term, so this is exactly the mean-field Bass rate applied per agent. With p=0.03, q=0.4, the SD closed form puts the inflection at t*=ln(q/p)/(p+q) and the adopted fraction there at (q-p)/(2q); the agent run matches it within Monte Carlo noise. p, q and the market size m are this instance's own; the Product preset fills p and q from an illustrative catalogue.

naga run agents_bass_diffusion_agents

1 replication, seed 0:

KPI Mean 95% half-width
agent/bass_diffusion_agents_1/Market/Potential/Avg Count 1,660
agent/bass_diffusion_agents_1/Market/Adopter/Avg Count 337

Machine agent with repair

Six Machine agents, each Working{Idle, Busy} while processing jobs (EXPO(2) idle, EXPO(5) busy). Two composite-level transitions out of Working, live regardless of which child is active and not restarted by an Idle<->Busy move: a rare random breakdown (rate 0.002, MTBF ~500 min) and a usage-based preventive-maintenance condition (self.wear >= 20, incremented on each Busy entry). Either sends the machine to Broken; repair (EXPO(30)) re-enters Working with history "deep", so the machine resumes the sub-state -- Idle or Busy -- it was in when it broke down, and resets wear. KPIs: COUNT("Machines", "Working") vs COUNT("Machines", "Broken"), and fleet availability.

naga run agents_machine_repair --replications 3

3 replications, seed 0:

KPI Mean 95% half-width
agent/Machines/Working/Avg Count 4.83 0.38
agent/Machines/Idle/Avg Count 1.38 0.071
agent/Machines/Busy/Avg Count 3.45 0.39
agent/Machines/Broken/Avg Count 1.17 0.38

Courier on a path network

One Courier agent moving on the model's own path network (network) instead of continuous space: it starts at a node named "Dock", is sent to a node named "Dropoff" the instant it starts, and enters Delivered on arrival. Needs the model to declare those two node names and a segment joining them -- validation reports E_AGENT_SPACE with a clear hint if they are missing. move_to's travel time is segment length / speed, exact, so a fixed leg gives an exact sojourn oracle just like the continuous walker asset.

naga run agents_network_courier

1 replication, seed 0:

KPI Mean 95% half-width
agent/network_courier_1/Couriers/Moving/Avg Count 0.2
agent/network_courier_1/Couriers/Delivered/Avg Count 0.8

Random walker (continuous space)

One Walker agent in a 100x100 continuous space, placed at [0, 0] and sent moving to [80, 0] the instant it starts (an entry action on its initial state); it enters Arrived on the 'arrived' message move_to delivers on the exact arrival instant. A straight trip at a fixed speed is a deterministic oracle: sojourn in Moving equals distance/speed exactly, no tolerance needed. Copy this asset, add more agents with a random {"kind": "random"} placement and a move_to target expression (e.g. another agent's position via AGENT(...)) to build a crowd or a pursuit model.

naga run agents_random_walker

1 replication, seed 0:

KPI Mean 95% half-width
agent/random_walker_1/Walkers/Moving/Avg Count 0.4
agent/random_walker_1/Walkers/Arrived/Avg Count 0.6

Server busy/idle cycle (agents)

A single Server agent alternating Idle (waiting EXPO(1/lambda) for the next customer) and Busy (serving for EXPO(1/mu)) -- the busy/idle process of an M/M/1 queue's server, without tracking the waiting line itself. Memorylessness makes each state's mean sojourn exactly 1/rate: with lambda=0.8, mu=1.0, Idle averages 1.25 and Busy averages 1.0 -- the same identity Little's law rests on. The arrival and service rates are this instance's own; add a queue-length agent type (states 0..K, arrival/departure transitions) for the waiting line itself.

naga run agents_server_utilization

1 replication, seed 0:

KPI Mean 95% half-width
agent/server_utilization_1/Servers/Idle/Avg Count 0.548
agent/server_utilization_1/Servers/Busy/Avg Count 0.452

SIR epidemic (agents)

The individual-based twin of the System dynamics library's SIR asset: 2000 Person agents, each a Susceptible/Infected/Recovered state machine. Infection is a SHARED rate beta * I / N (COUNT of the Infected state over the population) so every Susceptible agent's hazard tracks the current outbreak size; recovery is a per-agent EXPO(1/gamma) timeout. With beta=0.25, gamma=0.1 (R0=2.5) and 10 initial Infected, the final Recovered count converges to the classic final-size relation z = 1 - exp(-R0 z) as the population grows. Beta, gamma, the population and the initial Infected are this instance's own; the Outbreak preset fills beta and gamma from an illustrative catalogue.

naga run agents_sir_agents

1 replication, seed 0:

KPI Mean 95% half-width
agent/sir_agents_1/SIR People/S/Avg Count 562
agent/sir_agents_1/SIR People/I/Avg Count 120
agent/sir_agents_1/SIR People/R/Avg Count 1,320