Press "Enter" to skip to content

模拟主题公园:使用R了解排队时间

用R模拟主题公园以理解排队时间并学习如何优化业务流程。

Thomas Kelley在Unsplash上的照片

长队总是让人望而却步,特别是当你等待飞越太空或航行于大堡礁时。随着暑假的继续,我相信几乎每个人都会排队等待某个东西,希望你足够幸运能直接去魔法王国。也许你在读这篇博客的时候就在其中一个队列中!

文章中包含了一些代码来支持示例,但完整的代码可以在我的GitHub上找到,链接在文章末尾。该项目使用R和simmer包进行离散事件模拟。请享受吧!

概念回顾——离散事件模拟

那么,在我的笔记本电脑上模拟一个主题公园需要什么?会不会像《无敌破坏王》中的游戏中央站一样?

很抱歉……用R编写的代码将使用离散事件模拟(DES),它实际上只是展示了一个过程随时间可能发生的情况。DES的主要用例是优化流程,这就是为什么它常用于运营研究的原因。模拟允许决策者在多次迭代后查看一个典型过程,并了解如何改进它。例如,增加工厂生产线上的额外机器是否会减少生产产品的瓶颈?

本文将把DES应用于一个假想的迪士尼乐园。这个版本的乐园会更简单一些,并且有一些额外的假设,以便简化建模。

由于这篇博客更注重应用,所以会有很多代码示例而不是理论,但这篇概念回顾涉及的组件应该有助于我们尽快上手。

组件

离散事件模拟需要一些基本组件。在编码开始之前,让我们在这里对它们进行回顾:

  • 轨迹:轨迹是一个客人在模拟中所经历的路径。例如,当客人到达时,他们可能会排队等待乘坐游乐设施,然后离开。这将是他们的轨迹。
  • 资源:资源是在轨迹过程中使用的物品。在上面的例子中,游乐设施就是一个资源。
  • 生成器:生成器用于生成客人,而生成器通常在模拟过程中会生成多个客人。生成器还需要一个轨迹,以指示生成的客人应该去哪里。
  • 环境:环境是整个模拟运行的地方,对于我们来说,就是主题公园本身。它封装了我们所有的资源、生成器和轨迹。有了simmer,环境还会跟踪和报告我们的资源使用情况,这使得分析模拟变得更简单。

完成这个回顾后,让我们开始动手吧!下面的模拟将逐步建立并变得越来越复杂。为了说明目的,代码在最后一个模拟之前没有进行重构,而最后一个模拟利用了一些额外的R函数和特性来清理模拟。

模拟一:与莉洛和斯迪奇相遇

第一个模拟将作为介绍。在这个模拟中,客人到达并开始排队等待见莉洛和斯迪奇。在编写代码之前,有助于先回顾一下各个组件:

  • 轨迹:到达乐园,排队,使用角色资源(莉洛或斯迪奇),释放角色资源并离开乐园。
  • 资源:客人可以见到的角色。莉洛或斯迪奇,因此该资源的容量被设置为两个,意味着同时可以由两个客人占用。
  • 生成器:将定期生成到达乐园的客人。
  • 环境:乐园本身。

现在让我们思考每个元素的代码。R允许我们利用其他包,如dplyr,来组织我们编写的代码。这使得轨迹构建变得更简单:

首先,访客占用一个字符,使其无法被其他访客使用。然后他们在该资源上设置超时。超时意味着他们无法执行任何其他操作。在大多数模拟中,超时的持续时间将基于一个真实的过程。然而,在这个虚构的场景中,超时的长度是从正态分布中采样得到的。最后,访客释放资源,该资源可以再次被队列中的其他访客使用。

轨迹是最复杂的概念。环境、资源和生成器都在一段代码中一起定义:

这组组件再次非常基本。重要的是,资源的容量是两个,符合规范要求。访客按指数函数到达,并给出上面定义的轨迹。访客的到达通常也会根据真实事件建模,但为了示例的目的,指数函数就足够了!

最后一步是运行模拟并进行一些分析。运行模拟就像输入“run”并提供运行的时间步数一样简单。在这种情况下,公园将开放15小时。对于分析,我们将使用simmer.plot,这是simmer库的一个扩展,可以为我们提供一些简单的可视化效果:

下面的第一个图显示了资源利用率。对于这个模拟,我们的利用率只有20%。这个百分比表示资源被使用的模拟时间比例。

作者提供的图片

20%的利用率值相当低,理想情况下,我们希望有更高的利用率,因为这意味着更多的满意客人!下一个可视化表示等待时间,没有客人等待超过5个时间步。这是有道理的,因为我们的资源超时是基于从均值为5步的正态分布中采样得到的。然而,平均等待时间要低得多,由蓝色线表示。

作者提供的图片

第二次模拟:与快速通行证遇见Lilo和Stitch

现在让我们慢慢增加一些复杂性。模拟将与上述相同。然而,我们将添加优先级客户。这些客户将模拟迪士尼乐园的“快速通行证”系统。实际上,我们所做的就是生成一个具有优先级的新客户:

请注意,这个客户的优先级为1,而默认客户的优先级为0。较高的优先级值意味着该客户将在所有优先级较低的客户之前跳过队列并乘坐。

模拟主题公园:使用R了解排队时间 四海 第4张

作者提供的图片

请注意,资源利用率大幅增加!这是因为现在有一个保证到达的客户,该客户将在固定间隔内优先于所有其他客户。相反,等待时间增加了,这也是符合逻辑的,因为不仅有更多的客人,还有更多的快速通行证客人,这增加了原始群体的等待时间。

第三次模拟:与Lilo和Stitch会面并放弃等待

