抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Python 仿真库 SimPy,安装、结构和基本概念

学习笔记参考SimPy 文档

SimPy 简介

"SimPy 是基于过程的离散事件的标准 Python 模拟框架"
SimPy 文档

SimPy 安装

SimPy 基本概念

SimPy 是离散事件驱动的仿真库。所有活动部件,例如车辆、顾客,即便是信息,都可以用 process 来模拟。这些 process 存放在 environment 中。所有 process 之间,以及与 environment 之间的互动,通过 event 来进行。

SimPy 可以看作一个异步事件分发器,生成一些事件并在给定的仿真时间安排它们。事件按优先级仿真时间递增的事件id排序。事件还具有回调列表,这些回调在事件触发和处理时执行。事件也可能有返回值。

涉及的组件是编写的环境(Envirement)事件(events)进程(process)函数

环境(Environment)

环境(Environment)将这些事件(events)存储在其事件列表中,并跟踪当前仿真时间

进程(process)

进程(process)函数实现仿真模型,即定义仿真行为。它们可以看作是挂起事件实例的普通的 Python 生成器函数。进程在生命周期中可以创造并挂起(yield)事件(Events),等待事件的触发

  • 当进程生成事件时,该进程将被挂起。当事件发生时(事件已触发),SimPy 恢复进程。多个进程可以等待同一事件。SimPy 按照生成事件的统一顺序进行恢复

  • 启动进程涉及两步:
    1. 必须调用 Process 函数才能创建生成器对象。(这不会执行该函数的任何代码。见 Python yield 关键字

    2. 然后创建进程实例,并将环境和生成器对象传递给它。这将在当前仿真时间安排一个初始化事件,启动进程函数的执行。进程实例也是进程函数返回时触发的事件。

  • 默认情况下,只要事件列表中有事件,它就会运行,但您也可以通过提供until参数让它提前停止(请参见仿真控件)。

事件(events)

其中一类重要的事件Timeout,这类事件允许一段时间后再被激活,用来表达一个进程休眠或者保持当前的状态持续指定的一段时间。这类事件通过 Environment.timeout 来调用

Python yield 关键字

看作 return。举例说明。

Example 1.1

运行过程:

  • 程序开始执行以后,因为 foo() 中有 yield 关键字,所以 foo() 并不会真的执行,而是先得到一个生成器 g(相当于一个对象);
  • 调用 next(g)foo() 正式开始执行,先执行 print("starting..."),然后进入 while
  • 程序遇到 yield 关键字,把yield 想成 returnreturn 了一个 4 之后,程序停止,并没有执行赋值给 res 操作,此时 next(g) 执行完成,所以输出的前两行第一个是 while 上面 print 的结果,第二个是return出的结果;
  • 程序执行 print("*"20)
  • 又开始执行下面的 print(next(g)),从刚才那个next程序停止的地方开始执行,也就是要执行 res 的赋值操作,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候 res 赋值是 None,所以接着下面的输出就是 res:None
  • 程序会继续在 while 里执行,又一次碰到yield,这个时候同样 return 出 4,然后程序停止,print 函数输出的 4 就是这次 return 出的 4。

Example 1.2

运行过程:

  • 程序执行 g.send(7),程序会从 yield关键字那一行继续向下运行,send 会把 7 这个值赋值给 res 变量;
  • 由于 send 方法中包含 next() 方法,所以程序会继续向下运行执行 print,然后再次进入 while;
  • 程序执行再次遇到 yield 关键字,yield 会返回后面的值后,程序再次暂停,直到再次调用 next方法或 send 方法。

Python 生成器

使用了 yield 的函数被称为生成器函数。生成器函数可以在迭代过程中逐步产生值,而不是一次性返回所有结果。生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回;然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。

生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。

调用一个生成器函数,返回的是一个迭代器对象

Example 1.3

生成器函数实现费波拉契数列

运行结果




SimPy 学习




本站采用 Volantis 主题设计