Skip to main content

A Discrete-Event Simulator in Python

Project description

Simulus - A discrete-event simulator in Python

Simulus is an open-source discrete-event simulator in Python. Simulus fully supports the process-oriented simulation world-view.

In the near future, simulus will support parallel and distributed simulation, and real-time simulation.

Installation

Run the following to install:

pip install simulus

Usage

Simulus works in two ways. One way is through events. The user schedules events. Simulus makes sure all events are sorted in timestamp order. When an event happens, simulus advances the simulation time to the event and calls the event handler, which is a user defined function. While processing the event, the user can schedule new events into the simulated future. We call this direct event scheduling.

The other way is through processes. The user can create processes and have them run and interact. Each process is a separate thread of control. During its execution, a process may be blocked, either sleeping for some time or requesting for some resource that is currently unavailable. The process can resume execution when the specified time has passed or after the resource blocking condition has been removed. We call this process scheduling.

In simulus, both direct event scheduling and process scheduling can be used together to achieve the modeling tasks.

The following a hello-world example, which simply schedules a function invocation in the simulated future:

import simulus

def print_message():
    print("Hello world at time", sim.now)
    sim.sched(print_message, offset=10)

sim = simulus.simulator()
sim.sched(print_message, until=10)
sim.run(100)
Hello world at time 10
Hello world at time 20
Hello world at time 30
Hello world at time 40
Hello world at time 50
Hello world at time 60
Hello world at time 70
Hello world at time 80
Hello world at time 90
Hello world at time 100

The following is the same hello-world example, but instead we use a process:

import simulus

def print_message():
    while True:
        print("Hello world at time", sim.now)
        sim.sleep(10)

sim = simulus.simulator()
sim.process(print_message, until=10)
sim.run(100)
Hello world at time 10
Hello world at time 20
Hello world at time 30
Hello world at time 40
Hello world at time 50
Hello world at time 60
Hello world at time 70
Hello world at time 80
Hello world at time 90
Hello world at time 100

Simulus supports conditional wait and allows events and processes to coexist. The following shows a example that Tom and Jerry entering a race. We model Tom as a process. Each time, Tom calls sleep() to represent running for some time, which is a random variable from a normal distribution with a mean 100 and a standard deviation of 50 (with a cutoff below zero). We model Jerry as an event. Jerry calls sched() to schedule an event to represent running for some time, which is a random variable from a uniform distribution between 50 and 100. Tom and Jerry compete for ten times; the next race starts as soon as the previous one finishes. Whoever runs fastest wins. But if they run for more than 100 seconds, both are disqualified for that race.

import simulus

from random import seed, gauss, uniform
seed(321)

def tom():
    sim.sleep(max(0, gauss(100, 50)))
    print("%g: tom finished" % sim.now)

def jerry():
    print("%g: jerry finished" % sim.now)

def compete():
    tom_won, jerry_won = 0, 0
    for _ in range(10):
        print("<--- competition starts at %g -->" % sim.now)

        p = sim.process(tom) # run, tom, run!
        e = sim.sched(jerry, offset=uniform(50, 150)) # run, jerry, run!

        # let the race begin...
        (r1, r2), timedout = sim.wait((p, e), 100, method=any)
        if timedout:
            print("%g: both disqualified" % sim.now)
            sim.kill(p) # both tom and ...|
            sim.cancel(e) # jerry can stop running now
        elif r1: 
            print("%g: tom wins" % sim.now)
            tom_won += 1
            sim.cancel(e) # jerry can stop running now
        else:
            print("%g: jerry wins" % sim.now)
            jerry_won += 1
            sim.kill(p) # tom can stop running now
    print("final result: tom:jerry=%d:%d" % (tom_won, jerry_won))

