我正在考虑对 Material 流网络建模。有些进程以一定的速度运行,缓冲区可能会上溢或下溢以及它们之间的连接。

我没有发现使用全局事件队列以经典的离散事件模拟(DES)方式对此建模的任何问题。我尝试在没有队列的情况下对系统进行建模,但是在早期阶段失败了。仍然我不理解为什么需要队列的根本原因,至少对于在网络“内部”发生的事件至少不需要。

无队列DES的想法是将整个网络视为一个功能,该功能接收来自外部世界的事件流并返回状态变化流。网络中的每个节点应仅受与其直接连接的节点的影响。总的来说,我对Haskell的箭头和函数式 react 性编程(FRP)抱有一些希望,但我仍在学习。

对我来说,事件队列看起来太“全局”了。如果我的网络分成两个子网,并且它们之间没有连接,而我只问有关一个子网的状态变化的问题,那么另一个子网根本不做任何计算。在这种情况下,我可以使用两个事件队列。但是,一旦我连接了两个子网,就必须将所有事件放入一个队列中。我不喜欢这个想法,我需要了解网络的拓扑结构才能设置我的队列。

所以

  • 是否有人知道不需要全局队列的DES算法?
  • 有困难或什至不可能的原因吗?
  • 在DES上下文中FRP是否有用?
  • 最佳答案

    要回答第一点,不,我不知道任何不需要全局事件队列的离散事件模拟(DES)算法。可能具有事件队列的层次结构,其中每个事件队列在其父事件队列中表示为一个事件(对应于其下一个事件的时间)。如果将新事件添加到事件队列中,使其成为队列的下一个事件,则需要在其父级中重新安排事件队列,以保留事件执行的顺序。但是,您最终仍将归结为一个全局事件队列,该队列是层次结构中所有其他事件队列的父级,并调度每个事件。

    另外,您也可以省去DES,并执行类似于可编程逻辑 Controller (PLC)的操作,该可编程逻辑 Controller 每隔一小段时间就重新评估整个网络的状态。但是,通常情况下,它会慢很多(它可能甚至没有实时运行的快),因为在大多数情况下,它没有任何关系。如果选择的时间增量太大,则模拟可能会失去准确性。

    关于第二点的最简单答案是,据我所知,最终,没有全局事件队列是不可能的。每个模拟事件都需要在正确的时间执行,并且由于时间不能倒退,因此事件的分派(dispatch)顺序很重要。当前模拟时间由当前事件执行的时间定义。如果您有单独的事件队列,那么您也将有单独的时钟,至少可以这样使事情变得困惑。

    对于您的情况,如果您的子网完全独立,则可以分别模拟每个子网。但是,如果一个子网的状态影响整个网络的状态,并且整个网络的状态影响每个子网的状态,则-由于一个事件受其之前的事件影响,因此只能影响以下事件:跟随,但不能影响它之前的内容-您必须使用全局事件队列来模拟整个网络。

    如果得到安慰,真正的DES模拟不会在事件之间进行任何处理(除了确定下一个事件是什么),因此,如果所有 Action 都在另一个子网中进行,则不应在一个子网中浪费任何处理。

    最后,功能性响应式(Reactive)编程(FRP)在DES上下文中绝对有用。确实,我现在使用这种方法在Scala中编写了很多DES模拟。

    我希望这有帮助!

    UPDATE :自从编写以上内容以来,我已经使用了Sodium(一个出色的FRP库,在以下评论中由OP引用),并且可以添加一些进一步的解释:Sodium提供了一种订阅事件的方法,在这些事件发生时执行操作。但是,这里我使用一般意义上的事件一词,例如用户在GUI中单击按钮或到达网络程序包等。换句话说,事件不一定是模拟事件。

    在模拟过程中,您仍可以使用Sodium或任何其他FRP库作为模拟过程的一部分,以订阅模拟事件并在发生事件时执行操作。但是,这些工具通常不提供对模拟的内置支持,因此您必须将模拟引擎作为模拟事件的来源,就像将GUI作为用户交互事件的来源一样。全局事件队列必须驻留在此引擎内。

    顺便说一句,如果您尝试执行并行或分布式仿真模型执行,则事情会变得相当复杂。在这些情况下,您有多个事件队列,但是必须将它们同步(使单个队列出现)。两种基本方法是保守同步和乐观同步。

    关于functional-programming - 没有全局队列的离散事件模拟?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22284181/

    10-12 05:52