【待分类】用 SimPy 进行离散事件仿真(一)入门篇

官网链接

SimPy is a process-based discrete-event simulation framework based on standard Python.

1. 概念理解

simpy 中的几个重点概念

  • environment -环境,相当于一个计时器
  • Process -对象,比如一个car 一个driver 都是process
  • Event - 事件,仿真触发事件
  • Resource- 资源,

2. SimPy in 10 Minutes

2.0 Installation

2.1 Basic Concepts

通过一个车辆停车和行驶的例子,
理解yield, env.now, env.timeout, env.poricess, env.run的意义。

import simpy
def car(env):# 此处,car 就是一个process
     while True:
        print('Start parking at %d' % env.now) #env.now 当前仿真环境的时间
        parking_duration = 5
        yield env.timeout(parking_duration) # env.timeout(time)结束这个事件的时间

        print('Start driving at %d' % env.now)
        trip_duration = 2
        yield env.timeout(trip_duration)

if __name__ == '__main__':
	env = simpy.Environment()# 创建一个simpy 环境
	env.process(car(env))# 开始car 这个进程
	env.run(until=15)# 仿真的结束时间
#输出结果
Start parking at 0
Start driving at 5
Start parking at 7
Start driving at 12
Start parking at 14

Process finished with exit code 0

2.2 Process Interaction

process 之间可以相互影响

The Process instance that is returned by Environment.process() can be utilized for process interactions. The two most common examples for this are to wait for another process to finish and to interrupt another process while it is waiting for an event.

wait

interrupt

import simpy


class Car(object):
    def __init__(self, env):
        self.env = env
        self.action = env.process(self.run()) # 这里已经触发了 run 这个event

    def run(self):
        while True:
            print(f"start parking and charging at {self.env.now}")
            charge_duration = 5
            try:# 未被打断执行的process:charge
                yield self.env.process(self.charge(charge_duration))
            except simpy.Interrupt:# 被打断后执行的动作
                print(f"was interrupted. hope the cattery is full enough...")

            print(f"start driving at {self.env.now}")
            trip_duration = 2
            yield self.env.timeout(trip_duration)

    def charge(self, duration):
        yield self.env.timeout(duration)


def driver(env, car):
    yield env.timeout(3)
    car.action.interrupt()# 这里打断了一个process


if __name__ == '__main__':
    env = simpy.Environment()
    car = Car(env)
    env.process(driver(env, car)) # driver 这个process内含一个 interrupt
    env.run(until=15)

# 运行结果
start parking and charging at 0
was interrupted. hope the cattery is full enough...
start driving at 3
start parking and charging at 5
start driving at 10
start parking and charging at 12

Process finished with exit code 0

2.3 Shared Resources

有三种resources,下面简单介绍Resource

SimPy offers three types of resources that help you modeling problems, where multiple processes want to use a resource of limited capacity (e.g., cars at a fuel station with a limited number of fuel pumps) or classical producer-consumer problems.
In this section, we’ll briefly introduce SimPy’s Resource class.

resource 可以用 request() 方法,等到资源可用时 process 开始。

The resource’s request() method generates an event that lets you wait until the resource becomes available again. If you are resumed, you “own” the resource until you release it.

with 方法可以自动释放资源。

If you use the resource with the with statement as shown above, the resource is automatically being released.
If you call request() without with, you are responsible to call release() once you are done using the resource.

import simpy


def car(env,name,bcs,driving_time,charge_duration):
    yield env.timeout(driving_time)

    print(f"{name} arriving at {env.now}")
    with bcs.request() as req:# 用 with 可以自动释放资源
        yield req
        print(f"{name} starting to charge at {env.now}")
        yield  env.timeout(charge_duration)
        print(f"{name} leaving the bcs at {env.now}")


if __name__ == '__main__':
    env = simpy.Environment()
    bcs=simpy.Resource(env,capacity=2) # 创建资源,其容量为2

    for i in range(4):
        env.process(car(env,f"car {i}",bcs,i*2,5))
    env.run()

2.4 How to Proceed

看官方文档和例子。

其他资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值