simpm.des — SimPM’s Discrete Event Simulation components

Discrete Event Simulation primitives for project-management style models.

This module wraps simpy with opinionated helpers for creating entities, resources, and environments that can be logged and observed while a simulation is running. The docstrings are intentionally verbose so that API documentation generated from them provides ready-to-use guidance and code snippets.

class simpm.des.Entity(env: Environment, name: str, print_actions: bool = False, log: bool = True)

Dictionary-like item that moves through a Environment.

Entities are the actors in a simulation. They hold arbitrary attributes, start and finish activities, wait on resources, and emit lifecycle events that can be observed or logged.

add(res: GeneralResource, amount: int = 1)

Entity increases the number of resources using this method.

property attributes: dict[str, Any]

Get the dictionary of all attributes of the entity.

cancel(res: GeneralResource, amount: int = 1)

Cancels a resource request if it is pending, and puts it back if it is already granted.

do(name: str, dur: Any)

Defines the activity that the entity is doing.

Parameters

namestr

Name of the activity

durfloat | int | distribution

The duration of that activity

get(res: GeneralResource | PriorityResource | PreemptiveResource, amount: int = 1, priority: int = 1, preempt: bool = False)

Entity requests to get a resource using this method.

interruptive_do(name: str, dur: Any)

Start an interruptible activity.

is_pending(res: GeneralResource, amount: int = 1) bool

Check if the entity is waiting for a resource request.

not_pending(res: GeneralResource, amount: int = 1) bool

Convenience inverse of is_pending().

put(res: GeneralResource | PreemptiveResource, amount: int = 1, request=None)

Entity puts back the resources using this method.

schedule() DataFrame

Return a DataFrame with activity name and start/finish times.

status_log() DataFrame

Return a DataFrame with status changes (wait, get, start, finish, put, add).

waiting_log() DataFrame

Return a DataFrame with waiting episodes for resources.

waiting_time()

Return the waiting durations of the entity each time it waited for a resource.

class simpm.des.Environment(name: str = 'Environment')

Simulation environment with observer hooks and logging helpers.

The environment owns all entities and resources, and exposes lifecycle callbacks so observers can react to changes without patching core logic.

create_entities(name: str, total_number: int, print_actions: bool = False, log: bool = True) list[simpm.des.Entity]

Create and register multiple Entity instances at env.now.

log_event(source_type: str, source_id: Any, message: str, time: float | None = None, metadata: dict | None = None)

Send a structured log event to observers and store it on the env.

register_observer(observer: SimulationObserver)

Register a new simulation observer.

run(*args, **kwargs)

Run the simulation once, with per-run metadata.

This wraps simpy.Environment.run and additionally:

  • increments run_number and sets current_run_id,

  • stores a row in run_history,

  • notifies observers via on_run_started / on_run_finished,

  • accepts a hint num_runs (planned total runs in the experiment),

  • logs a final event with simulation_time for the dashboard.

class simpm.des.GeneralResource(env: Environment, name: str, capacity: int, init: int, print_actions: bool = False, log: bool = True)

Common bookkeeping shared by all resource types.

The class keeps track of queue lengths, idle capacity, and historical logs so higher-level resources only need to implement queuing semantics.

average_idleness()

Return the average idleness for the resource.

average_level()

Return the average level for the resource.

average_queue_length()

Return the average queue length for this resource.

average_utilization()

Return the average utilization for the resource.

capacity() int

Return the maximum capacity for the resource.

idle_level() int

Alias for level() (available capacity).

in_use_level() int

Return the number of resources that are currently in use.

level() int

Return the number of resources that are currently available.

queue_log() DataFrame

Return a DataFrame of all waiting episodes at this resource.

status_log() DataFrame

Return a DataFrame of resource status over time.

total_time_idle()

Return the total idle time of the resource.

total_time_in_use()

Return the total in-use time of the resource.

waiting_time()

Return waiting durations for this resource.

class simpm.des.PreemptiveResource(env: Environment, name: str, print_actions: bool = False, log: bool = True)

Resource with priority-based preemption (capacity is assumed to be 1).

idle_level() int

Alias for level() (available capacity).

level() int

Return the number of resources that are currently available.

class simpm.des.PriorityRequest(entity: Entity, amount: int, priority: int)

A class defining a priority request for capturing the resources. This class allows keeping all the requests in a sorted list of requests.

class simpm.des.PriorityResource(env: Environment, name: str, init: int = 1, capacity: int = 1000, print_actions: bool = False, log: bool = True)
add(entity: Entity, amount: int)

A method for adding the resource by the entity.

get(entity: Entity, amount: int, priority: int = 1)

A method for getting the resource with priority.

put(entity: Entity, amount: int)

A method for putting back the resource by the entity.

class simpm.des.Request(entity: Entity, amount: int)

A class defining a request for capturing the resources. This class allows keeping all the requests in a list.

class simpm.des.Resource(env: Environment, name: str, init: int = 1, capacity: int = 1000, print_actions: bool = False, log: bool = True)
add(entity: Entity, amount: int)

A method for adding the resource by the entity.

get(entity: Entity, amount: int)

A method for getting the resource.

put(entity: Entity, amount: int)

A method for putting back the resource by the entity.