- UID
- 18608
- 积分
- 2508
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-12-4
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
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()产生的随机数更加随机(可以用数学方法检验),
//范围更大(一目了然),速度更快(测试一下便知,稍加修改我还可以让它再快一些,如果有必要)。
/*假设随机数均匀分布为理想分布, 粗略估计随机性*/
#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]; //统计频度
++v4[v2];
}
//假设[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 << ", ";
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 << ", ";
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;
}
|
|