2012-01-13 54 views
1

我目前正致力於實現一個簡單的圖類,並且我想要的方法之一就是讓它返回一個隨機鄰居,如下所示的算法。但是,我發現每次運行程序時,返回nborList[r]總是返回nborList中的相同元素。僞隨機數發生器在同一個調用之間的不同行爲

IDType Graph::random_neighbor(const IDType source) const 
{ 
    IDVector nborList = neighbors(source); 
    IDType r = nrand(nborList.size()); 

    cout << "TEST Neighbors: "; 
    for (IDVector::const_iterator iter = nborList.begin(); 
     iter != nborList.end(); ++iter) 
     cout << *iter << " "; 
    cout << endl; 
    cout << "TEST Rand: " << r << endl; 

    return nborList[r]; 
} 

int nrand(int n) // Returns number [0, n), taken from Accelerated C++ 
{ 
    if (n <= 0 || n > RAND_MAX) 
     throw domain_error("Argument to nrand is out of range"); 

    const int bucket_size = RAND_MAX/n; 
    int r; 

    do r = rand()/bucket_size; 
    while (r >= n); 

    return r; 
} 

test.cpp文件,我使用這個圖形類有這樣的代碼:

#include <ctime> 
#include <iostream> 
#include "Graph.h" 

using std::cout; 
using std::endl; 

int main() 
{ 
    srand(time(NULL)); 

    Graph G(50); 
    for (int i = 1; i < 25; ++i) 
     if (i % 2 == 0) 
      G.add_edge(0, i); 
    G.add_edge(2, 49); 

    cout << "Number of nodes: " << G.size() << endl; 
    cout << "Number of edges: " << G.number_of_edges() << endl; 
    cout << "Neighbors of node 0: "; 
    IDVector nborList = G.neighbors(0); 
    for (IDVector::const_iterator iter = nborList.begin(); 
     iter != nborList.end(); ++iter) 
     cout << *iter << " "; 

    cout << endl << endl; 
    cout << "Random neighbor: " << G.random_neighbor(0) << endl; 
    cout << "Random number: " << nrand(nborList.size()) << endl; 
    return 0; 
} 

輸出:

Number of nodes: 50 
Number of edges: 13 
Neighbors of node 0: 2 4 6 8 10 12 14 16 18 20 22 24 

TEST Neighbors: 2 4 6 8 10 12 14 16 18 20 22 24 
TEST Rand: 1 
Random neighbor: 4 
Random number: 9 

我得到的輸出是這樣的,每一次,除了最後一行說Random number: 9應該改變。然而,TEST Rand: 1始終爲1,有時當我重新編譯時它會更改爲不同的數字,但在多次運行時它保持相同的數字。在這兩個地方的電話似乎是相同的,使用nrand(nborList.size())其中nborList = neighbors(source) ..幫助?

謝謝!

+0

一些C++ 11魔法固定它,使用STD在中使用:: random_shuffle()來洗牌矢量,並返回第0個值。 – adelbertc 2012-01-13 18:15:21

回答

1

rand()是衆所周知的shonky。如果您進行一些測試並使用時間接近的種子,則其產生的第一個數字將始終接近數值。如果可以的話,我建議使用類似boost::random的東西。

0

代替nrand功能,你爲什麼不只是寫

IDType r = rand() % nborList.size(); 

這會給你一些[0, n],其中n爲nborList.size() - 1

+0

(引用加速C++的第135頁)rand()當n很高時,%n沒有(隨機傳遞的)隨機數的均勻分佈。對於我的目的(大圖),n可以在幾十數千甚至更高。例如,本書說(對於32767的RAND_MAX實現),如果n = 20000,將有2個值獲得10000(rand()%10000和rand()%30000),但只有一個值可獲得15000(rand()% 150000)。我想盡可能保持一致隨機而不過度複雜,因此我從書中獲得了nrand()函數。 – adelbertc 2012-01-13 06:00:18