0

我正在尝试在 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 函数是一元的,因为它们使用随机数。)

4

1 回答 1

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如果您不喜欢,可以通过各种技巧来消除重复。

不过,您可能应该重新考虑一下。这是一个非常必要的方法;可能可以做一些更好的事情(但很难从你在这里给出的几个细节中说出来)。

于 2012-04-04T19:31:19.663 回答