时间总和不等于模拟的持续时间

Posted

技术标签:

【中文标题】时间总和不等于模拟的持续时间【英文标题】:Sum of times doesn't add up to the duration of the simulation 【发布时间】:2021-08-20 14:36:54 【问题描述】:

我有 2 种代理类型、操作员和机器的工业模拟。每种代理类型都有状态图控制其逻辑的不同方面,如生产、空闲等。在进入退出时计算状态图的状态,time 以确定每个操作员或机器在每个状态中花费的时间。所以在模拟结束时,我会打印它们或使用直方图绘制它们以查看每个步骤/状态的百分比。

我遇到的问题是模拟的长度是 480 分钟28800 秒,但我计算的时间总和是 运行之间和代理之间不同(因为我有 9 台机器(来自代理类型的机器)和 6 个操作员(来自代理类型的操作员))。例如,操作员#1 有 28750 秒,操作员#2 有 29000 秒,依此类推。

我认为时间低于 28800 秒的原因是因为有时模拟在代理离开当前状态之前就结束了,所以函数不会更新,因为它没有启动存在动作。这对我来说很有意义。但是没有意义的是超过模拟长度(> 28800s)的代理,一些代理的时间总和超过了模拟的整个持续时间,我不明白为什么。

有什么方法可以知道问题是来自我在建模时犯的错误还是AnyLogic本身的问题?前段时间我在 AnyLogic 计算距离并与支持人员联系的方式上遇到了类似的问题,所以我猜这一次可能是 AnyLogic 处理时间的方式存在问题。


编辑,@Artem P. 的更多详细信息:

这是一个用于计算经过时间的代码示例,以及代码的总和,以及一个状态图示例:

例如,这是机器的状态图。

Statechart

在每个状态(最低级别的状态,而不是更高级别的状态)的进入动作和退出动作中,都有计算进入时间,然后存在时间和减法的代码,例如这些是进入和等待状态的退出操作:

Waiting state entry and exit actions

然后我将每个时间添加到它自己的 DataSet 中,以便我可以将它们绘制在直方图中并获得所有时间的百分比视图,因此 TnPAttente_DS.update();

如果您需要更多详细信息,我很乐意分享!

【问题讨论】:

几个额外的问题:1)你如何定义TnPAttnte_DSTnPAttnte_DS.update();? 2)你有任何静态变量吗? 3) 你是如何定义模型停止条件的? 1) TnPAttente_DS 只是我计算完所有time_exit - time_entry 后存储数据的数据集,我猜TnPAttente_DS.update() 是为了提高效率?因为我不让数据集自动更新,所以我只在它实际存储了一些东西后才更新它。 2)静态变量是什么意思?我猜我所有的变量都是动态的?因为它们都随着时间而变化,我不明白你的问题。 3)模型运行8小时或480分钟或28800秒即停止条件,一直运行到结束,我想模拟一个工作班次(8小时) 【参考方案1】:

时间操作通常非常依赖于模型的时间单位以及实际添加的方式。因此,例如,如果您的模型时间单位是 SECOND,并且您以 SECOND 计算总时间,即使用以下内容:

double startTime = time();
...
double elapsedTime += time() - startTime;

那么在 elapsedTime 变量中具有 29000 秒的值是不可能的,因为 time() 返回的值永远不会达到该值。

但是,如果您在几分钟内运行并且需要在几秒钟内获得您的价值,那么很可能会在某个地方出现一个舍入问题,该问题会随着模型运行时间的累积而累积。 因此,总的来说,建议是:确保以正确的单位进行计数并避免四舍五入。

当然,如果您通过屏幕截图分享代码和模型布局,可以提供更详细的建议。

【讨论】:

最好不要调用time(),而是给它单位作为参数,例如time(MINUTE)。这样,您就可以始终依赖这些单位。 是的,我的表现完全像@Benjamin 所说的那样。我正在使用time(SECOND)。但它仍然没有加起来模拟的 28800 秒,它要么少一点,要么多一点(通常在 10 到 100 秒或更多的范围内)【参考方案2】:

这不起作用可能有多种原因:

您确定要在每个简单状态中设置开始时间(进入操作)并增加经过时间(退出操作)吗?您的屏幕截图显示您正在使用复合状态:确保您没有通过复合状态简单状态重复计算时间。

您的开始和经过时间变量必须是 double 类型,每个代理每个状态都有每个实例,并且这些变量除了它们各自的状态开始/结束时不会在任何地方设置/更改。 (例如,您最好通过状态到经过时间的映射来构建它们;这也有助于避免诸如拼写错误之类的愚蠢错误,这意味着您正在将变量更新为另一种状态而不是正确的状态。但是您需要知道一点Java。)看起来您正在为每个代理使用一个启动时间变量,这应该没问题,因为退出操作总是在进入操作之前触发(因此您将在重置之前使用它的值)。

您是否允许在模拟结束时有“额外”时间(他们已经处于某种状态一段时间但没有离开它)?虽然这只会导致计算时间不足,而不是过度计算。

如果您没有获得模型时间单位中的时间值(这需要在封面下进行除法),则舍入问题(如 Artem 所述)。

【讨论】:

嗨!感谢您的回答,* 是的,我的 startTime 变量属于 double 类型!由于 AnyLogic 的工作方式,它们只是没有明确说明,但是当编译模拟时,它们确实是 double 类型! * 同样,这是 AnyLogic 内部的东西,我对它没有太多控制权,时间增量由 AnyLogic 处理,而不是由我处理。 * 我同意这一点,这是我在第 3 段的前半部分试图解释的内容,但这只会解释小于模拟长度的时间,而不会解释更高的时间。 * 舍入应该不是问题,因为所有时间都在SECONDS中处理 “未明确说明”是什么意思?在代理中定义变量时,您明确指定其类型。我知道您正在处理其他答案的 cmets,但我将其写为涵盖所有可能性的“完整”答案。 他们明确说明,我的错。使用的每个变量都是double 类型。我以为你不熟悉 AnyLogic。 Here you can see a variable used to calculate one portion of time,如您所见,它明确声明为 double 类型。我认为第三个答案是最接近实际情况的答案,但这只是答案的一半,因为我仍然不明白为什么总和超过了模拟的总长度。没有意义,就好像时间是从无到有,时间是从虚无中来的。 没看到你也在使用复合状态;更新了答案(因为那是您可能会重复计算时间并因此超过 sim 长度的区域)。

以上是关于时间总和不等于模拟的持续时间的主要内容,如果未能解决你的问题,请参考以下文章

numpy 1.9.0:ValueError:概率总和不等于 1

查找等于给定总和的数组元素[关闭]

如何计算密度直方图中的高度(它们的总和不等于 1)?

SQL(Presto):当 x 的总和等于某个阈值时返回日期

SQL 连接查询以获取借方余额不等于 0 的借方余额的项目名称、日期和总和?

jquery bootstrap Validation:多个输入值的总和,如果不等于其他输入字段,则禁用提交按钮