python语言例子_【Python】SimPy的使用示例-Go语言中文社区

使用SimPY进行离散事件仿真

SimPY是一个Python下的第三方库,可以方便的进行离散事件的仿真。仿真速度比较快。下面记录一下我的一点心得,不保证完全正确,供参考。

安装

$ pip install -U simpy

pycharm可以再File | Settings | Project: Simulation | Project Interpreter中添加

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hlbGxvWkVY,size_16,color_FFFFFF,t_70

主要概念

Environment

Process

Event

Resource

SimPY使用Environment,Process,Event,Resource四大概念来进行离散事件的仿真。

Environment就是整体仿真所在的时间,主要用于提取时间。

Process就是仿真过程中的实体,如:顾客, 设备, 车辆等。 Process本质上也是一个event。源代码里面可以看到是继承Event的一个类。

Event是仿真中触发的事件,可以理解为一个定时器。当定时器到时时,触发事件。

Resource是仿真中的资源,如ATM机,服务器等。

官方示例:

>>> import simpy

>>>

>>> def clock(env, name, tick):

... while True:

... print(name, env.now)

... yield env.timeout(tick)

...

>>> env = simpy.Environment()

>>> env.process(clock(env, 'fast', 0.5))

>>> env.process(clock(env, 'slow', 1))

>>> env.run(until=2)

fast 0

slow 0

fast 0.5

slow 1

fast 1.0

fast 1.5

逻辑很简单,

1. 创建一个env

2. 以env为参数创建process, process有名字和参数,process内部使用生成器直接调用了超时事件。

3. 运行该env

深入原理

通过SimPY的源代码可以了解到,SimPY使用了一个heapq队列,这个队列中的元素是事件。Environment中对这个 队列进行调度,实际上是将事件压入队列中,environment中还有step方法,就是从队列中取出时间最小的一个事件(也就是时间点上最接近当前时间的下一个事件,使用heapq的heappop方法),然后运行这个事件的callback函数,一般就是Process。 因此仿真实际上是对一系列事件进行压入队列,按时间序弹出队列的过程。这样可以避免使用时间步长进行步进,时间步长步进的缺点就是太慢了。必须一个时间步长一个时间步长的挨个遍历过去,如果时间步长不合理的话,会有大量的计算时间上的浪费。

另外,为了语法上的优美易用,env中使用了Python的反射机制,将常用的几种事件,包括Process, Timeout, Anyof, Allof, Event都绑定为env的一种方法。 这个语法看上去很简单,但实现机制相对有点难以理解(我也只是了解是一种反射),只需要记住类似env.process, env.timeout, env.event, env.all_of, env.any_of的方法调用实际上都是声明了simpy.Process, simpy.Timeout等类的就可以了。详细实现在simpy.core.py中。

稍微复杂一点的例子:

"""

服务站示例

场景介绍:

一个有特定服务提供工作站,客户服务时长不一,工作机器数有限。

Client接受服务步骤:Client到达工作站,若有空闲的机器就立刻接受服务,如果没有,就等待直到其他机器空闲下来。

每个接受过服务的Client都有一个完成满意度(或者为进度)实时统计服务客户数和完成满意进度。

"""

import random

import simpy

# 可接受输入参数

RANDOM_SEED = 0 # 不设置

NUM_MACHINES = 2 # 可以同时处理的机器数(类似工作工位数)

TIME_CONSUMING = 5 # 单任务耗时 (可以设计成随机数)

TIME_INTERVAL = 5 # 来车的间隔时间约5分钟 (可以设计成随机数)

SIM_TIME = 1000 # 仿真总时间

CLIENT_NUMBER = 2 # 初始时已经占用机器数

class WorkStation(object):

"""

一个工作站,拥有特定数量的机器数。 一个客户首先申请服务。在对应服务时间完成后结束并离开工作站

"""

def __init__(self, env, num_machines, washtime):

self.env = env

self.machine = simpy.Resource(env, num_machines)

self.washtime = washtime

self.allClient = 0

self.accomplishClient = 0

def wash(self, car):

"""服务流程"""

yield self.env.timeout(random.randint(2, 10)) # 假设服务时间为随机数(2~10)

self.allClient += 1

per = random.randint(50, 99)

print("%s's 任务完成度:%d%%." % (car, per))

if per > 80:

self.accomplishClient += 1

print("工作站服务客户数:%d,"

"工作站服务达标率:%.2f。" % (self.allClient, float(self.accomplishClient) / float(self.allClient)))

def Client(env, name, cw):

"""

客户到达动作站接受服务,结束后离开

"""

print('%s 到达工作站 at %.2f.' % (name, env.now))

with cw.machine.request() as request:

yield request

print('%s 接受服务 at %.2f.' % (name, env.now))

