除了rand函数,还有没有别的办法可以获得随机数?

yuqangy 2010-11-23 11:16:43
如果产生的随机数的个数量比较大的话,比如40000个,数的范围大概在0-40,是否还考虑还用rand函数?或是有别的比较高效的办法产生随机数?

求思路。
...全文
626 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
srand也行,如果重复则比较去掉
yuqangy 2010-11-27
  • 打赏
  • 举报
回复
_ptiddata 又是啥玩意 ?

zhao4zhong1 能不能提供点文字说明

目前采用的是rand算法 计算2 - 3 万次的耗时大概在2至3秒 不过这可能跟硬件上有关系
yuqangy 2010-11-27
  • 打赏
  • 举报
回复
谢谢各位 终于明白我想要的了
xunxun 2010-11-26
  • 打赏
  • 举报
回复
内置函数是最通常意义的,随机数算法有rand0、rand1等,很多很多。
赵4老师 2010-11-26
  • 打赏
  • 举报
回复
c:\boost_1_38_0\boost\random\uniform_int.hpp
/* boost random/uniform_int.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: uniform_int.hpp 50601 2009-01-15 03:43:36Z marshall $
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/

#ifndef BOOST_RANDOM_UNIFORM_INT_HPP
#define BOOST_RANDOM_UNIFORM_INT_HPP

#include <cassert>
#include <iostream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
#include <boost/type_traits/is_float.hpp>
#endif

namespace boost {

// uniform integer distribution on [min, max]
template<class IntType = int>
class uniform_int
{
public:
typedef IntType input_type;
typedef IntType result_type;
typedef typename make_unsigned<result_type>::type range_type;

explicit uniform_int(IntType min_arg = 0, IntType max_arg = 9)
: _min(min_arg), _max(max_arg)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
#endif
assert(min_arg <= max_arg);
init();
}

result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
void reset() { }

// can't have member function templates out-of-line due to MSVC bugs
template<class Engine>
result_type operator()(Engine& eng)
{
return generate(eng, _min, _max, _range);
}

template<class Engine>
result_type operator()(Engine& eng, result_type n)
{
assert(n > 0);

if (n == 1)
{
return 0;
}

return generate(eng, 0, n - 1, n - 1);
}

#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_int& ud)
{
os << ud._min << " " << ud._max;
return os;
}

template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, uniform_int& ud)
{
# if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC == 1400
return detail::extract_uniform_int(is, ud, ud.impl);
# else
is >> std::ws >> ud._min >> std::ws >> ud._max;
ud.init();
return is;
# endif
}
#endif

private:
template<class Engine>
static result_type generate(Engine& eng, result_type min_value, result_type max_value, range_type range)
{
typedef typename Engine::result_type base_result;
// ranges are always unsigned
typedef typename make_unsigned<base_result>::type base_unsigned;
const base_result bmin = (eng.min)();
const base_unsigned brange =
random::detail::subtract<base_result>()((eng.max)(), (eng.min)());

if(range == 0) {
return min_value;
} else if(brange == range) {
// this will probably never happen in real life
// basically nothing to do; just take care we don't overflow / underflow
base_unsigned v = random::detail::subtract<base_result>()(eng(), bmin);
return random::detail::add<base_unsigned, result_type>()(v, min_value);
} else if(brange < range) {
// use rejection method to handle things like 0..3 --> 0..4
for(;;) {
// concatenate several invocations of the base RNG
// take extra care to avoid overflows
range_type limit;
if(range == (std::numeric_limits<range_type>::max)()) {
limit = range/(range_type(brange)+1);
if(range % range_type(brange)+1 == range_type(brange))
++limit;
} else {
limit = (range+1)/(range_type(brange)+1);
}
// We consider "result" as expressed to base (brange+1):
// For every power of (brange+1), we determine a random factor
range_type result = range_type(0);
range_type mult = range_type(1);
while(mult <= limit) {
result += random::detail::subtract<base_result>()(eng(), bmin) * mult;
mult *= range_type(brange)+range_type(1);
}
if(mult == limit)
// range+1 is an integer power of brange+1: no rejections required
return result;
// range/mult < brange+1 -> no endless loop
result += uniform_int<range_type>(0, range/mult)(eng) * mult;
if(result <= range)
return random::detail::add<range_type, result_type>()(result, min_value);
}
} else { // brange > range
if(brange / range > 4 /* quantization_cutoff */ ) {
// the new range is vastly smaller than the source range,
// so quantization effects are not relevant
return boost::uniform_smallint<result_type>(min_value, max_value)(eng);
} else {
// use rejection method to handle cases like 0..5 -> 0..4
for(;;) {
base_unsigned result =
random::detail::subtract<base_result>()(eng(), bmin);
// result and range are non-negative, and result is possibly larger
// than range, so the cast is safe
if(result <= static_cast<base_unsigned>(range))
return random::detail::add<base_unsigned, result_type>()(result, min_value);
}
}
}
}

void init()
{
_range = random::detail::subtract<result_type>()(_max, _min);
}

// The result_type may be signed or unsigned, but the _range is always
// unsigned.
result_type _min, _max;
range_type _range;
};

} // namespace boost

#endif // BOOST_RANDOM_UNIFORM_INT_HPP
matrixcl 2010-11-26
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 zzhhopeless 的回复:]
srand((unsigned int)time(NULL));

这个方法要经过一秒 种子才会变化 一秒之内的 产生的随机数是相同的~~

就算超过一秒这个随机数也是递增的...
[/Quote]

srand调一次就行了,不需要每次rand前都调
赵4老师 2010-11-26
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 yuqangy 的回复:]
有没有相关rand函数的实现文档 ?
提供下吧 。。
[/Quote]
c:\Microsoft SDK\src\crt\rand.c
/***
*rand.c - random number generator
*
* Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines rand(), srand() - random number generator
*
*******************************************************************************/

