【问题标题】:Bound the runtime of a computation in haskell在haskell中绑定计算的运行时间
【发布时间】:2012-11-19 17:43:59
【问题描述】:

我正在用 Haskell 编写游戏 AI,我想在指定的时间内搜索游戏状态树(即我总是希望 AI 花费 3 秒来决定要采取的行动)

我怎样才能用像 Haskell 这样的纯语言做到这一点?我希望我需要深入研究线程等,但我希望尽可能地减少它。

【问题讨论】:

标签: haskell artificial-intelligence sleep thread-sleep


【解决方案1】:

一个想法:将timeout(@MathematicalOrchid 建议)与来自SafeSemaphore 的可变变量结合起来,以便在您的进程每次计算部分结果时存储中间值:

import Control.Monad
import Control.Concurrent.MSampleVar
import System.Timeout

fac :: Integer -> Integer
fac 0 = 1
fac n = n * fac (n - 1)

tmo :: Int -> ((a -> IO ()) -> IO ()) -> IO (Maybe a)
tmo ms f = do
    mvar <- newSV Nothing
    timeout ms (f (writeSV mvar . (Just $!)))
    readSV mvar

longComp :: (Integer -> IO ()) -> IO ()
longComp save = let loop n = save (fac n) >> loop (n + 1)
                in loop 0

main :: IO ()
main = tmo 10000 longComp >>= print

传递给tmo 的函数的第一个参数是IO 操作,它可以用来保存中间结果。如果超时,则返回最后保存的结果。结果被转换为 WHNF,以便真正的计算发生在保存结果的线程中,而不是在从tmo 返回时处理它的线程中。

在这个变体中,传递给tmo 的函数必须保存它的输出,它不能返回它。但是很容易修改它,使其签名为(a -&gt; IO ()) -&gt; IO a

如果你想让事情变得更纯粹,我建议创建你自己的 monad 来封装这个想法,而不会让 IO 出来。


更新:请注意:

虽然无法保证异常会及时交付,但 运行时将努力确保不会发生任意延迟。在 GHC,只有在线程到达安全点时才能引发异常, 安全点是发生内存分配的地方。有些循环不 在循环内执行任何内存分配,因此不能 被 throwTo 打断。

(来自throwTo 的文档)。在上面的示例中,fac 不分配任何内存,因此对于大量内存不会立即中断。

更新:我基于这些想法创建了一个小型库,该库定义了一个用于计算的单子,该单子可以在返回最终结果或因超时而死之前返回部分结果。见https://github.com/ppetr/timeout-with-results

【讨论】:

    【解决方案2】:

    由于您要寻找的结果取决于时间,这不可避免地会涉及不纯的代码。

    看起来 base 包中的 System.Timeout 提供了运行 I/O 计算直到超时(根据 leftaroundabout 的评论)的能力。所以你需要做的就是编写一个 IO 计算返回您感兴趣的结果。但是......棘手的部分是使 IO 操作实际上 compute 结果,而不仅仅是返回未评估的结果。为此,我认为您需要来自Control.Exceptionevaluate

    【讨论】:

    • +1 表示依赖于时间的函数必然是不纯的。
    【解决方案3】:

    System.Timeout 是要走的路。它有一个非常干净的界面,一点也不觉得你在搞乱线程。

    搜索游戏空间听起来像是纯粹的计算,System.Timeout 运行 IO 动作,因此您需要将值包装在 return 中,并严格评估代码以使 timeout 不会立即相信答案一经评估就已返回给 WHNF。

    有一个示例 here 来自我遇到的类似问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 2012-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多