Haskell用于模拟多车道交通圈?

时间:2009-04-12 22:39:05

标签: concurrency haskell

我很难想出并发的真实例子:

  

想象一下上面的情况,在哪里   有很多车道,很多路口   和大量的汽车。除了,   有一个人为因素。

这个问题对交通工程师来说是一个艰难的研究领域。当我在一段时间前调查它时,我注意到许多模型都失败了。当人们谈论函数式编程时,我会想到上述问题。

  

你能在Haskell中模拟它吗? Haskell真的如此并发吗?在Haskell中并行化这些并发事件的限制是什么?

6 个答案:

答案 0 :(得分:6)

我不确定究竟是什么问题。 Haskell 98没有为并发指定任何内容。像GHC这样的特定实现提供了实现并行性和并发性的扩展。

要模拟流量,它将取决于模拟所需的内容,例如:如果您想跟踪单个车辆或以一般统计方式进行,无论您是想使用刻度线还是连续模型的时间等,从那里,您可以想出您的数据的表示,使其自身平行或并行评估。

GHC提供several方法,利用多个硬件执行单元,从传统的信号量和互斥量,到channels的轻量级线程(可用于实现像Erlang这样的actor model) ,software transactional memory,纯函数parallel expression evaluationstrategies和实验nested data parallelism

所以是的,Haskell有许多并行执行的方法,当然可以用于流量模拟,但是在为并发模拟选择最佳数字表示之前,你需要清楚地了解你要做的事情。 。每种方法都有自己的优点和局限,包括学习曲线。您甚至可能会发现并发性对于模拟的规模来说是过度的。

答案 1 :(得分:5)

听起来我正在尝试进行模拟,而不是现实世界的并发。通常使用discrete event simulation处理此类事情。几年前我在Haskell做了类似的事情,并基于continuation monad变换器推出了我自己的离散事件仿真库。我担心它由我的雇主拥有,所以我不能发布它,但它并不太难。延续实际上是一个挂起的线程,所以定义类似这样的东西(来自内存):

type Sim r a = ContT r (StateT ThreadQueue IO a)

newtype ThreadQueue = TQ [() -> Sim r ()]

状态内的ThreadQueue包含当前调度线程的队列。您还可以使用其他类型的线程队列来保存未调度的线程,例如在信号量中(基于“IORef(Int,ThreadQueue)”)。一旦你有了信号量,就可以构建相当于MVars和MQueues的东西。

安排线程使用“callCC”。 “callCC”的参数是一个函数“f1”,它本身将函数“c”作为参数。这个内部参数“c”是延续:调用它恢复线程。当你这样做时,从该线程的角度来看,“callCC”只是将你给出的值作为参数返回给“c”。实际上,您不需要将值传递回挂起的线程,因此参数类型为null。

所以你对“callCC”的参数是一个lambda函数,它接受“c”并将它放在适合你正在做的动作的任何队列的末尾。然后它从状态内部获取ThreadQueue的头部并调用它。你不必担心这个函数会返回:它永远不会。

答案 2 :(得分:4)

如果您需要具有功能性顺序子集的并发编程语言,请考虑使用Erlang。

More about Erlang

答案 3 :(得分:2)

我想你在问你是否可以为系统中的每个对象都有一个线程?

GHC运行时scales nicely to millions of threads,并通过Chris Smith提到的抽象将这些线程多路复用到可用的硬件上。因此,如果您正在使用Haskell / GHC,那么系统中肯定有数千个线程。

在性能方面,它往往是a good deal faster than Erlang,但不太重视跨多个节点的进程分发。特别是GHC,更倾向于在共享内存多核系统上实现快速并发。

答案 4 :(得分:0)

Erlang,Scala,Clojure是适合您的语言。

但我认为您需要更多的是找到合适的Multi-Agents仿真库或工具包,并绑定您喜欢的语言。

我可以告诉你有关MASON,Swarm和Repast的信息。但这些是Java和C库......

答案 5 :(得分:0)

我已经就此做了一个答案,但现在我想从更广阔的视角再添一个。

这听起来像是一个难以解决的问题是,每个驾驶员都将其行动建立在对其他驾驶员将要做的事情的心理预测上。例如,当我开车时,我可以判断一辆车是否有可能在我面前拉,甚至在他指示之前,基于他将我和前面的车之间的间隙排成一线的方式。他反过来可以告诉我,我已经看到了他,因为我正在退出为他腾出空间,所以可以接受。一个好的司机捡起了很多这些微妙的线索,而且很难建模。

因此,第一步是找出真实驾驶的哪些方面未包含在失败的模型中,并弄清楚如何将它们放入。

(线索:所有模型都错了,但有些模型很有用)。

我怀疑答案将涉及为每个模拟驾驶员提供一个或多个心理模型,了解每个其他驾驶员将要做什么。这涉及使用驱动程序1可能对驱动程序2的意图做出的几个不同假设来运行驱动程序2的规划算法。同时驱动程序2对驱动程序1执行相同的操作。

这是一种很难添加到现有模拟器的东西,特别是如果它是用传统语言编写的,因为规划算法可能会产生副作用,即使它只是以它遍历的方式数据结构。但功能语言可能会做得更好。

此外,驱动程序之间的相互依赖可能意味着在那里的某个地方有一个固定点,懒惰的语言往往会做得更好。