SimPy

2023-11-13

简介

  SimPy是一个基于Python的异步事件调度器,产生一系列事件并按照仿真时间进行计划安排升序排列,在事件的循环序列中触发并执行,产生回调返回响应值,在物流,工厂制造业和餐饮服务业等工业仿真中都有所应用,比如优化快递分拣中的排班表,优化工厂制造的排班和成本,估算服务排队的时长等,还可以用于网络通信仿真.详细介绍可查阅官方文档原理介绍,另有知乎简介.

安装命令
pip install simpy
Environment

Environment管理仿真时间的进行,让各种组件和事件按照一定的计划表进行驱动,管理仿真元素之间的关联, 主要 API 有

simpy.Environment.process  #添加仿真进程
simpy.Environment.event  #创建事件
simpy.Environment.timeout  #提供延时(timeout)事件
simpy.Environment.until  #仿真结束的条件(时间或事件)
simpy.Environment.run  #仿真启动
simpy.Environment.all_of
simpy.Environment.any_of

创建一个空的仿真环境并实例化,然后执行一段时间,这时由于没有创建任何组件和事件,所以实际上什么也没有发生,也可以使用处理进程或事件作为结束条件

env=simpy.Environment()#创建环境并实例化
env.run(until=100)#运行仿真环境,100s后停止
Events

simpy.events.Event是仿真事件,simpy是以事件作为基础组件进行构建的,各种其它类型如events.Process,events.Timeout都是以事件派生出来的,本质上还是Event.

events.Event
|
+— events.Timeout
|
+— events.Initialize
|
+— events.Process
|
+— events.Condition
|  |
|  +— events.AllOf
|  |
|  +— events.AnyOf

创建一个事件并定义响应函数,这个事件一旦调用之后就结束了,不会再响应了,在process event中也是如此.

import simpy

def my_callback(event):
    print('Called back from', event)
env = simpy.Environment()
event = env.event()
event.callbacks.append(my_callback)#给事件添加回调
event.callbacks

事件若被触发,按给定的调度事件放入队列,Event.triggered变为True,事件响应函数理完后Event.processed设为True,能获取返回值

Event.value或value=yield event

也可以将事件记为成功或失败

Event.succed(value=None)#记为成功
Event.fail(exception)#记为失败
Event.trigger(event)#记为触发

process进程也是事件

env.process()#处理时间的进程也是一个事件

所以process能产生执行另一个process,其执行结束后这个process恢复,另一个process能传给这个process返回值,创建process后,触发执行时会有Initialize事件,但不必手动处理这个.

simpy.util.start_delayed()#使process进程延迟触发
>>> from simpy.util import start_delayed
>>>
>>> def sub(env):
...     yield env.timeout(1)
...     return 23
...
>>> def parent(env):
...     start = env.now
...     sub_proc = yield start_delayed(env, sub(env), delay=3)
...     assert env.now - start == 3
...
...     ret = yield sub_proc
...     return ret
...
>>> env.run(env.process(parent(env)))
23

Condition条件事件,有时需要等待其它的事件执行出想要的结果,然后以此为条件进行事件的触发或执行,有events.AllOf和events.AnyOf事件.

>>> from simpy.events import AnyOf, AllOf, Event
>>> events = [Event(env) for i in range(3)]
>>> a = AnyOf(env, events)  # Triggers if at least one of "events" is triggered.
>>> b = AllOf(env, events)  # Triggers if all each of "events" is triggered.

也可以不用AllOf和AnyOf,转而使用逻辑运算符&,|定义条件事件

>>> def test_condition(env):
...     t1, t2 = env.timeout(1, value='spam'), env.timeout(2, value='eggs')
...     ret = yield t1 | t2
...     assert ret == {t1: 'spam'}
...
...     t1, t2 = env.timeout(1, value='spam'), env.timeout(2, value='eggs')
...     ret = yield t1 & t2
...     assert ret == {t1: 'spam', t2: 'eggs'}
...
...     # You can also concatenate & and |
...     e1, e2, e3 = [env.timeout(i) for i in range(3)]
...     yield (e1 | e2) & e3
...     assert all(e.processed for e in [e1, e2, e3])
...
>>> proc = env.process(test_condition(env))
>>> env.run()
>>> def fetch_values_of_multiple_events(env):
...     t1, t2 = env.timeout(1, value='spam'), env.timeout(2, value='eggs')
...     r1, r2 = (yield t1 & t2).values()
...     assert r1 == 'spam' and r2 == 'eggs'
...
>>> proc = env.process(fetch_values_of_multiple_events(env))
>>> env.run()
Sleep until woken up

