使用 SimPy 进行离散事件模拟的基础知识
SimPy 是一个强大的基于过程的离散事件模拟框架,用Python编写。
安装 :
要安装 SimPy,请使用以下命令 -
pip install simpy
基本概念 :
SimPy 背后的核心思想是Python中的生成器函数。普通函数和生成器的区别在于普通函数使用“return”语句,而生成器使用“yield”语句。
如果函数有 return 语句,那么即使在多个函数调用中,它也会返回相同的值。例如——
def func():
return 1
return 2
在运行时调用 func() 时,总是会在 return 语句的第一个实例处返回,即函数func() 总是返回 1,永远不会执行下一个 return 语句。
但是,在离散事件模拟中,我们可能需要找到系统在给定时间 T 的状态。为此,需要记住 T 之前的区间状态,然后执行给定的模拟并返回状态在时间 T。
这就是生成器函数非常有用的地方。例如,考虑以下函数
def func():
while True:
yield 1
yield 2
现在,当这个函数第一次被调用时,它'yield' 1。但是,在下一次调用时,它将产生2。在某种意义上,它记住了它在最后一次调用时返回的内容,然后继续下一个调用产量声明。
SimPy 中的事件称为进程,由它们自己的生成器函数定义。这些过程发生在环境中。 (把环境想象成一个大盒子,里面保存着进程。)
考虑一个简单的例子,涉及交通灯的模拟——
# Python 3 code to demonstrate basics of SimPy package
# Simulation of a Traffic Light
# import the SimPy package
import simpy
# Generator function that defines the working of the traffic light
# "timeout()" function makes next yield statement wait for a
# given time passed as the argument
def Traffic_Light(env):
while True:
print ("Light turns GRN at " + str(env.now))
# Light is green for 25 seconds
yield env.timeout(25)
print ("Light turns YEL at " + str(env.now))
# Light is yellow for 5 seconds
yield env.timeout(5)
print ("Light turns RED at " + str(env.now))
# Light is red for 60 seconds
yield env.timeout(60)
# env is the environment variable
env = simpy.Environment()
# The process defined by the function Traffic_Light(env)
# is added to the environment
env.process(Traffic_Light(env))
# The process is run for the first 180 seconds (180 is not included)
env.run(until = 180)
输出 :
Light turns GRN at 0
Light turns YEL at 25
Light turns RED at 30
Light turns GRN at 90
Light turns YEL at 115
Light turns RED at 120
在此代码中,生成器函数Traffic_Light(env) 将环境变量作为参数,并在 env.run()函数中作为参数传递的时间段内模拟交通灯的操作。 (实际上,SimPy 中的时间是无单位的。虽然它可以根据方便转换为小时、分钟或秒)。 env.now 返回已用时间的当前值。
env.timeout()函数是此模拟的基础,因为它等待作为参数传递的时间在计算机的模拟时钟(它不是实时时钟)上经过,然后启动下一个 yield 语句,直到在 env.run() 中作为参数传递的时间已经结束。
env.run() 同时启动所有链接到环境的进程 = 0。