a better random generator
//
random.hpp
// Copyright (C) 2008 Chipset
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see < http://www.gnu.org/licenses/ >.
//
#ifndef RANDOM_HPP_
#define RANDOM_HPP_
#include < ctime >
class random
{
public :
explicit random(unsigned long s = 0 ) : seed(s)
{
if ( 0 == seed) seed = std::time( 0 );
randomize();
}
void reset(unsigned long s = 0 )
{
seed = s;
if ( 0 == seed) seed = std::time( 0 );
randomize();
}
unsigned long rand( )
{
// returns a random integer in the range [0, -1UL)
randomize();
return seed ;
}
double real()
{
// returns a random real number in the range [0.0, 1.0)
randomize();
return double (seed) / -1UL;
}
private :
unsigned long seed;
void randomize() { seed = 1103515245UL * seed + 12345UL ; }
};
class rand_help
{
static random r;
public :
rand_help() {}
void operator ()(unsigned long s) { r.reset(s); }
unsigned long operator ()() const { return r.rand() ; }
double operator ()( double ) { return r.real(); }
};
random rand_help:: r;
extern void srandom(unsigned long ns = 0 ) { rand_help()(ns); } // reset seed
extern unsigned long irand() { return rand_help()(); } // negative numbers disallowed
extern double drand() { return rand_help()( 1.0 ); } // for real numbers
#endif // RANDOM_HPP_
// 以上随机数产生器产生的随机数比rand()产生的随机数更加随机(可以用数学方法检验),
//范围更大(一目了然),速度更快(测试一下便知,稍加修改我还可以让它再快一些,如果有必要)。
// Copyright (C) 2008 Chipset
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see < http://www.gnu.org/licenses/ >.
//
#ifndef RANDOM_HPP_
#define RANDOM_HPP_
#include < ctime >
class random
{
public :
explicit random(unsigned long s = 0 ) : seed(s)
{
if ( 0 == seed) seed = std::time( 0 );
randomize();
}
void reset(unsigned long s = 0 )
{
seed = s;
if ( 0 == seed) seed = std::time( 0 );
randomize();
}
unsigned long rand( )
{
// returns a random integer in the range [0, -1UL)
randomize();
return seed ;
}
double real()
{
// returns a random real number in the range [0.0, 1.0)
randomize();
return double (seed) / -1UL;
}
private :
unsigned long seed;
void randomize() { seed = 1103515245UL * seed + 12345UL ; }
};
class rand_help
{
static random r;
public :
rand_help() {}
void operator ()(unsigned long s) { r.reset(s); }
unsigned long operator ()() const { return r.rand() ; }
double operator ()( double ) { return r.real(); }
};
random rand_help:: r;
extern void srandom(unsigned long ns = 0 ) { rand_help()(ns); } // reset seed
extern unsigned long irand() { return rand_help()(); } // negative numbers disallowed
extern double drand() { return rand_help()( 1.0 ); } // for real numbers
#endif // RANDOM_HPP_
// 以上随机数产生器产生的随机数比rand()产生的随机数更加随机(可以用数学方法检验),
//范围更大(一目了然),速度更快(测试一下便知,稍加修改我还可以让它再快一些,如果有必要)。
/*
假设随机数均匀分布为理想分布, 粗略估计随机性
*/
#include < iostream >
#include < vector >
#include < iomanip >
#include " random.hpp "
int main()
{
srand(time( 0 ));
// SZ分别取值2^3, 2^4, , 2^15进行测试
const size_t SZ = 1 << 15 ;
std::vector < unsigned > v1(SZ), v3(SZ);
std::vector < unsigned > v2(SZ), v4(SZ);
for (size_t i = 0 ; i < SZ; ++ i)
{
++ v1[rand() % SZ]; // 对应元素计数 ,理论上v1[0] ~ v1[SZ - 1]之间每个都应该是1
++ v2[irand() % SZ];
}
for (size_t i = 0 ; i < SZ; ++ i)
{
++ v3[v1[i]]; // 统计频度
++ v4[v2[i]];
}
// 假设[0, SSZ)之间不存在间断点, (即使有间断点也无所谓,我们只做粗略模糊统计,因为没有必要那么精确)
// 最理想的显示结果应该是0: 0, 1: SZ, 2: 0, 3: 0, 4: 0, other: 0
// 0:表示间断,1:表示均匀,2:, 3:, 4:, other: 都表示不同程度的重复
const size_t SSZ = 5 ;
std::cout.fill( ' ' );
for (size_t i = 0 ; i < SSZ; ++ i)
std::cout << i << " : " << std::setw(SSZ) << v3[i] << " , " ;
std::cout << " other: " << std::setw(SSZ)
<< v3.size() - v3[ 0 ] - v3[ 1 ] - v3[ 2 ] - v3[ 3 ] - v3[ 4 ] << ' \n ' ;
for (size_t i = 0 ; i < SSZ; ++ i)
std::cout << i << " : " << std::setw(SSZ) << v4[i] << " , " ;
std::cout << " other: " << std::setw(SSZ)
<< v4.size() - v4[ 0 ] - v4[ 1 ] - v4[ 2 ] - v4[ 3 ] - v4[ 4 ] << ' \n ' ;
system( " pause " );
}
#include < iostream >
#include < vector >
#include < iomanip >
#include " random.hpp "
int main()
{
srand(time( 0 ));
// SZ分别取值2^3, 2^4, , 2^15进行测试
const size_t SZ = 1 << 15 ;
std::vector < unsigned > v1(SZ), v3(SZ);
std::vector < unsigned > v2(SZ), v4(SZ);
for (size_t i = 0 ; i < SZ; ++ i)
{
++ v1[rand() % SZ]; // 对应元素计数 ,理论上v1[0] ~ v1[SZ - 1]之间每个都应该是1
++ v2[irand() % SZ];
}
for (size_t i = 0 ; i < SZ; ++ i)
{
++ v3[v1[i]]; // 统计频度
++ v4[v2[i]];
}
// 假设[0, SSZ)之间不存在间断点, (即使有间断点也无所谓,我们只做粗略模糊统计,因为没有必要那么精确)
// 最理想的显示结果应该是0: 0, 1: SZ, 2: 0, 3: 0, 4: 0, other: 0
// 0:表示间断,1:表示均匀,2:, 3:, 4:, other: 都表示不同程度的重复
const size_t SSZ = 5 ;
std::cout.fill( ' ' );
for (size_t i = 0 ; i < SSZ; ++ i)
std::cout << i << " : " << std::setw(SSZ) << v3[i] << " , " ;
std::cout << " other: " << std::setw(SSZ)
<< v3.size() - v3[ 0 ] - v3[ 1 ] - v3[ 2 ] - v3[ 3 ] - v3[ 4 ] << ' \n ' ;
for (size_t i = 0 ; i < SSZ; ++ i)
std::cout << i << " : " << std::setw(SSZ) << v4[i] << " , " ;
std::cout << " other: " << std::setw(SSZ)
<< v4.size() - v4[ 0 ] - v4[ 1 ] - v4[ 2 ] - v4[ 3 ] - v4[ 4 ] << ' \n ' ;
system( " pause " );
}
//
做速度测试
#include < iostream >
#include < ctime >
#include < cstdlib >
#include < windows.h >
#include " random.hpp "
int main()
{
const size_t SZ = 1 << 27 ;
std::cout << " generating random numbers in progress \n " ;
std::cout << SZ << " random numbers generated.\n " ;
std::cout << " random used: " ;
Sleep( 1000 );
std::clock_t time = clock();
for (size_t i = 0 ; i < SZ; ++ i)
irand();
std::cout << clock() - time << " ms, " ;
std::cout << " rand() used: " ;
Sleep( 1000 );
std::srand(std::time( 0 ));
std::clock_t t = clock();
for (size_t i = 0 ; i < SZ; ++ i)
std::rand();
std::cout << clock() - t << " ms\n " ;
std::system( " PAUSE " );
return 0 ;
}
#include < iostream >
#include < ctime >
#include < cstdlib >
#include < windows.h >
#include " random.hpp "
int main()
{
const size_t SZ = 1 << 27 ;
std::cout << " generating random numbers in progress \n " ;
std::cout << SZ << " random numbers generated.\n " ;
std::cout << " random used: " ;
Sleep( 1000 );
std::clock_t time = clock();
for (size_t i = 0 ; i < SZ; ++ i)
irand();
std::cout << clock() - time << " ms, " ;
std::cout << " rand() used: " ;
Sleep( 1000 );
std::srand(std::time( 0 ));
std::clock_t t = clock();
for (size_t i = 0 ; i < SZ; ++ i)
std::rand();
std::cout << clock() - t << " ms\n " ;
std::system( " PAUSE " );
return 0 ;
}