模型为,一辆汽车在行驶一段时间后停车一段时间,停车期间进行充电,所以需要在执行停车事件时激活充电时间.

>>> from random import seed, randint
>>> seed(23)
>>>
>>> import simpy
>>>
>>> class EV:
...     def __init__(self, env):
...         self.env = env
...         self.drive_proc = env.process(self.drive(env))
...         self.bat_ctrl_proc = env.process(self.bat_ctrl(env))
...         self.bat_ctrl_reactivate = env.event()
...
...     def drive(self, env):
...         while True:
...             # Drive for 20-40 min
...             yield env.timeout(randint(20, 40))
...
...             # Park for 1–6 hours
...             print('Start parking at', env.now)
...             self.bat_ctrl_reactivate.succeed()  # "reactivate"
...             self.bat_ctrl_reactivate = env.event()
...             yield env.timeout(randint(60, 360))
...             print('Stop parking at', env.now)
...
...     def bat_ctrl(self, env):
...         while True:
...             print('Bat. ctrl. passivating at', env.now)
...             yield self.bat_ctrl_reactivate  # "passivate"
...             print('Bat. ctrl. reactivated at', env.now)
...
...             # Intelligent charging behavior here …
...             yield env.timeout(randint(30, 90))
...
>>> env = simpy.Environment()
>>> ev = EV(env)
>>> env.run(until=150)
Bat. ctrl. passivating at 0
Start parking at 29
Bat. ctrl. reactivated at 29
Bat. ctrl. passivating at 60
Stop parking at 131
Waiting for another process to terminate

上一个充电休眠的例子中会有一个问题,停车事件可能比充电时间短,一方面在停车充电,一方面停车结束正在驾驶,这时矛盾的.为此可以这样解决,开始停车时开始充电,然后只有到停车和充电都结束的时候,才开始驾驶,这里用到了条件事件&.

>>> class EV:
...     def __init__(self, env):
...         self.env = env
...         self.drive_proc = env.process(self.drive(env))
...
...     def drive(self, env):
...         while True:
...             # Drive for 20-40 min
...             yield env.timeout(randint(20, 40))
...
...             # Park for 1–6 hours
...             print('Start parking at', env.now)
...             charging = env.process(self.bat_ctrl(env))
...             parking = env.timeout(randint(60, 360))
...             yield charging & parking
...             print('Stop parking at', env.now)
...
...     def bat_ctrl(self, env):
...         print('Bat. ctrl. started at', env.now)
...         # Intelligent charging behavior here …
...         yield env.timeout(randint(30, 90))
...         print('Bat. ctrl. done at', env.now)
...
>>> env = simpy.Environment()
>>> ev = EV(env)
>>> env.run(until=310)
Start parking at 29
Bat. ctrl. started at 29
Bat. ctrl. done at 83
Stop parking at 305
Interrupting another process

现在又有一个问题,汽车只能等待电池完全充满的时候才能开始驾驶,如果将条件事件改为停车或充电结束的时候就开始驾驶,那么有时就要中断充电进程,使用process.interrupt()中断一个进程.

class EV:
    def __init__(self, env):
        self.env = env
        self.drive_proc = env.process(self.drive(env))

    def drive(self, env):
        while True:
            # Drive for 20-40 min
            yield env.timeout(randint(20, 40))

            # Park for 1 hour
            print('Start parking at', env.now)
            charging = env.process(self.bat_ctrl(env))
            parking = env.timeout(60)
            yield charging | parking
            if not charging.triggered:
                # Interrupt charging if not already done.
                charging.interrupt('Need to go!')
            print('Stop parking at', env.now)

    def bat_ctrl(self, env):
        print('Bat. ctrl. started at', env.now)
        try:
            yield env.timeout(randint(60, 90))
            print('Bat. ctrl. done at', env.now)
        except simpy.Interrupt as i:
            # Onoes! Got interrupted before the charging was done.
            print('Bat. ctrl. interrupted at', env.now, 'msg:',
                  i.cause)

