使用终止条件和不同的迭代步骤在Haskell中进行最佳迭代

时间:2012-04-04 19:01:07

标签: haskell

我正在尝试在Haskell中编写一个简单的迭代算法,但我很难在优雅和速度方面找到最佳解决方案。

我有一个算法需要在多次迭代中对一个状态应用一个操作,直到达到一些停止条件,使用一些任意函数记录状态。我已经知道如何通过定义像iterateM这样的函数来实现这样的方案。

但是在这种情况下,为每个步骤执行的操作取决于状态,并归结为检查“步骤类型”条件以决定下一个迭代类型,然后执行后续10次迭代的操作A,或者在再次检查条件之前执行下一次迭代的操作B.

我可以用命令式的方式写出:

c=0
while True:
    if c>0:
        x=iterateByA(x)
        c=c-1
    else:
        if stepCondition(x)==0:
            x=iterateByA(x)
            c=9
        else:
           x=iterateByB(x)
    observeState(x)
    if stopCondition(x):
        break

当然这可以在Haskell中复制,但我宁愿做一些更优雅的事情。

我的想法是让迭代使用一个函数列表来弹出并应用于状态,并在它为空时用新的列表(基于“步骤类型”条件)更新该列表。我有点担心这会效率低下。会这样做并使用像

这样的东西
take 10 (repeat iterateByA)

将所有列表分配等编译成仅使用计数器的紧密循环,就像上面的命令一样?

还有另一种干净利落的方法吗?

如果这对于自适应随机模拟算法有帮助,则迭代步骤更新状态,步骤条件(决定最佳模拟方案)是当前状态的函数。实际上有3种不同的迭代方案,但我认为2的例子更容易解释。

(我不确定它是否重要,但我也应该指出,在haskell中,iterateByX函数是monadic,因为它们使用随机数。)

1 个答案:

答案 0 :(得分:1)

直接翻译看起来并不太糟糕。

loop c x
    | stopCondition x = observe x
    | c > 0           = observe x >> iterateByA x >>= loop (c-1)
    | stepCondition x = observe x >> iterateByA x >>= loop 9
    | otherwise       = observe x >> iterateByB x >>= loop c

observe的重复可以通过各种技巧删除,如果你不喜欢它。

但你可能应该重新思考一些事情。这是一种非常迫切的方法;可能会做得更好(但很难说你在这里给出的一些细节如何)。