sim = simulus.simulator()
sim.process(compete)
sim.run()
<--- competition starts at 0 -->
77.5459: jerry finished
77.5459: jerry wins
<--- competition starts at 77.5459 -->
171.749: jerry finished
171.749: jerry wins
<--- competition starts at 171.749 -->
271.749: both disqualified
<--- competition starts at 271.749 -->
357.072: tom finished
357.072: tom wins
<--- competition starts at 357.072 -->
430.387: tom finished
430.387: tom wins
<--- competition starts at 430.387 -->
485.297: tom finished
485.297: tom wins
<--- competition starts at 485.297 -->
585.297: both disqualified
<--- competition starts at 585.297 -->
611.838: tom finished
611.838: tom wins
<--- competition starts at 611.838 -->
711.838: both disqualified
<--- competition starts at 711.838 -->
811.838: both disqualified
final result: tom:jerry=4:2

Simulus also provides several advanced features to ease the common modeling tasks. For example, simulus provides the modeling abstraction for resources and facilities, so that multiple processes can access single-server or multi-server queues, perform producer-consumer synchronization over bounded buffers, and conduct message-passing communication among them.

For more information, check out the Simulus Tutorial, available at the homepage.

Changelog

1.1.0 (2019-07-07)

New

  • Added sections to explain the use of resource and store in tutorial; also added readme jupyter notebook. chg: dev: changed the use of super() in init methods. chg: test: changed tomjerry.py; gauss distribution may return negative time. [Jason Liu]

  • Added store facility and some examples, including most simpy examples. [Jason Liu]

  • Added a couple simpy examples (carwash, moviegoers). [Jason Liu]

  • Changed sched() and process() to allow arbitrary functions; examples and documents have been updated accordingly. [Jason Liu]

  • Added regression pytest and tox support. [Jason Liu]

1.0.5 (2019-07-04)

New

  • New trappables and conditional waits (1.0.5). new: dev: added support for changelogs generated from git logs. chg: dev: changed resource reserve to acquire. [Jason Liu]

  • Redesigned trappables; the processes, events, semaphores, traps, and resources now work with a more intuitive interface design. [Jason Liu]

  • Added initial implementation of resource and qstats. [Jason Liu]

1.0.4 (2019-07-04)

New

  • Finished trappables and timed waits implementation and accompanying documents (1.0.4). [Jason Liu]

  • Updated documents for using trappables and timed wait; and a bug fix. [Jason Liu]

  • Added support for conditional wait (wait on multiple trappables and timed wait). [Jason Liu]

1.0.1 (2019-07-04)

New

  • Pip ready; simulus has been published on pypi (1.0.1, 1.0.2, 1.0.3). [Jason Liu]

0.0.3 (2019-07-04)

New

  • Updated docs and added examples of using trappables; also some minor changes to interface (0.0.3). [Jason Liu]

  • Adding trapping mechanisms for inter-process communication. [Jason Liu]

0.0.2 (2019-07-04)

New

  • Added some examples using processes for user document. [Jason Liu]

  • Added useful functions for direct event scheduling (including resched, cancel, peek, step, and show_calendar). [Jason Liu]

  • Added phold example (to test processes). [Jason Liu]

Changes

  • Restructured examples directory (0.0.2). [Jason Liu]

  • Minor incremental updates. [Jason Liu]

  • Minor updates on a few interface functions including the sleep function. [Jason Liu]

Fix

  • Fixed process scheduling issue. [Jason Liu]

0.0.1 (2019-07-04)

New

  • First implementation of simulus, with support of events, processes, semaphores, and simulators; and also the jupyter notebook establishing the simple use cases. [Jason Liu]

  • This project got started in the evening on June 14, 2019 with a simple idea of creating an easy-to-use python simulator to replace our somewhat dilapitated Simian simulator and also outdoing the esoteric SimPy simulator. [Jason Liu]

Changes

  • Some minor updates (0.0.1). [Jason Liu]

  • Updated the jupyter notebooks. [Jason Liu]

  • Updated README.md (mindless update). [Jason Liu]

  • Updated README.md. [Jason Liu]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for simulus, version 1.1.0
Filename, size File type Python version Upload date Hashes
Filename, size simulus-1.1.0-py3-none-any.whl (31.5 kB) File type Wheel Python version py3 Upload date Hashes View hashes
Filename, size simulus-1.1.0.tar.gz (68.0 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page