// 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[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; }
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
常用链接
留言簿(2)
随笔分类(99)
收藏夹(2)
主页
最新评论
|
|