>>> env = simpy.Environment()
>>> ev = EV(env)
>>> env.run(until=100)
Start parking at 31
Bat. ctrl. started at 31
Stop parking at 91
Bat. ctrl. interrupted at 91 msg: Need to go!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SimPy 的相关文章

  • python操作leveldb数据库

    1 leveldb简介 优点 1 leveldb是一个开源的持久化的键值数据库 2 具有很高的随机写 顺序读写性能 但是随机读性能一般 适合写多读少的场景 在一台4核Q6600的CPU机器上 每秒钟写数据超过40w 而随机读的性能每秒钟超过
  • vue小技巧:性能优化使用篇 => 路由/tab切换取消当前页面异步请求

    tab在前端是非常常见的一个组件 在vue里面 结合了双向绑定原理 更是将页面无感刷新提升到了极致 假设每个tab选项都需要请求一次接口 做一次异步操作 但是假如我们有一个手速超快的人 我摊牌了 就是我 他在一秒钟内能切换3次tab选项 也
  • redis zset利用并集求差集

    解决的痛点是缓存里的数据结构 zset 有序集合 它只能做并集 交集 不能做差集 我的需求是需要它做差集 总的内容缓存 差 用户已看的缓存 就能得到 用户没有看的 也就是接下来要给用户看的内容我的思路是利用并集操作完成 内容的缓存池 val
  • Unity中关于Destroy的API

    Unity中关于Destroy的API 常用的关于Destory的API 销毁游戏物体 Destroy gameObject 从游戏物体删除该脚本 Destroy this 从游戏物体删除刚体 Destroy rigidbody 加载物体5
  • 红帽官宣新任总裁兼 CEO!转型关键人物 Paul Cormier “退而不休”

    整理 郑丽媛 出品 CSDN ID CSDNnews 在今年 5 月的红帽峰会上 曾有传言称红帽总裁兼 CEO Paul Cormier 可能很快就会退休 事实证明 这一传言有所偏差 Paul Cormier 的确要退位 但并没有打算退休
  • 「干货分享」DevExpress常用控件——RichEditControl使用指南

    做WinForms的一般都知道 传统 NET界面有一个RichTextBox控件 这个是一个富文本控件 可以存储图片文字等内容 它有自己的文件格式RTF 在DevExpress控件组里面也有一个同等的控件 他的名字是RichEditCont
  • k8s-如何快速编写yaml文件(新手)

    k8s 如何快速编写yaml文件 新手 1 使用kubectl create 命令生成yaml文件 kubectl create depolyment web image nginx o yaml dty run depolyment 工作
  • 升级到Window11体验

    1 把禁掉的微软更新服务开启 2 去官网按照指导来 用微软账号 3 打开Window预览体验计划 比较慢 不要开代理不然会有错误 多转几圈多等一会儿 其次就是最近网络有问题虽然能够上网图标却显示未连接Internet 4 登录之前在官网弄的
  • 操作系统修炼秘籍(1):秘籍简介

    毋庸置疑 操作系统 Operating System OS 是一个非常大的概念 涉及到的内容非常非常多 在探讨它的时候 往往会将操作系统置于一个比较底层的角度去对待 这也使得多数人对OS是 闻之丧胆 对OS相关的资料或概念也是望而却步 这也
  • python编程基础-task5-面向对象的编程

    一 类的例子 class Song object class表示要创建类 Song是类的名称 def init self lyrics self lyrics lyrics 这里是设置了lyrics是的全局变量 后面的类里都可以使用这个参数
  • 数据结构——线性表

    线性表 线性表是最基本的 最常见的一种数据结构 1 1 前驱元素 若A元素在B元素的前面 则称A为B的前驱元素 后继元素 若B元素在A元素的后面 则称B为A的后继元素 1 2 线性表的特征 数据元素之间只有一对一的关系 第一个数据元素没有前
  • 初识Node.js与内置模块

    目录 1 初识 Node js 1 1 回顾与思考 1 2 Node js 简介 1 3 Node js 环境的安装 2 fs 文件系统模块 2 1 什么是 fs 文件系统模块 2 2 读取指定文件中的内容 2 3 向指定的文件中写入内容
  • MyCAT简易入门

    MyCAT简易入门 MyCAT是mysql中间件 前身是阿里大名鼎鼎的Cobar Cobar在开源了一段时间后 不了了之 于是MyCAT扛起了这面大旗 在大数据时代 其重要性愈发彰显 这篇文章主要是MyCAT的入门部署 一 安装java 因
  • 印度 SaaS 的崛起

    引言 云创新作为全球范围的努力已超过二十年 改变了整个行业 现在 印度正在成为一个新兴的全球领导者 推动了技术创新和显著的企业家精神 SaaS在全球范围内继续加速发展 因为各行业和企业都在向云上转移 随着数字化持续增长 印度成立的SaaS初
  • qgis 3.30 python二次开发环境搭建,一遍过教程

    qgis 3 30 python二次开发环境搭建 一遍过教程 1 使用mamba加速conda下载qgis 2 创建qgis虚拟环境 3 设置环境变量 4 测试代码 5 qgis库代码提示 6 参考链接和推荐链接 1 使用mamba加速co
  • JVM 字节码从入门到精通

    小册介绍 也许你写了无数行代码 会用很多炫酷的语法糖和高级的框架 但你未必了解这些高级语言背后的执行过程 即使对于一名经验丰富的 Java 程序员 在阅读 Java 字节码的时候也会感到很枯燥 我们为什么需要深入了解如此底层的信息呢 0x0
  • 《数智碳中和》白皮书发布以数智技术助力关键相关方实现碳达峰碳中和

    实现碳达峰 碳中和是一场广泛而深刻的经济社会系统性变革 促进能源转型升级成为实现双碳战略目标所需的重要一环 政府监管部门 能源生产企业 能源输送企业 能源消费用户及金融投资机构是实现双碳目标的关键力量 也是参与全国碳市场的重要主体 他们将以

