2012-01-13 51 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