2010-03-10 205 views
3

我正在學習編程課程,我們正在使用C++。 我們有一個任務,在某些時候,我們需要編寫一個函數,以[上限,下限]間隔返回一個隨機數。我用下面的:隨機數生成問題

lower + (int) (upper * (rand()/(RAND_MAX + 1.0))); 

我沒有忘記用srand((unsigned int) time(0))改變srand

但是,我每次都得到相同的價值!我請求教授尋求幫助,經過一番調查,他發現rand()生成的第一個數字不是隨機的......高階位保持不變,並且由於此實現使用它們,所以最終結果不是完全是我所期望的。

是否有一個更優雅,但簡單的解決方案,而不是放棄第一個值或使用餘數來實現我想要的?

非常感謝您的關注!

〜Francisco

編輯:謝謝大家的意見。我不知道rand()是這樣一個很爛的RNG:P

+0

是不是'rand()'過時了?我認爲現在每個人都應該使用'random()'。 – 2010-03-10 19:39:20

+0

'lower + rand()%(upper - lower + 1)'有什麼問題?你爲什麼不想用餘數? – IVlad 2010-03-10 19:39:53

+2

只是在說我也注意到了這一點。如果你實際上每次發現它不完全相同時打印出第一個rand(),但這些數字都相當接近。例如,現在當我連續多次開始一個程序時,我都會將數字全部在23000範圍內,例如作爲第一個數字。之後,數字更隨機。我一直只是拋棄了像你提到的第一個rand()數字。 – 2010-03-10 19:42:29

回答

2

鑑於rand()不是一個非常強的隨機數生成器,標準方法添加的少量偏差可能不是問題:(更高 - 更低)當然需要小於MAX_RAND。

lower + rand() % (higher-lower+1); 

由一個錯誤的固定關斷。

+0

'lower + rand()%(higher-lower + 1);' – IVlad 2010-03-10 19:42:11

+0

這將是'lower + rand()%(higher-lower + 1);' 出於學術的好奇,我想得到一個這個問題的解決方案不同,但感謝您的意見。 :) – 2010-03-10 19:45:05

1

rand()不是一個好的隨機數發生器。除了你觀察到的問題之外,它的週期長度可能很短。

考慮使用gsl random number generators之一。

+0

感謝您的鏈接! – 2010-03-10 19:48:54

1

根據您正在使用的操作系統,除rand()之外,還可能有random()。這產生比rand()好得多的僞隨機數。請檢查<stdlib.h>和/或man 3 random

1

你的代碼是好的,但你應該取代

lower + (int) upper * (rand()/(RAND_MAX + 1.0)); 

lower + (int) (upper - lower + 1)*(rand()/(RAND_MAX + 1.0)); 

下面的代碼工作很好地在我的機器上:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

#define lower 10 
#define upper 20 

int main(void) 
{ 
    int i; 
    int number; 

    srand(time(0)); 
    for(i=0; i<10; i++) 
    { 
     number = lower + (int) (upper - lower + 1)*(rand()/(RAND_MAX + 1.0)); 
     printf ("%d\n", number); 
    } 

    return 0; 
}  

當然,因爲time(0)給目前時間在幾秒鐘內 ,同一秒內兩次執行的結果相同。

+2

「rand()以秒爲單位給出當前時間」 - 這是一個奇怪的實現。 :P – Bill 2010-03-10 20:53:21

+1

@ Bill:哦,呃,好吧......它仍然是一個無證的功能。絕密。不要告訴任何人 – 2010-03-10 21:13:19

1

C++ 0x隨機數字庫(也可在TR1和Boost中使用)最終解決了一些令人討厭的蘭特問題。它允許獲得真正的隨機性(random_device),你可以使用它來進行適當的播種,然後你可以使用一個快速且良好的僞隨機生成器(mt19937),並且你可以使用一個合適的分佈(例如uniform_int,每個值的概率)。

它也不像Rand()那樣使用全局隱藏狀態,所以在多線程程序中不會有任何問題。

由於所有的模塊化,使用起來比簡單地調用rand要困難一些,但是仍然有益處遠遠超過了陡峭的學習曲線。