[英]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;
}
}
返回時,從first
到first
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.