simul 0.5.1

A discrete-event simulation library aimed at high-level use-cases to quickly simulate real-world problems and run simulated experiments. Some example use cases might include simulating logistics or operations research problems, running experiments to determine optimal parameters, simulating queueing systems, distributed systems, performance engineering, and so on.
Documentation

simul is a discrete-event simulation library for running high-level simulations of real-world problems and for running simulated experiments.

simul is a discrete-event simulator using incremental time progression, with M/M/c queues for interactions between agents. It also supports some forms of experimentation and simulated annealing to replicate a simulation many times, varying the simulation parameters.

Use-cases:

Usage

Warning

Experimental and unstable. Almost all APIs are expected to change.

  • For some examples, see the examples subdirectory.
  • For use cases where your agents need their own custom state, define a struct, implement Agent, and pass your agents into Simulation via constructing AgentInitializers.

Basic usage

[dependencies]
simul = "0.4.1"
use simul::agent::*;
use simul::Simulation;
use simul::SimulationParameters;

/// Example of a minimal, simple Simulation that can be executed.
fn main() {
    // Runs a simulation with a producer that produces work at every tick of
    // discrete time (period=1), and a consumer that cannot keep up (can only
    // process that work every third tick).
    let mut simulation = Simulation::new(SimulationParameters {
        // We pass in two agents:
        //   `producer`: produces a message to the consumer every tick
        //   `consumer`: consumes w/ no side effects every second tick
        // Agents are powerful, and you can pass-in custom implementations here.
        agent_initializers: vec![
            periodic_producing_agent("producer", 1, "consumer"),
            periodic_consuming_agent("consumer", 2),
        ],

        // We pass in a halt condition so the simulation knows when it is finished.
        // In this case, it is "when the simulation is 10 ticks old, we're done."
        halt_check: |s: &Simulation| s.time == 10,

        ..Default::default()
    });

    // For massive simulations, you might block on this line for a long time.
    simulation.run();

    // Post-simulation, you can do analytics on the stored metrics, data, etc.
    simulation
        .agents
        .iter()
        .for_each(|agent| println!("{:#?}", agent));
}

Simulation Concepts / Abstraction

  • A simulation is a collection of Agents that interact with each other via Messages.
  • The simulation keeps a discrete time (u64) which is incremented on each tick of the Simulation.
  • What an Agent does at each tick of the simulation is provided by you in its on_tick() and on_message() methods.
  • Agents must have a unique name.
  • If an Agent wants to interact with another Agent, it can send a Message via the &mut ctx: AgentContext passed into on_tick and on_message.

The simulation runs all the logic of calling process(), distributing messages, tracking metrics, incrementing time, and when to halt. A Simulation is finished when the provided halt_check function returns true, or if an Agent responds with a special Interrupt to halt the Simulation.

Poisson-distributed example w/ Plotting

Here's an example of an outputted graph from a simulation run. In this simulation, we show the average waiting time of customers in a line at a cafe. The customers arrive at a Poisson-distributed arrival rate (lambda<-60.0) and a Poisson-distributed coffee-serving rate with the same distribution.

This simulation maps to the real world by assuming one tick of discrete-simulation time is equal to one second.

Basically, the barista serves coffees at around 60 seconds per drink and the customers arrive at about the same rate, both modeled by a stochastic Poisson generator.

This simulation has a halt_check condition of the simulation's time being equal to 60*60*12, representing a full 12-hour day of the cafe being open.

Contributing

Issues, bugs, features are tracked in TODO.org