#include <cruntime.h>
#include <mtdll.h>
#include <stddef.h>
#include <stdlib.h>

#ifndef _MT
static long holdrand = 1L;
#endif /* _MT */

/***
*void srand(seed) - seed the random number generator
*
*Purpose:
* Seeds the random number generator with the int given. Adapted from the
* BASIC random number generator.
*
*Entry:
* unsigned seed - seed to seed rand # generator with
*
*Exit:
* None.
*
*Exceptions:
*
*******************************************************************************/

void __cdecl srand (
unsigned int seed
)
{
#ifdef _MT

_getptd()->_holdrand = (unsigned long)seed;

#else /* _MT */
holdrand = (long)seed;
#endif /* _MT */
}


/***
*int rand() - returns a random number
*
*Purpose:
* returns a pseudo-random number 0 through 32767.
*
*Entry:
* None.
*
*Exit:
* Returns a pseudo-random number 0 through 32767.
*
*Exceptions:
*
*******************************************************************************/

int __cdecl rand (
void
)
{
#ifdef _MT

_ptiddata ptd = _getptd();

return( ((ptd->_holdrand = ptd->_holdrand * 214013L
+ 2531011L) >> 16) & 0x7fff );

#else /* _MT */
return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
#endif /* _MT */
}
smad732 2010-11-26
  • 打赏
  • 举报
回复
STL有随机数产生的函数
zourong0412 2010-11-25
  • 打赏
  • 举报
回复
我每次都用的是rand()%i...或者是srand(i)time(NULL))...用的是ctime头文件...
今天上来开眼界了...原来随机数有真伪之分的啊?求讲解~~
ForestDB 2010-11-25
  • 打赏
  • 举报
回复
还是看看随机数理论方面的知识吧。
caoatcao 2010-11-25
  • 打赏
  • 举报
回复
看楼上的讨论这问题已经到了 人更聪明还是电脑更聪明,电脑到底能不能代替人脑...
yuqangy 2010-11-25
  • 打赏
  • 举报
回复
如果计算机出现真随机的话 ?
那计算机不就是无法呗人控制了 ?


现在这个技术好像有点离谱了吧
cphj 2010-11-25
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 zanglengyu 的回复:]
引用 20 楼 cphj 的回复:
告诉你吧,常规的方法没有比rand()好的,否则rand()早就使用那个更好的方法了

路边的李子不甜,这道理明白吧?

未必
[/Quote]

如果你是搞发明创造的话,那么的确可以“未必”。如果还是在学习阶段,那么就别“未必”了。
失落的凡凡 2010-11-24
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 zzhhopeless 的回复:]

srand((unsigned int)time(NULL));

这个方法要经过一秒 种子才会变化 一秒之内的 产生的随机数是相同的~~

就算超过一秒这个随机数也是递增的...
[/Quote]

不会就不要误导别人,真受不了
失落的凡凡 2010-11-24
  • 打赏
  • 举报
回复
不保证这样会比调5次rand()直接求余性能要高。
失落的凡凡 2010-11-24
  • 打赏
  • 举报
回复
可以考虑这样的做法。以你的例子,要求生成的数在0-40。假设rand返回的值是32位,可截成5个6位数(6位二进制可以表示0-63),然后这些数在要求范围内,则取用,不在范围内则抛弃(为了随机性)。
失落的凡凡 2010-11-24
  • 打赏
  • 举报
回复
4w个不算多,就用rand吧。rand应该很少会成为性能瓶颈。
yuqangy 2010-11-24
  • 打赏
  • 举报
回复
4万 不是4千
cranium 2010-11-24
  • 打赏
  • 举报
回复
tr1中有新的随机实现.

default_random_engine def_rand;

#include <random>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
//rand engine
default_random_engine def_rand;
//distribution
uniform_int_distribution<int> uni_dist(1,100);

//rand value
int iNum = 0;

//rand seed ( and itself is a rand engine)
random_device rnd_device;
def_rand.seed(rnd_device());

//output min and max value about two engine defined above
cout<<"default_random_engine\n";
cout<<"Min:"<<def_rand.min()<<'\n'<<"max:"<<def_rand.max()<<endl;
cout<<"uniform_int_dirstribution<int>(1,100)\n";
cout<<"Min:"<<uni_dist.min()<<'\n'<<"Max:"<<uni_dist.max()<<endl;

//generate random value
for (int i=0;i<20;i++)
{
iNum = uni_dist(def_rand);
cout<<iNum<<'\t';
}
return 0;
}
zanglengyu 2010-11-24
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;
int main()
{
double rnd(unsigned int x);
unsigned int i,s;
cout<<"输入随机种子(1-65535):";
cin>>s;
rnd(-s);
int count=0;
cout<<"输出4000个(0-40)的随机数:";
for(i=0;i!=4000;++i)
{
cout<<(int)(rnd(1)*40)<<" ";
++count;
if(count%20==0)
cout<<endl;
}
return 0;
}
/*
随即函数,其实是伪随机,不过这个循环周期很大,产生0-40的随机性很大了,
c=2的18次幂+3 是个素数,r=2的35次幂/2的39次幂,得出一个小数 再乘以c,得出一个大于0的小数,取其小数部分。
小数部分乘以40 得出结果
*/
double rnd(unsigned int x)
{
static double c=262147.0,t,i,r=34359738365.0/549755813888.0;
if(x==1)
{
r=r*c-(long)(r*c);
}
else
{
for(i=1;i<=-x;i++)
{
r=r*c-(long)(r*c);
}
}
return (r);
}
加载更多回复(14)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