📜  使用 SimPy 进行离散事件模拟的基础知识

📅  最后修改于: 2022-05-13 01:55:12.138000             🧑  作者: Mango

使用 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。