Giter Club home page Giter Club logo

simpy's Introduction

DEPRECATION WARNING: Official SimPy is hosted on GitLab.

SimPy

SimPy is a process-based discrete-event simulation framework based on standard Python. Its event dispatcher is based on Python’s generators__ and can also be used for asynchronous networking or to implement multi-agent systems (with both, simulated and real communication).

Processes in SimPy are defined by Python generator functions and can, for example, be used to model active components like customers, vehicles or agents. SimPy also provides various types of shared resources to model limited capacity congestion points (like servers, checkout counters and tunnels).

Simulations can be performed “as fast as possible”, in real time (wall clock time) or by manually stepping through the events.

Though it is theoretically possible to do continuous simulations with SimPy, it has no features that help you with that. Also, SimPy is not really required for simulations with a fixed step size and where your processes don’t interact with each other or with shared resources.

The SimPy distribution contains tutorials, in-depth documentation, and a large number of examples.

SimPy is released under the MIT License. Simulation model developers are encouraged to share their SimPy modeling techniques with the SimPy community. Please post a message to the SimPy mailing list__.

There is an introductory talk that explains SimPy’s concepts and provides some examples: watch the video__ or get the slides__.

__ http://docs.python.org/3/glossary.html#term-generator __ https://groups.google.com/forum/#!forum/python-simpy __ https://www.youtube.com/watch?v=Bk91DoAEcjY __ http://stefan.sofa-rockers.org/downloads/simpy-ep14.pdf

A Simple Example

One of SimPy's main goals is to be easy to use. Here is an example for a simple SimPy simulation: a clock process that prints the current simulation time at each step:

.. code-block:: python

>>> import simpy
>>>
>>> def clock(env, name, tick):
...     while True:
...         print(name, env.now)
...         yield env.timeout(tick)
...
>>> env = simpy.Environment()
>>> env.process(clock(env, 'fast', 0.5))
<Process(clock) object at 0x...>
>>> env.process(clock(env, 'slow', 1))
<Process(clock) object at 0x...>
>>> env.run(until=2)
fast 0
slow 0
fast 0.5
slow 1
fast 1.0
fast 1.5

Installation

SimPy requires Python 2.7, 3.2, PyPy 2.0 or above.

You can install SimPy easily via pip <http://pypi.python.org/pypi/pip>_:

.. code-block:: bash

$ pip install -U simpy

You can also download and install SimPy manually:

.. code-block:: bash

$ cd where/you/put/simpy/
$ python setup.py install

To run SimPy’s test suite on your installation, execute:

.. code-block:: bash

$ py.test --pyargs simpy

Getting started

If you’ve never used SimPy before, the SimPy tutorial__ is a good starting point for you. You can also try out some of the Examples__ shipped with SimPy.

__ https://simpy.readthedocs.org/en/latest/simpy_intro/index.html __ https://simpy.readthedocs.org/en/latest/examples/index.html

Documentation and Help

You can find a tutorial, examples, topical guides__ and an API reference, as well as some information about SimPy and its history in our online documentation. For more help, contact the SimPy mailing list. SimPy users are pretty helpful. You can, of course, also dig through the source code__.

If you find any bugs, please post them on our issue tracker__.

__ https://simpy.readthedocs.org/en/latest/simpy_intro/index.html __ https://simpy.readthedocs.org/en/latest/examples/index.html __ https://simpy.readthedocs.org/en/latest/topical_guides/index.html __ https://simpy.readthedocs.org/en/latest/api_reference/index.html __ https://simpy.readthedocs.org/en/latest/about/index.html __ https://simpy.readthedocs.org/ __ mailto:[email protected] __ https://bitbucket.org/simpy/simpy/src __ https://gitlab.com/team-simpy/simpy __ https://bitbucket.org/simpy/simpy/issues?status=new&status=open

Enjoy simulation programming in SimPy!

Ports

An almost feature-complete reimplementation of SimPy in C# was written by Andreas Beham and is available at github.com/abeham/SimSharp__

__ http://github.com/abeham/SimSharp

simpy's People

Contributors

arisliang avatar cristiklein avatar dependabot[bot] avatar ericlafevers avatar jpgrayson avatar mattgrogan avatar sscherfke avatar thecom avatar vaidyasm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

simpy's Issues

Scala port

Hello there, just wanted to give a heads-up here that I've started an effort on porting SimPy's process-oriented approach to the scala/akka platform.

You can see some (very early) results here: https://github.com/jchapuis/simscala

