2012-06-21 100 views
2

我寫了這個代碼工作正常,但每次輸出是相同的。所以沒有任何隨機的。好奇知道爲什麼! 假設:33名學生 第一行:7名學生 第二行:9名學生 第三行:9名學生 第4行:8名學生隨機返回相同的輸出每次

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <ctime> 
using namespace std; 

int main() { 
    vector<int> random; 

    for (int i = 1; i < 34; i++) 
     random.push_back(i); 

    random_shuffle(random.begin(), random.end()); 

    for (int i = 1; i < 8; i++) 
     cout << random[i] << " " ; 
    cout << endl; 

    int i = 7; 
    int num_seats = 1; 

    for (int j = 1; j <=3; j++) { 
     while (num_seats < 10 && i < 33) { 
     cout << random[i++] << " " ; 
     num_seats++; 
     } 
     cout << endl; 
     num_seats = 1; 
    } 
} 
+0

大家知道,C++ 11有一個['iota'](http://en.cppreference.com/w/cpp/algorithm/iota )功能,可以幫助您避免使用連續數字填充矢量。 – chris

+2

您是否向隨機數生成器提供了[隨機種子](http://en.wikipedia.org/wiki/Random_seed)? – Veger

回答

7

您需要首先初始化隨機數發生器。隨機數生成取決於「種子值」。要在每次執行程序時擁有唯一的種子值,您可以依賴當前時間。 time(NULL)返回表示當前時間的秒數 - 可以是唯一的種子。

嘗試內部main()

srand(unsigned(time(NULL))); 
+0

是正確的,但是爲什麼他的「問題」首先存在的一點解釋可能會有幫助 – ltjax

+0

@Itjax:在聽起來像一個透視的風險,我敢打賭,這是課程的這個特定部分的重點是,教PRNG如何工作)。 –

+1

實際上並沒有指定'random_shuffle'使用'rand()'作爲隨機的來源,所以這不一定是可移植的。 – bames53

2

在第一行中添加此使用的過載random_shuffle()訪問隨機性的未指定的源。它幾乎肯定使用rand(),這意味着你需要使用srand()來播種它以獲得不同的隨機洗牌。

然而更便攜的解決方案將是指定一個隨機來源,因此您不必假設使用rand()。如果你的代碼是C++ 11的話,最好的選擇是使用shuffle()和發動機從<random>庫:

#include <random> 
#include <algorithm> 

#include <vector> 
#include <numeric> 
#include <iterator> 
#include <iostream> 

int main() { 
    std::vector<int> v(34); 
    iota(begin(v), end(v), 1); 

    std::random_device r; 
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; 
    std::mt19937_64 eng(seed); 

    shuffle(begin(v), end(v), eng); 

    copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " ")); 
    std::cout << '\n'; 
} 

缺席C++ 11可以使用random_shuffle()重載需要一個隨機數生成器,所以該程序可移植地指定了隨機性的來源:

#include <cstdlib> 
#include <ctime> 
#include <algorithm> 

#include <vector> 
#include <iterator> 
#include <iostream> 

struct RNG { 
    int operator() (int n) { 
     return static_cast<int>(std::rand()/(static_cast<double>(RAND_MAX)+1) * n); 
    } 
}; 

int main() { 
    std::vector<int> v(34); 
    for (int i=0; i < v.size(); ++i) 
     v[i] = i + 1; 

    std::srand(std::time(NULL)); 
    random_shuffle(v.begin(), v.end(), RNG()); 

    copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ")); 
    std::cout << '\n'; 
} 
+0

+1,但是如果你使用'C++ 11',爲什麼不使用'{}'來避免最煩人的解析而不是多餘的'()'。它也保持'random_device'構造和調用之間的區別更清晰。 – KillianDS

+0

@KillianDS我認爲,但是我決定讓我的示例支持一些流行的編譯器,它們還沒有實現通用初始化語法,但是它們具有必要的C++ 11庫組件。 – bames53

相關問題