在队列中等待可能令人沮丧,人们往往会放弃。这可以通过放弃等待的概率来进行数学计算。如果一个客户在队列中等待的时间很长,我们可以模拟他们放弃的机会。这是通过添加到轨迹中来完成的:

客户放弃等待的时间再次从一个围绕值为2的正态分布中采样得到,这通常会被估计得更高,但为了帮助理解放弃等待,对于这个例子,我们假设客户非常不耐烦。重要的是,一旦客户获取到资源,我们必须中止放弃等待。客人们不会在达到等待期末时就离开!

模拟主题公园:使用R了解排队时间 四海 第6张

作者照片

这种反悔最终导致资源的利用率降低,因为越来越多的客人离开了,因此没有使用资源。然而,它也减少了等待时间,因为许多客人只是放弃了,所以他们的等待时间不包括在内。客人离开的另一个效果是其他客人经历了更短的队列,这也减少了等待时间。在其余的模拟中,我们将增加客人反悔所需的时间。

第四个模拟:使用分批处理一辆车乘坐太空山

现在让我们来享受一下乐趣:游乐设施。主题公园的游乐设施将利用 simmer 中的分批处理功能。分批处理允许我们将客人分组到一辆太空山车中,例如:

参数 n 表示可以将多少位客人分批处理到该组中,所以在这种情况下,每辆车可以容纳 6 位客人。timeout 参数表示在批次填满之前等待的时间。因此,在该批次占用一辆车资源之前,该批次可以达到其容量 6 或经过 10 个时间步骤。

模拟主题公园:使用R了解排队时间 四海 第8张

作者照片

由于这个例子的复杂性增加以及需要将客人分批处理,或者至少在没有完整的批次时等待适当的时间后离开,利用率下降了。这些条件也对等待时间造成了问题,与角色等待时间相比,等待时间大大变化。一个客人可能会立即到达并离开,或者需要等待整整 10 个时间步骤才能出发新的批次。为了解决这个问题,实际上会增加车辆的大小或数量。

第五个模拟:太空山或溅水山的分支

让我们使事情更加真实;一个主题公园如果只有一种游乐设施就不会有什么意思了。通过添加一个新的游乐设施,比如溅水山,我们可以模拟客人的偏好,并使用分支轨迹来确定他们将选择哪个游乐设施。这变得有点复杂,在完整的脚本中可以看到,轨迹的游乐设施元素已经添加到它们自己的函数中。为了简洁起见,这里只显示了一个更简洁的版本,以演示分支逻辑:

在上面的情况下,客人根据抛硬币来选择,所以客人选择太空山或溅水山的可能性是相等的。在更真实的应用中,这可以根据实际偏好进行建模。这里模拟的建设也有所不同:

在这个例子中,有两个不同的资源。这与上面的 Lilo 和 Stitch 的例子不同,因为 Lilo 和 Stitch 都被建模为一个“角色”资源,容量为两个。然而,在这里,溅水山与太空山相比是一个单独的资源。

模拟主题公园:使用R了解排队时间 四海 第10张

作者照片

这两个游乐设施的利用率非常不同,主要是由于两种轨迹之间的骑行时间差异导致的。乘坐太空山需要更长时间,而且客人更有可能反悔。增加的复杂性还导致了更加多样化的等待时间,然而从优化的角度来看,我们通过减少平均等待时间来成功改善了客人的体验。

模拟六:使用日程表和队列偏好开放公园

最后的模拟将我们所创建的一切汇集在一起,并为公园添加一个日程表。到目前为止,我们一直使用固定值来定义资源容量。还有一种选择:使用日程表。日程表允许我们根据时间间隔来控制资源的容量。

公园的日程表将由一个大门控制,该大门在模拟结束前的50个时间步之后打开,并在结束前的50个时间步之前关闭。下面的代码使用了许多重构的函数,这些函数再次在下面的GitHub存储库中链接。大门的日程表是此处需要审查的最重要的事情:

这次我们的轨迹结合了游乐设施和角色。已经添加了一些其他的代码,使得客人可以按照轮询策略选择他们要参观的角色。现在产生了更多的客人,因为有更多的活动可供选择。

模拟主题公园:使用R了解排队时间 四海 第12张

作者的图片

这个模拟展示了资源的更真实的利用分布。现在客户有更多的事情可以做,因此每个资源的使用时间更短。还增加了一个限制条件,即客户必须等待进入公园。请注意,大门导致了利用率的大幅减少,但实际上它本身的利用率很低,因为客户立即占用并释放它。在这里,等待时间也达到了峰值,客人等待公园开放,然后等待游乐设施,但这是一个更加真实的模拟。当大门打开时,第一组客人将被释放到公园中,选择他们想要玩什么和见谁。

结论和最后的思考

离散事件模拟为分析师和决策者提供了探索业务流程的机会。在上述示例中,复杂性从客人到达、进行活动和离开的情况一直延伸到考虑偏好和人类行为(如放弃)的情况。

通过这个过程做出的一些决策,比如增加更多的游乐设施,展示了离散事件模拟如何用于优化流程。另一方面,添加更复杂的行为,比如放弃,展示了如果资源没有正确设置,则可能导致资源被低效利用。

希望您喜欢这篇文章!如果您喜欢,请考虑关注我的页面以获取更多数据科学内容。

资源

代码:

GitHub – josephlewisjgl/DESR: 存储从博客文章“模拟主题公园…”中的代码的仓库

存储从博客文章“模拟主题公园:用R了解排队时间”的代码的仓库 – GitHub …

github.com

Simmer文档:

6.1 甜甜圈店 | 模拟和建模以了解变化

这些是在人文学院中给出的模拟和建模以了解变化模块的讲座笔记

bookdown.org

Leave a Reply

Your email address will not be published. Required fields are marked *