2011-02-06 14 views
4

私はすでにこのための解決法を書いていますが、「正しい」と感じていないので、他の人からの入力を希望します。ヒステリシス付きの単純加重ランダムウォーク

規則は次のとおり

  • 運動は、2Dグリッド(行き方任意に標識されたN、NE、E、SE、S、SW、W、NW)に所定の方向に移動
  • 確率であります進行方向に対するものである(すなわち、40%が先に示す)、および加重:

[14%] [40%] [14%]
[8%] [4%] [8%] [4%] [4%] [4%]

これは、圧倒的な確率で、現在の軌道に沿った移動が続くことを意味します。中央の値は停止を表します。最後の移動がNWた場合、一例として、絶対確率は次のようになります。

[40%] [14%] [8%]
[14%] [4%] [4%]
[8%] [4%] [4%]

  • 確率は近似である - 私が作っていたとおもちゃ一つは、任意の確率を変化させたであろう主計算の外部スタティック5%の確率で、停止他の操作はこれほどわずかです。

次のように私の現在のアルゴリズム(簡体擬似コードで)です:私は本当にこの方法を嫌う理由

int[] probabilities = [4,40,14,8,4,4,4,8,14] 

if move.previous == null: 
    move.previous = STOPPED 

if move.previous != STOPPED: 
    // Cycle probabilities[1:8] array until indexof(move.previous) = 40% 

r = Random % 99 

if r < probabilities.sum[0:0]: 
    move.current = STOPPED 
elif r < probabilities.sum[0:1]: 
    move.current = NW 
elif r < probabilities.sum[0:2]: 
    move.current = NW 
... 

理由:
*これは、配列のインデックスに特定の役割を割り当てるために私を強制的に:[0] =停止、[1] =北...
*サイクリング時にアレイのサブセットで動作するように強制されます(つまり、STOPPEDは常に正しい位置に残ります)
*非常に反復的です。それは右のものになるまで順番にすべての値をチェックしなければなりません。アレイをサイクリングするには、最大4回の操作が必要です。
* 9ブロックifブロック(ほとんどの言語ではダイナミックスイッチが許可されていません)。
*停止したものは、すべてに特殊なケースが必要です。私が検討している

もの:
*循環リンクリスト:サイクリングを簡素化(ピボット常に同じ北を作る)が、ポインタのセットを維持し、まだ具体的な指標にロールを割り当てる必要が必要です。
*ベクター:これを重み付けする方法については、実際にはわかりませんが、大きさについても心配する必要があります。
*行列:回転行列は次のようには機能しません。
*よく知られているランダムウォークアルゴリズムを使用します。推奨事項は考慮されますが。 *木:ちょうどこれを考えたので、実際の考えはそれに与えられていません...

だから。誰にも明るいアイデアはありますか?

+1

を選ぶあなたの目標は何ですか? –

+0

2次元グリッド上を無意識にさまよっているポイントを持っていることがあります。時には停止し、時折方向を変更しますが、通常は選択した方向に沿って進みます。 –

+0

[ランダムウォークのアルゴリズム](http://en.wikipedia.org/wiki/Markov_chain_Monte_Carlo#Random_walk_algorithms) – karlcow

答えて

2

8Youは8つの方向性を持っているとあなたには、いくつかの方向性を打ったとき、あなたが

「この行列を回転」する必要がある。しかし、これは単に有限体上を法で次の方向を取得します。

確率を拾うのに100の整数しかないので、リストのすべての整数と各整数点の値をあなたの方向のインデックスにパターすることができます。

この方向は、移動しなければならない方向に回転(モジュロ加算)されます。

あなたの移動に適用する必要のある違いがある配列が1つあります。

そのようなものです。

    40 numbers 14 numbers 8 numbers 
int[100] probab={0,0,0,0,0,0,....,1,1,1,.......,2,2,2,...}; 

、その後

    N  NE E  SE  STOP 
int[9] next_move={{0,1},{ 1,1},{1,1},{1,-1}...,{0,0}}; //in circle 

ですから、

move=probab[randint(100)] 

if(move != 8)//if 8 you got stop 
{ 
    move=(prevous_move+move)%8; 
} 

move_x=next_move[move][0]; 
move_y=next_move[move][1]; 
+0

これは素晴らしいスピードで動作しました。私の控えめなマシンは、毎秒100万ポイントをマップできましたシングルスレッド操作。 –

2

たとえば、(dx、dy)のペアのような、アルゴリズムの方向をより直接的に表現します。 これは、あなただけのあなたの次の問題は、「確率表」の優れた表現を見つけることですx += dx; y += dy; (ご希望の場合は、まだ「方向ENUM」+ルックアップテーブルを使用することができます...)

持つことで移動することができます。 rは1から99までの範囲しかないので、ダム配列をしてprob_table[r]を直接使用することは可能かもしれません。

次に、任意の方法でこれらの確率テーブルの3x3マトリックスを計算します。あなたは一度だけ行うので、それが遅いかどうかは関係ありません。

は単に

prob_table = dir_table[curr_dx][curr_dy]; 
(curr_dx, curr_dy) = get_next_dir(prob_table, random_number()); 
関連する問題