随机推荐

  • Visual Studio 出现warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失。 解决方案 转载的文章

    问题 Visual Studio 出现warning C4819 该文件包含不能在当前代码页 936 中表示的字符 请将该文件保存为 Unicode 格式以防止数据丢失 解决方案 1 修改字符编码格式 推荐 Visual Studio提供高
  • 从类声明中探索Qt的UI组合开发模式-组合模式

    引言 在使用Qt的的的的的开发引用程序的时候 有的会用UI设计师来设计UI界面 有的则的英文直接在代码中写 那么那种好呢 笔者认为使用UI设计师是最好的 尽管会生成许多多余的代发 Qt的的组合开发模式 Qt的这样的设计是一种MVC的逻辑 可
  • 关于iostat中await的理解

    关于iostat中await的理解 await 每个I O平均所需的时间 rd ticks wr ticks rd ios wr ios 不仅包括硬盘设备处理I O的时间 还包括了在kernel队列中等待的时间 rd ticks 读操作消耗
  • linux 6中4T磁盘识别并分区格式化挂接

    存储端划分4T的LUN后 主机端操作如下 1 主机识别 本例中hba卡的端口是host11和host12 root db1 echo gt sys class scsi host host11 scan root db1 echo gt s
  • Netlink 内核实现分析(一):创建

    http blog csdn net luckyapple1028 article details 50839395 Netlink 是一种IPC Inter Process Commumicate 机制 它是一种用于内核与用户空间通信的机
  • Resnet 18网络模型

    1 残差网络 Resnet 残差块 让我们聚焦于神经网络局部 如图左侧所示 假设我们的原始输入为x 而希望学出的理想映射为f x 作为上方激活函数的输入 左图虚线框中的部分需要直接拟合出该映射f x 而右图虚线框中的部分则需要拟合出残差映射
  • Canalys 2020Q2报告:百度智能云稳坐第一阵营 AI打造差异化竞争力

    在AI新基建领域的持续布局下 百度智能云站稳中国云市场第一阵营 9月9日消息 据英国调研机构Canalys发布的2020年第二季度中国基础云市场报告显示 中国云计算市场整体规模达43亿美金 同比增长70 突破新纪录 其中 头部四家厂商市场占
  • 手机热点总是正在连接服务器,电脑连接手机热点无法上网的三种解决方法

    电脑连接手机热点无法上网的三种解决方法 方法一 网络诊断 右键点击通知栏的网络图标 打开网络和共享中心 如图所示 在网络和共享中心 找到所连接的手机网络热点并点击它 如图所示 点击 诊断 功能 诊断网络无法连接的问题 如图所示 系统的网络诊
  • 网络分层模型

    OSI七层模型 物数网传会表应 物理层 主要定义物理设备标准 如网线的接口类型 光纤的接口类型 各种传输介质的传输速率等 它的主要作用是传输比特流 就是由1 0转化为电流强弱来进行传输 到达目的地后再转化为1 0 也就是我们常说的数模转换与
  • 性能综述方法论

    性能问题和Bug不同 后者的分析和解决思路更清晰 很多时候从应用日志 文中的应用指分布式服务下的单个节点 即可直接找到问题根源 而性能问题 其排查思路更为复杂一些 对应用进行性能优化 是一个系统性的工程 对工程师的技术广度和技术深度都有所要
  • fiery服务器不显示,fiery服务器打印设置

    fiery服务器打印设置 内容精选 换一换 在创建数据库连接之后 才能使用它来执行SQL语句操作数据 JDBC提供了三个方法 用于创建数据库连接 DriverManager getConnection String url DriverMa
  • 矩阵的秩与行列式的几何意义

    这里首先讨论一个长期以来困惑工科甚至物理系学生的一个数学问题 即 究竟什么是面积 以及面积的高维推广 体积等 1 关于面积 一种映射 大家会说 面积 不就是长乘以宽么 其实不然 我们首先明确 这里所讨论的面积 是欧几里得空间几何面积的基本单
  • spring boot jar部署 控制台 日志 乱码

    spring boot jar部署 控制台 日志 乱码 问题描述 spring boot jar包部署 通过java jar 命令运行 jar文件 代码中通过变量log输出到控制台的中文 乱码 但是仅仅是在运行jar时才乱码 而在用ecli
  • Mybatis源码分析:MapperMethod中内部静态类MethodSignature的作用

    MethodSignature分析 MethodSignature为MapperMethod类提供了三个作用 获取待执行方法中的参数和 Param注解标注的参数名 获取标注有 MapKey的参数 Mapkey作用在后续会讲到 方法的返回类型
  • SQLSERVER-CASE关键词的用法 .

    在Oralce中有个函数为Decode 感觉非常好用 但是此函数为Oracle所独有 在SQLSERVER和MYSQL中实现与之相类似的功能还无相关函数 但通过CASE关键词可实现类似功能 1 首先让我们看一下 CASE 的语法 在一般的
  • 僵尸进程及其处理

    进程 一个可并发执行的程序在一个数据集上的一次运行 即程序的一次运行过程 进程与程序的关系 程序是进程的一个组成部分 是进程的执行文本 进程是程序的执行过程 僵尸进程 进程主体结束 但是进程的PCB依旧存在 在多进程编程中 父进程未结束 但
  • 用U盘安卓esxi虚拟机出现 error loading /s.v00 错误解决办法

    前段时间用 一个 白色的 东芝U盘 给戴尔 R720服务器安装 esxi 6 0时 在加载到 s v00 找个文件时出现错误 大致为 error loading s v00 compressed MD5 xxxxxxx decompress
  • vue3快速入门-Teleport传送(瞬移组件)

    Vue 的组件架构使我们能够将用户界面构建为能够精美地组织业务逻辑和表示层的组件 Teleporting是Vue 3发布带来的一项新功能 它的灵感来自React Portals 相同的门户是 React 中的一个常见功能 在 Vue2 的
  • 2023最新100道渗透测试面试题(附答案)

    眨眼间2023年快过去一半了 不知道大家有没有找到心仪的工作呀 今天我给大家整理了100道渗透测试面试题给大家 需要答案的话可以在评论区给我留言哦 第一套渗透面试题 什么是渗透测试 它的目的是什么 渗透测试的五个阶段是什么 您如何选择正确的
  • SimPy

    目录 简介 安装命令 Environment Events Sleep until woken up Waiting for another process to terminate Interrupting another process