簡體   English   中英

快速生成隨機集,蒙特卡羅模擬

[英]Fast generation of random set, Monte Carlo Simulation

我有一組數字~100,我希望在這個集合上執行MC模擬,基本思路是我完全隨機化集合,對前20個值做一些比較/檢查,存儲結果並重復。

現在實際的比較/檢查算法非常快,它實際上在大約50個CPU周期內完成。 考慮到這一點,為了優化這些模擬,我需要盡可能快地生成隨機集。

目前我正在使用George Marsaglia的Multiply With Carry算法,該算法為我提供了17個CPU周期內的隨機整數,非常快。 但是,使用Fisher-Yates混洗算法,我必須生成100個隨機整數,~1700個CPU周期。 這遠遠超過了我的比較時間。

所以我的問題是有沒有其他眾所周知/強大的技術來進行這種類型的MC模擬,我可以避免長的隨機集生成時間?

我想只是從集合中隨機選擇20個值,但我必須進行碰撞檢查以確保選擇了20個唯一條目。

更新:

謝謝你的回復。 關於我在帖子之后提出的方法,我還有另外一個問題。 問題是,這是否會提供真實的(假設RNG是好的)隨機輸出。 基本上我的方法是設置一個與輸入數組長度相同的整數值數組,將每個值設置為零。 現在我開始從輸入集中隨機選擇20個值,如下所示:

int pcfast[100];
memset(pcfast,0,sizeof(int)*100);
int nchosen = 0;
while (nchosen<20)
{
    int k = rand(100); //[0,100]
    if ( pcfast[k] == 0 )
    {
        pcfast[k] = 1;
        r[nchosen++] = s[k]; // r is the length 20 output, s the input set.
    }
}

基本上我上面提到的,隨機選擇20個值,除了它似乎是一種確保沒有碰撞的優化方式。 這會提供良好的隨機輸出嗎? 它很快。

如果您只使用隨機數組中的前20個值,那么您只需要執行Fisher-Yates算法的20個步驟(Knuth的版本)。 然后,20個值被隨機化(實際上在數組的末尾而不是在通常的公式中的開頭),在這個意義上,算法的剩余80個步驟保證不移動它們。 其他80個職位沒有完全洗牌,但是誰在乎呢?

C ++代碼(迭代器應該是隨機訪問):

using std::swap;

template <typename Iterator, typename Rand> // you didn't specify the type
void partial_shuffle(Iterator first, Iterator middle, Iterator last, Rand rnd) {
    size_t n = last - first;
    while (first != middle) {
        size_t k = rnd(n);   // random integer from 0 to n-1
        swap(*(first+k),*first);
        --n;
        ++first;
    }
}

返回時,從firstfirst middle-1的值被洗牌。 像這樣使用它:

int arr[100];
for (int i = 0; i < 100; ++i) arr[i] = i;
while (need_more_samples()) {
    partial_shuffle(arr, arr+20, arr+100, my_prng);
    process_sample(arr, arr+20);
}

羅斯模擬書提出如下內容:


double return[10];
for(int i=0, n=100; i < 10; i++) {
  int x = rand(n);  //pseudocode - generate an integer on [0,n]
  return[i] = arr[x];
  arr[x] = arr[n];
  n--;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM