2014-03-24 49 views

回答

1

如果你想/需要使用兩個單獨的列出了你的價值觀和概率,要做到這一點是擴展選擇一個索引,並使用此索引來訪問記者傳遞給rnd:weighted-one-of的概率,並且一旦選擇它,就可以訪問列表中的值。在下面的代碼中,這是example1

但是,如果您可以將您的值和概率都放在同一個列表中,則擴展更容易使用。這是通過構建「對」列表(即,在每個子列表中具有兩個項目的列表的列表)來完成的。如果有這種情況,可以使用報告中的一對(item 1)中的第二個項目,並使用該對中的第一個項目(item 0)設置您的狀態。 example2顯示如何做到這一點。

extensions [ rnd ] 

to example1 
    let values [1 2 3] 
    let probabilities [0.2 0.3 0.5] 
    let indices n-values length values [ ? ] 
    let index rnd:weighted-one-of indices [ item ? probabilities ] 
    let state item index values 
end 

to example2 
    let pairs [[1 0.2] [2 0.3] [3 0.5]] 
    let state item 0 rnd:weighted-one-of pairs [ item 1 ? ] 
end 

編輯:

正如在評論中提到由Seth,你可以用(map list values probabilities)從兩個單獨的列表構建你對列表。他還提到代碼可能「更清晰,firstlast而不是item 0item 1」。

example3集成了建議:

to example3 
    let values [1 2 3] 
    let probabilities [0.2 0.3 0.5] 
    let pairs (map list values probabilities) 
    let state first rnd:weighted-one-of pairs [ last ? ] 
end 
+0

如何使'對',給定'值'和'概率':'(地圖列表值概率)' –

+0

也許用'first'和'last'代替'item 0'和'item 1' '? –

+0

好點。我編輯了我的答案。 –

0

如果你想使用任何概率,而不僅僅是那些加起來一個,你可以這樣做沒有RND擴展。例如,如果你想根據投票數量挑候選人1,2,或3:

to-report weighted-rand 
    let values [1 2 3] 
    ;let probabilities [0.2 0.3 0.5] 
    let votes [5 7 9] 

    ; calculate the cumulative probability list 
    let cum reduce [ 
    lput (?2 + (ifelse-value (empty? ?1) [0] [last ?1])) ?1 
    ] (fput [] votes) 

    ; Roll a uniform random number weighted by the cumulative probability vector 
    let x random-float sum votes 
    let j -1 
    let found false 
    while [(not found) and (j < (length cum))] 
    [ 
    set j (j + 1) 
    if (x <= item j cum) [set found true] 
    ] 

    report item j values 
end 

這是一個有點複雜(尤其是棘手的使用減少了),但它通常做的是創造一個累積總和(概率)(票數),然後找到統一隨機值下降的列表中的位置。然後它返回與找到的地方對應的值列表中的項目。

相關問題