2012-04-04 6 views
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) 

上記の必須のようなカウンタだけを使用するタイトなループにすべてのリスト割り当てなどをまとめてコンパイルしますか?

これを行うためのもう少しきちんとした効率的な方法がありますか?

これは適応的確率的シミュレーションアルゴリズムにとって役立つ場合、反復ステップは状態を更新し、(最適なシミュレーション方式を決定する)ステップ状態は現在の状態の関数です。 infactには3つの異なる反復スキームがありますが、私は2での例が説明しやすいと考えました。

(私はそれが重要なのかはわからないが、私はおそらく、彼らは乱数を使用するので、HaskellでiterateByX機能がモナドであることを指摘しなければならない。)

答えて

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の繰り返しは、様々なトリックを介して除去することができます。

あなたはおそらく事を考えなければなりません。これは非常に不可欠なアプローチです。たぶんもっと良いことができるでしょう(しかし、あなたがここで与えたいくつかの詳細からどのように言っているのかは分かりません)。

+0

これは同じですか? OPコードは突然変異したバージョンの 'x'に対して' observeState'を呼び出し、あなたのバージョンはあらかじめ突然変異したバージョンで 'observe'を呼び出します。また、 'stopCondition'の場合は、ループの最後でテストされ、開始ではテストされません。 – pat

+0

@pat私のコードにオフラインでエラーがあることを知っても驚くことはありません。私はそれがポイントだとはほとんど思っていません。 –

+0

これは実際にはあまりにも悪くはありませんが、あなたが言うように、それは非常に不可欠なアプローチです。理想的には、ストップコンディションと観測機能は完全に汎用的でなければならないので、あまり説明しませんが、とにかく最後に少し追加しました。 – Tom

関連する問題