yield env.process(cw.wash(name))

print('%s 离开服务站 at %.2f.' % (name, env.now))

def setup(env, num_machines, washtime, t_inter, clientNumber):

"""创建一个工作站,几个初始客户,然后持续有客户到达. 每隔t_inter - 2, t_inter + 3分钟(可以自定义)."""

# 创建工作站

workstation = WorkStation(env, num_machines, washtime)

# 创建clientNumber个初始客户

for i in range(clientNumber):

env.process(Client(env, 'Client_%d' % i, workstation))

# 在仿真过程中持续创建客户

while True:

yield env.timeout(random.randint(t_inter - 2, t_inter + 3)) # 3-8分钟

i += 1

env.process(Client(env, 'Client_%d' % i, workstation))

# 初始化并开始仿真任务

print('开始仿真')

# 初始化seed,指定数值的时候方正结果可以复现

random.seed()

# 创建一个环境并开始仿真

env = simpy.Environment()

env.process(setup(env, NUM_MACHINES, TIME_CONSUMING, TIME_INTERVAL, CLIENT_NUMBER))

# 开始执行!

env.run(until=SIM_TIME)

输出:

开始仿真

Client_0 到达工作站 at 0.00.

Client_1 到达工作站 at 0.00.

Client_0 接受服务 at 0.00.

Client_1 接受服务 at 0.00.

Client_2 到达工作站 at 3.00.

Client_0's 任务完成度:54%.

工作站服务客户数:1,工作站服务达标率:0.00。

Client_3 到达工作站 at 7.00.

Client_0 离开服务站 at 7.00.

Client_2 接受服务 at 7.00.

Client_1's 任务完成度:97%.

工作站服务客户数:2,工作站服务达标率:0.50。

.

.

.

Client_179 接受服务 at 986.00.

Client_178 离开服务站 at 986.00.

Client_180 到达工作站 at 989.00.

Client_180 接受服务 at 989.00.

Client_179's 任务完成度:89%.

工作站服务客户数:180,工作站服务达标率:0.36。

Client_179 离开服务站 at 993.00.

Client_181 到达工作站 at 995.00.

Client_181 接受服务 at 995.00.

Client_180's 任务完成度:96%.

工作站服务客户数:181,工作站服务达标率:0.36。

Client_180 离开服务站 at 997.00.

Process finished with exit code 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue变量传值_VUE 学习——父组件传值给子组件

在我们编写前端代码时,经常遇到的一种场景,子组件需要使用父组件的值,这种情况下,我们可以使用props帮助我们进行父子组件间的通信。这里我们先模拟一个场景,展示如何使用。场景:在父组件修改值&#xff0c…

matlab 最小二乘法拟合_Scripy实现最小二乘法与股票K线回归

