模拟时间和Akka调度器

4
我正在使用Akka构建多智能体模拟,因此希望可以比实时更快地运行模拟。具体来说,我想配置Akka调度程序,使得调度程序从一个已安排的事件转到下一个(这显然可能涉及到非常不同的时间步长), 而不是按照某种固定的底层时间步进。
换句话说,我希望调度程序的行为就像是一种优先队列,其中优先级由事件的模拟时间戳给出。
这清楚吗?如果是,请问是否可以在Actor System的默认调度程序中实现我想做的事情?如果这不可能,那么我该如何使用现有的Akka组件编写自己的调度程序以完成此任务?

必须使用调度程序吗?为什么不只使用递归函数将消息分派给您的代理? - Ramón J Romero y Vigil
@RamonJ.RomeroyVigil 抱歉,我不太明白。您能提供更详细的描述吗? - davidrpugh
我会写一个带有示例的答案。如果不是你要找的,我可以随时删除... - Ramón J Romero y Vigil
1个回答

1
我不认为使用akka调度程序可以实现这个功能。从文档中可以看到(重点是我的):
有时需要在将来发生一些事情,那么你去哪里找呢?不要再看ActorSystem了!在那里,您会发现scheduler方法,该方法返回一个akka.actor.Scheduler实例,该实例对于每个ActorSystem都是唯一的,并且用于内部安排在特定时间点发生的事情。
但是,您始终可以通过递归函数完成相同的事情。假设您的“实时”功能类似于:
def periodicFunction() : Unit = ???  //whatever you're doing to Agents

//periodicFunction is called every 10 seconds
actorSystem.scheduler().schedule(0 seconds, 10 seconds)(periodicFunction())

您的模拟代码可能如下所示:

Your simulation code could simply be:

@scala.annotation.tailrec
def fasterThanRealTimeLoop(n : Int) = 
  if(n > 0) {
    periodicFunction()

    fasterThanRealTimeLoop(n-1)
  }

然后,您可以使用HTML保留20次模拟运行。
fasterThanRealTimeLoop(20)

这个功能可以进一步封装,以包含两种可能性:
val realtimeMode : Boolean = ??? //some configuration setting

val periodicArgs : Either[FiniteDuration, Int] = 
  if(realtimeMode) Left(10 Seconds) else Right(20)

periodicArgs.left.foreach { period => 
  actorSystem.scheduler().schedule(0 seconds, period)(periodicFunction())
}

periodicArgs.right.foreach { count => 
  fasterThanRealTimeLoop(count)
}

这段代码现在将根据配置设置调用正确类型的循环(定时或尽可能快)。

@RamonJ.RomeroyVigil 谢谢。我认为这个递归函数调用并不适合我想要做的事情。我想要的是让Akka调度器表现得像一个优先级队列,其中队列中的对象按照模拟时间排序。 - davidrpugh
@davidrpugh 不用谢。正如我在回答开头所说的,我认为调度程序并没有这个技巧。祝你编程愉快。 - Ramón J Romero y Vigil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接