2011-02-06 36 views
4

我已經爲此編寫了一個解決方案,但它不覺得「正確」,所以我想要其他人的一些輸入。帶有滯後的簡單加權隨機遊走

規則是:

  • 運動是在二維網格(路線任意標記的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個case if塊(大多數語言不允許動態切換)。
*停止必須特別容納在一切。

我考慮過的事情:
*循環鏈表:簡化循環(使樞軸總是等於北),但需要維護一組指針,並且仍然需要將角色分配給特定索引。
*矢量:真的不知道我怎麼去衡量這個,再加上我需要擔心幅度。
*矩陣:旋轉矩陣不能這樣工作:)
*使用一個衆所周知的隨機遊走算法:矯枉過正?雖然建議被考慮。 *樹木:剛想到這個,所以沒有真正想過給它...

所以。有沒有人有任何明智的想法?

+1

什麼是你的目標是什麼? – 2011-02-06 15:55:32

+0

在二維網格上漫無目的地漫遊,偶爾會停下來,偶爾會改變方向,但通常會沿着它所選擇的方向繼續。 – 2011-02-06 15:56:38

回答

2

8You有8個方向,當你打一些方向,你必須「旋轉這個矩陣」

但這只是模有限域。

由於您只有100個整數來挑選概率,因此您可以將所有整數都列入列表,並將每個整數的值從您的方向中索引。

這個方向你旋轉(模加法),它指向移動,你必須做的。

而且比你有一個陣列有區別,你必須適用於你的舉動。

這樣的事情。

    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]; 
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());