我想在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功能是一元,因爲他們使用的隨機數。)
這是一樣的嗎? OP代碼在'x'的突變版本上調用'observeState',而您的版本在預先突變版本上調用'observe'。此外'stopCondition'的情況在循環結束時進行測試,而不是開始。 – pat 2012-04-04 20:14:09
@pat我不會驚訝地發現我的代碼中有一個錯誤的錯誤。不過,我幾乎認爲這不是問題所在。 – 2012-04-04 20:21:54
這實際上看起來不算太糟糕,但正如你所說,這是一個非常必要的方法。理想情況下,停止條件和觀察函數應該是完全通用的,所以我們不需要解釋多少,但是無論如何我都加了一點。 – Tom 2012-04-04 20:26:27