python的Scripy提供了丰富的数学工具,python的科学计算包scipy的里面提供了一个函数,可以求出任意的想要拟合的函数的参数。那就是scipy.optimize包里面的leastsq函数。函数原型是:leastsq(func, x0, args(), DfunNone, full_output0, col_de…

html 调高德地图 导航,在H5页面内通过地址调起高德地图实现导航

项目中用到的一个功能是要通过点击地址来实现打开地图app实现地址导航。如下图:实现思路就是在H5页面内通过点击marker图标然后进行当前位置与页面上地址的路程规划与导航。由于项目中用到的是高德地图,所以这里用到的是调起高德地图APP来实现该功能。首…

.jar文件如何打开_ofd发票文件如何打开

有时候大家查找文件的时候会不会觉得很心烦,因为经常能碰到OFD格式的文件,但是我们却不知道怎么打开,造成了很多困扰。我以前也常常遇到这样的情况,但是最近我发现了一个好办法,迫不及待地想分享给大家了,可…

印刷体是什么意思_家长晒出4年级小学霸课前笔记,字迹堪比“印刷体”,老师都羡慕...

目前,很多小学生都在家里上网课,为了达到最佳学习效果,要提前做好预习工作,尤其是语文这一学科,更需要预习。这不就有一位4年级学霸的家长晒出了孩子日常课前预习笔记。他不仅对文章进行了合理的布置和预习&#xff0c…

不使用自带函数求区域的周长_Excel表格中最强大求和函数______DSUM函数

在Excel表格中说起求和函数,朋友们首先会想到的是sum、sumif、和sumifs函数。这篇文章为朋友们分享最强大求和函数,数据库函数之DSUM函数。这个函数不仅能完成各种要求的求和,还可以用于查找。一.DSUM函数说明:1.语法:…

python 用if判断一个数是不是整数_Python基础教程07-函数和模块的使用

在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解。x1x2x3x48事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。可以用Python的程序来计算出这个…

前端跨域请求get_(单点登录)跨域SSO看这篇文章就够了:前端篇

前言前俩篇文章,我们从概念,聊到了服务器中设计的内容。不知道大家是否觉得通俗易懂呢?接下来的内容则有些偏向前端部分。正文三、Cookie传递3.1、通过URL参数实现跨域信息传递我们要在A域实现写入token到B域,需要在A域设计一个se…

win10 如何锁定计算机,Win10 1909 专业版怎么锁定计算机屏幕

Win10 1909 专业版怎么锁定计算机屏幕?如果我们需要暂时离开计算机,但不想关机或者注销当前登录,那么为了防止未经授权的使用,我们可以将计算机锁定。在本文中,win10之家小编给大家分享如何自动锁定Windows 10计算机。Win10 1909…

qfile指定从多少行开始_大牛进化路上之Linux基础命令,看看你了解多少?

玩转Linux系统还是要从基础命令开始,基础命令是你大牛发展之路的第一步,扎实的基本命令操作功底才能在工作中游刃有余,下面我们就来看看吧。路径切换说明Linux中分绝对路径和相对路径,绝对路径一定是从/开始写的,还可能…

如何开机进入grub界面_如何进入http://192.168.1.1的设置界面 ?

登入192.168.1.1管理界面需要确保前期的硬件连接和已获知路由器的账号密码。接下来详细介绍:1、首先做好准备,检查一下是否已经连接好无线路由器和网线、调制解调器,要确保网络畅通、所有指示灯都正常亮着;2、然后打开手机设置&am…

手机html5雪花飘落,如何使用HTML5canvas实现雪花飘落

这篇文章主要为大家详细介绍了HTML5 canvas实现雪花飘落特效,效果实现引人入胜,很逼真的动画效果,感兴趣的小伙伴们可以参考一下看到网上很多展示html5雪花飞动的效果,确实非常引人入胜,我相信大家也跟我一样看着心动的…

灰度调节_网关实现灰度发布

一、背景互联网产品开发有个非常特别的地方,就是不停的升级,升级,再升级。采用敏捷开发的方式,基本上保持每周或者每两周一次的发布频率,系统升级总是伴随着各种风险,新旧版本兼容的风险,用户使…

string类的erase函数属于stl吗_探索STL容器:vector

用了这么久的 vector ,今天终于有时间来看下STL的实现源码了,开心?~最近几个月在刷 leetcode ,用的较多的数据结构就是STL里面的 vector 了,相比较于直接的 array 数组,它具备了灵活地根据需求去分配管理内存&#xf…

泰森怎么会输给道格拉斯_泰森24岁就被击败,如果能像他学习巅峰时期至少能延长三年...

一个职业拳击手的运动生涯长短,除了与自身的打法风格有关外,最重要的就是自律,有很多拳手自身天赋极高,但当他成名之后,随着金钱和荣誉的到来往往无法把持自己,最终走向衰退。我们都知道,拳王迈…

数字加密c语言程序_国外程序员整理的 C++ 资源大全

喜欢的话可以收藏转发加关注摘要:C是在C语言的基础上开发的一种集面向对象编程、泛型编程和过程化编程于一体的编程语言。应用较为广泛,是一种静态数据类型检查的,支持多重编程的通用程序设计语言。关于 C 框架、库和资源的一些汇总列表&…

linux操作命令 mongo_Linux安装mongodb总结(仅学习)

原链接:Linux安装mongodb总结 - Lovebugs.cn - 博客园由于自己的博客上线部署时需要用到mongodb来存储图片文件,所以先在本地电脑上安装了mongodb做测试,由于之前没接触过mongodb,所以安装过程中遇到了各种小问题,折腾…

计算机二级必备快捷键知识,计算机二级考试中的一些注意事项️

原标题:计算机二级考试中的一些注意事项️科教武汉 【计算机二级考试中的一些注意事项️】1、要合理安排做题时间可以先通过观察整个题目的题形,判断整个试卷的难点,通过观察题型然后确定自己的应对策。选择题建议用时15-20分钟为好。自己要有…

vba 自定义function返回值_用vba解决excel如何求前面连续为0的个数

领导布置了任务,要求每天统计当月的发展量,并且统计有多少业务员最多连续多少天发展为0的情况,统计的表格是这样的。用几行简单的VBA语言就能解决这个问题首先打开vba编辑窗口,点击开发工具——visual basic(如果没有这个菜单&…

禁用计算机组策略和管理,计算机正在使用时,禁用或关闭组策略刷新 | MOS86

点击此处修复Windows错误并提高系统性能Group Policy(Windows 2000中引入的管理工具)可以确定组织中的用户和计算机的程序,网络资源和操作系统的运行方式。组策略可帮助用户通过在Windows Windows注册表中进行修改来为活动对象添加策略。通常,默认情况下…