非“僞”隨機數的生成

非“僞”隨機數的生成

作者: Jerry Cat
時間: 2006/05/16
鏈接: 
http://www.cppblog.com/jerysun0818/archive/2006/05/16/7232.html

問題的來由 - "隨機取m個數(在1到n的範圍之內),(m <= n),要求m個數沒有重複。有沒有
什麼好的算法,時間複雜度和空間複雜度都很好"

----------------------------------------------------------------
方案一:
取隨機數可以用C++標準的rand,至於M個不重複,你可以用std::set來解決,把取道的隨機數
插入到set裏面,set的size() == m就可以了, 具體可以這樣:

#include <set>
#include <stdlib.h>

int main()
{
   std::set<int> s;
   while(1)
   {
      int r = rand() % n;
      s.insert(r);
      if(s.size() == m)
      {
         break;
      }
   }
}

 由於set底層實現是紅黑樹,插入複雜度是對數級的^_^

----------------------------------------------------------------
方案二:
#include <iostream>
#include <cstdlib>      //用於rand()和srand()函數
#include <ctime>        //設置不同的隨機數

using namespace std;

int main (){
    srand( time( 0 ) );    //調用不重複的隨機數函數
    unsigned i;
    for ( int n = 0; n++ < 10; )
    {
        i = rand() ;        //對i 賦系統的隨機數
        cout << " The NO." << n << "is : " << i << endl;
    }

    return 0;
}

1. C++標準函數庫提供一隨機數生成器rand,返回0-RAND_MAX之間均勻分佈的僞隨機整數。 RAND_MAX
   必須至少爲32767。rand()函數不接受參數,默認以1爲種子(即起始值)。

   隨機數生成器總是以相同的種子開始,所以形成的僞隨機數列也相同。失去了隨機意義。

2. C++中另一函數srand(),可以指定不同的數(無符號整數變元)爲種子。但是如果種子相同,僞
   隨機數列也相同。--一個辦法是讓用戶輸入種子,但是仍然不理想。

3. 比較理想的是用變化的數,比如時間來作爲隨機數生成器的種子。
   在 頭文件ctime中時間庫包含time函數,它可以返回一個表示時間、日期、月和年的數值使用如
   下調用可將該值設爲rand的種子
   srand(static_cast<unsigned>(time(static_cast<time_t*>(NULL))));

4. 但, srand()並不是說使隨機數都不一樣,它只是使取隨機數的種子隨着時間而改變:)
   So, 還是方案一好!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章