We have a need for such a platform at my current workplace and so I took advantage of this opportunity to launch this project - I hope we will end up using it and that I'll have more time to work on it.

Any suggestions or help welcome!

Not an issue, a compliment!

Absolutely amazing what can be done with simpy!
I just made a simulation having six machines, which break down randomly and are repaired, 12 storage facilities, which are emptied and replenished, and an assembly line - and to simulate 100,000 time units it takes just 1.3 sec on my iPad!

And I am only a beginner.
Thanks for this great library!

Why `yield env.process(Timeout(self.env, delay)) is not working?

For a newbie (I'm just going through the Tropical guide "Waiting for another process to terminate"), I imagined yield self.env.process(Timeout(self.env, delay)) and yield self.env.timeout(delay) is equivalent expression, where the latter is a short form of the former, because both expression have the same meaning to register the Timeout event with the environment, and get triggered a later time.

But former complains ValueError: <Timeout(29) object at 0x2997fa2fd08> is not a generator..

The generator in the error indicates, there's something technical going on, could you please shed some light on what is the difference of these two forms? And how to make the former work (that is to use Timeout directly) if desired to for testing purpose?

Timeout on Store

I am trying to implement a code where if the packet receiver does not receive a packet within a period of time it must report it to the console.

I realized the simpy engine does not process this correctly, digging deep I realized that the engine removes the callbacks from the event but I cannot understand why.

Code below:


from simpy import *

def dbg_log(env, msg):
	tmp = '[%0.2f] %s' % (env.now, msg)
	print(tmp)

def packet_receiver(env, q):
	while True:
		dbg_log(env, 'RX: Queue len: ' + str(len(q.items)))
		event_a = env.timeout(10)
		event_b = q.get()
		condition = yield event_a | event_b
		if event_a in condition:
			dbg_log(env, 'RX: Timeout...')
		else:
			dbg_log(env, 'RX: received a packet...')
		yield env.timeout(20)

def packet_transmitter(env, q):
	yield env.timeout(500)
	while True:
		dbg_log(env, 'TX: Sending')
		q.put(10)
		yield env.timeout(50)

env = Environment()
packet_store = Store(env)
env.process(packet_receiver(env, packet_store))
env.process(packet_transmitter(env, packet_store))

dbg_log(env, "*** SIM START ***")
env.run(until=1000)
dbg_log(env, "*** SIM END ***")

Please help.

Support one resource with one queue?

Hello~ Can simpy support that each resource has one or more queue? Specifically, I want to model many ATMs, and each ATM has one queue. I know simpy can model all ATMs with only one queue. So could you help me?

It is better that each resource has more queues and I can choose which queue to be served.

accessing resource identifier

I want to access resource identifier.

The codeIt is designed for 2 carwash machine and multiple car order. ıt is from this link: https://simpy.readthedocs.io/en/3.0.3/examples/carwash.html gives.

Car 0 arrives at the carwash at 0.00.
Car 1 arrives at the carwash at 0.00.
Car 2 arrives at the carwash at 0.00.
Car 3 arrives at the carwash at 0.00.
...

here is my project

But I want to log match results like below (multiple carwash machine and multiple car order.)

Car 0 arrives at the carwash 1 at 0.00.
Car 1 arrives at the carwash 3 at 0.00.
Car 2 arrives at the carwash 5 at 0.00.
Car 3 arrives at the carwash 8 at 0.00.
...

How can I do this? is there a way access to resource requests identifiers

Note: below link is a similar but I want to make it in resource type

SimPy Resource of 3 where each has different characteristics

here is my project with 3 different resource

# -*- coding: utf-8 -*-
import numpy as np
import simpy

o_id=0
supplier_fault={}

def order(env,suppliers,workers,technicans,machines,material_depot,production_depot,m_production):
    global o_id
    while True:
        t_order=np.random.uniform(0.1,24)
        n_order=np.random.randint(1,5)#(m_production-200,m_production+200)
        t_manufacture=np.random.uniform(1,6)
        for i in range(n_order):
            o_id+=1
            order_report=[]
            order_report.append(env.now)
            order_report.append("O%d"% o_id)
            env.process(supply(env,suppliers,workers,technicans,machines,material_depot,production_depot,o_id,t_manufacture,order_report))
            env.process(prepare(env,suppliers,workers,technicans,machines,material_depot,production_depot,o_id,t_manufacture,order_report))
            env.process(manufacture(env,suppliers,workers,technicans,machines,material_depot,production_depot,o_id,t_manufacture,order_report))
        yield env.timeout(t_order)

def supply(env,suppliers,workers,technicans,machines,material_depot,production_depot,o_id,t_manufacture,order_report):
    global supplier_fault
    print("supply",o_id,env.now)
    with suppliers.request() as req:
        s=yield req
        print("yierld s",s)
        supplier=str(req).split(" ")[-1][:-1].replace("0x258c8","s")
        
        yield env.timeout(0.1)
        order_report.append(str(supplier))
        print("supply", o_id, "supplier: ",supplier)
    print("End supply",env.now)

def prepare(env,suppliers,workers,technicans,machines,material_depot,production_depot,o_id,t_manufacture,order_report):
    global worker_fault
    print("prepare",o_id,env.now)
    with workers.request() as req:
        worker=str(req).split(" ")[-1][:-1].replace("0x258c8","w")
        yield req
        yield env.timeout(time_prepare(worker))
        order_report.append(str(worker))
        print("prepare", o_id, "worker: ",worker)
    print("End prepare",env.now)

def time_prepare(worker):
    global worker_dict
    return np.random.uniform(1,10)

def manufacture(env,suppliers,workers,technicans,machines,material_depot,production_depot,o_id,t_manufacture,order_report):
    global machine_fault
    print("Manufacture",o_id,env.now)
    print("select machine")
    with machines.request() as req:
        machine=str(req).split(" ")[-1][:-1].replace("0x258c8","m")
        yield req
        yield env.timeout(t_manufacture)
        order_report.append(str(machine))
        print("Manufacture", o_id, "with ",machine)
        
    print("End Manufacture",env.now)
    print (order_report)

num_suppliers=5
num_workers=7
num_technicans=2
num_machines=40

num_days=604
m_production=500

material_capacity=5000
production_capacity=5000

env = simpy.Environment()
suppliers=simpy.Resource(env,capacity=num_suppliers)
workers=simpy.Resource(env,capacity=num_workers)
technicans=simpy.Resource(env,capacity=num_technicans)
machines=simpy.Resource(env,capacity=num_machines)

material_depot=simpy.Container(env, init=material_capacity,capacity=material_capacity)
production_depot=simpy.Container(env, init=production_capacity,capacity=production_capacity)

env.process(order(env,suppliers,workers,technicans,machines,material_depot,production_depot,m_production))

env.run(until=80)

Resource utilization

Hi there,

I am trying to code some examples with SimPy.
I am currently stuck with a monitoring problem.

I just wanted to implement a simple M/M/1 queueing system.

I used a basic simpy resource with capacity=1 and everything seems to run OK.
But how do I get the average resource utilization over time?
In the documentation there is a comment, that it is very easy and very often required. However I did not find any example for it and am currently out of ideas that would not require pages of code.

Thanks for your support.
Pascal

Machine that can batch process

Hi, I want to model a process that can handle multiple samples in a batch.
Let's say we are making pizza using a big oven.
We will make 5 pizza dough and then send them together into the oven for cooking.

I cant simply set the capacity of a oven to 5, because the dough will be processed 1 by 1 once ready from the previous step.

In other word, the oven can handle multiple samples, but once it starts, it has to wait for the complete process to finish to load another batch.

Could you offer some guidance on this?

Resource not getting released

Hi guys, I have been using simpy for a while now but I have an issue with shared resources that I can't figure tout. Since it is part of a complex simulations, I do not have a simple reproducible example for now.

In short, I have resources used by different users. I create the requests for the users, everything is fine. When I release a resource, everything works fine most of the time. However, it happens that some requests never get succeeded, even though the previous is released. So:

  • resource.release(resource.users[0]) is called (release previous request),
  • the next request is put into the users list of the resource alright,
  • but now resource.users[0].triggered is False and other processes yielding for this request are stuck.

In fact, is the last point possible at all in theory in simpy? Shouldn't it be always the case that an event in the users list is triggered?

NB: resources have capacity 1.

How to trigger env.timeout?

Hello,

I'm trying to set up an environment with simpy but in combination with the package osbrain to work with agents.
If I look into debugging the environment is set at default time 0 and can be printed. Now I want to let some time pass with env.timeout(4) in my process and then the parameter 'height' is send to another agent, but nothing happens to the time. Due to the documentation and examples I thought I need to yield my time, but if I do so, I get the error: AttributeError: 'Tree' object has no attribute 'height' and I have a problem with the environment and the information I want to send.

So, I'm not sure, if the env.timeout is triggered without yield and why is then a problem with my other parameters?

I have tried different possibilities like a inner function, a inner class, call a function, etc. and don't know how to solve it.


import simpy
from osbrain import run_agent
from osbrain import run_nameserver
from osbrain import Agent


class Tree(Agent):
    def on_init(self):

        self.height=30

        self.env = simpy.Environment()
        self.env.timeout(4)
        #yield self.env.timeout(4)
        print(self.env.now)

class Fruit(Agent):
    def on_init(self):
        self.height=[]

def sende_height(agent, value):
    agent.height = value
    agent.log_info('Height %s' % value)


if __name__ == '__main__':
    # Initialisation of the name Server and the agent
    ns = run_nameserver()
    baum1 = run_agent('TreeAgent_01', base=Tree)
    apple1 = run_agent('FruitAgent_01', base=Fruit)
    
    # Communication between the agents
    addr1 = baum1.bind('PUB', alias='kanal1')
    apple1.connect(addr1, handler=sende_height)

    baum1.send('kanal1', baum1.get_attr('height'))

    env = simpy.Environment()
    tree = Tree(env)
    fruit = Fruit(env)
    env.run(until=20)

    ns.shutdown()

I'm probably missing something obvious, but I have been stuck on it for awhile. Does anyone have any suggestions?
Thanks so much!

how to serialize env object( like pickle.dump())?

It's there anyway to save/load an env object to harddisk?

demo code as:

import simpy
import pickle

def car(env):
    while True:
        print('Start parking at %d' % env.now)
        parking_duration = 5
        yield env.timeout(parking_duration)
        print('Start driving at %d' % env.now)
        trip_duration = 2
        yield env.timeout(trip_duration)


if __name__ == '__main__':
    env = simpy.Environment()
    env.process(car(env))
    env.run(until=15)
    print('env pause')
    with open('game_save.pkl', 'wb') as f:
        pickle.dump(env, f)
    print('env save')
    #'env load'
    print('env rusume')
    env.run(until=30)

I see as simpy based on python's generator which is cant pickle (Why can't generators be pickled?)
while generator seems can be dumped under pypy.

so I turn to pypy, but still cant dump “env“ object.

error info is that:

PS D:\tests> pypy3 test_dump.py
Start parking at 0
Start driving at 5
Start parking at 7
Start driving at 12
Start parking at 14
env pause
Traceback (most recent call last):
File "test_dump.py", line 20, in
pickle.dump(env, f)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 1598, in _dump
_Pickler(file, protocol, fix_imports=fix_imports).dump(obj)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 450, in dump
self.save(obj)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 562, in save
self.save_reduce(obj=obj, *rv)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 675, in save_reduce
save(state)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 517, in save
f(self, obj) # Call unbound method with explicit self
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 872, in save_dict
self._batch_setitems(obj.items())
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 898, in _batch_setitems
save(v)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 517, in save
f(self, obj) # Call unbound method with explicit self
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 832, in save_list
self._batch_appends(obj)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 859, in _batch_appends
save(tmp[0])
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 517, in save
f(self, obj) # Call unbound method with explicit self
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 802, in save_tuple
save(element)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 562, in save
self.save_reduce(obj=obj, *rv)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 675, in save_reduce
save(state)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 517, in save
f(self, obj) # Call unbound method with explicit self
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 872, in save_dict
self._batch_setitems(obj.items())
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 898, in _batch_setitems
save(v)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 517, in save
f(self, obj) # Call unbound method with explicit self
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 832, in save_list
self._batch_appends(obj)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 859, in _batch_appends
save(tmp[0])
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 562, in save
self.save_reduce(obj=obj, *rv)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 651, in save_reduce
save(args)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 517, in save
f(self, obj) # Call unbound method with explicit self
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 787, in save_tuple
save(element)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 562, in save
self.save_reduce(obj=obj, *rv)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 675, in save_reduce
save(state)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 517, in save
f(self, obj) # Call unbound method with explicit self
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 872, in save_dict
self._batch_setitems(obj.items())
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 898, in _batch_setitems
save(v)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 562, in save
self.save_reduce(obj=obj, *rv)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 646, in save_reduce
save(cls)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 517, in save
f(self, obj) # Call unbound method with explicit self
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 1029, in save_type
return self.save_global(obj)
File "D:\soft\dev\python\pypy3.7-v7.3.5-win64\lib-python\3\pickle.py", line 973, in save_global
(obj, module_name, name)) from None
pickle.PicklingError: Can't pickle <class 'generator'>: it's not found as builtins.generator

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.