rustsim 0.0.1

High-performance agent-based modelling engine - top-level orchestration crate
Documentation
//! Event-queue (continuous-time) model example.
//!
//! Agents schedule events at random future times. Each event increments
//! the agent's counter. Demonstrates EventQueueModel with deterministic
//! event ordering.
//!
//! Run with: `cargo run -p rustsim --example event_queue`

use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
use rustsim::prelude::*;
use rustsim_spaces::nothing::NothingSpace;

#[derive(Debug, Clone)]
struct Counter {
    id: AgentId,
    count: u64,
}

impl Agent for Counter {
    fn id(&self) -> AgentId {
        self.id
    }
}

fn tick_action(agent: &mut Counter, ctx: &mut EventContext<'_, NothingSpace, Counter, (), StdRng>) {
    agent.count += 1;

    // Schedule the next event at a random interval
    let dt = ctx.rng().gen_range(0.5..2.0);
    ctx.add_event(agent.id(), 0, dt);
}

fn main() {
    let mut store = HashMapStore::new();
    for i in 1..=10u64 {
        store.insert(Counter { id: i, count: 0 });
    }

    #[allow(clippy::type_complexity)]
    let actions: Vec<
        fn(&mut Counter, &mut EventContext<'_, NothingSpace, Counter, (), StdRng>),
    > = vec![tick_action];

    let mut model =
        EventQueueModel::new(store, NothingSpace, (), StdRng::seed_from_u64(7), actions);

    // Seed initial events: each agent fires at t = random(0, 1)
    {
        let mut rng = model.rng_mut();
        for i in 1..=10u64 {
            let dt = rng.gen_range(0.0..1.0);
            drop(rng);
            model.add_event(i, 0, dt);
            rng = model.rng_mut();
        }
    }

    println!("Event-Queue Model: 10 agents, continuous time");
    println!("Each agent schedules random-interval events.\n");

    // Run until t = 20.0
    model.step_until(20.0);

    println!("Time: {:.2}", model.time_f64());
    println!(
        "Events processed (queue now empty: {})\n",
        model.queue_is_empty()
    );

    println!("{:>5}  {:>8}", "Agent", "Count");
    println!("{}", "-".repeat(16));

    let mut total = 0u64;
    for i in 1..=10u64 {
        let agent = model.agent(i).unwrap();
        println!("{:>5}  {:>8}", agent.id, agent.count);
        total += agent.count;
    }
    println!("{}", "-".repeat(16));
    println!("{:>5}  {:>8}", "Total", total);
    println!("\nAvg events/agent: {:.1}", total as f64 / 10.0);
}