📄 random
字号:
// random TR1 header
#pragma once
#ifndef _RANDOM_
#define _RANDOM_
#ifndef RC_INVOKED
#include <istream>
#include <limits>
#include <vector>
#include <xtr1common>
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
#pragma warning(disable: 4127 4244 4389 4521 4723)
#pragma warning(disable: 6294 6326)
#ifndef _BITS_BYTE
#define _BITS_BYTE 8
#endif /* _BITS_BYTE */
#if defined(_DEBUG) || defined(_RNG_CHECK)
#define _RNG_QUOTX(x) #x
#define _RNG_QUOT(x) _RNG_QUOTX(x)
#define _RNG_ASSERT(ex, msg) \
((ex) ? (void)0 : _Rng_abort(__FILE__ "(" _RNG_QUOT(__LINE__) "): " msg))
#else /* defined(_DEBUG) || defined(_RNG_CHECK) */
#define _RNG_ASSERT(ex, msg) ((void)0)
#endif /* defined(_DEBUG) || defined(_RNG_CHECK) */
_STD_BEGIN
namespace tr1 { // TR1 additions
// CONSTANTS
static const long double _Pi = 3.14159265358979323846264338327950288L;
static const long double _Exp1 = 2.71828182845904523536028747135266250L;
static const long double _Two32 = 4294967296.0L;
static const long double _Two31 = 2147483648.0L;
// HELPER FUNCTIONS
_CRTIMP2_PURE __declspec(noreturn) void __CLRCALL_PURE_OR_CDECL _Rng_abort(_In_z_ const char *_Msg);
_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _XLgamma(float);
_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _XLgamma(double);
_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _XLgamma(long double);
// TEMPLATE FUNCTION _Nrand
#define _NRAND(eng, resty) _Nrand(eng, (eng.min)(), (resty)1)
template<class _Engine,
class _Ety,
class _Rty>
_Rty _Nrand(_Engine& _Eng, _Ety _Emin, _Rty _Inc)
{ // scale random value to [0, 1), integer engine
return ((_Eng() - _Emin)
/ ((_Rty)(_Eng.max)() - (_Rty)_Emin + _Inc));
}
template<class _Engine,
class _Rty>
_Rty _Nrand(_Engine& _Eng, float _Emin, _Rty)
{ // scale random value to [0, 1), float engine
return ((_Eng() - _Emin) / ((_Eng.max)() - _Emin));
}
template<class _Engine,
class _Rty>
_Rty _Nrand(_Engine& _Eng, double _Emin, _Rty)
{ // scale random value to [0, 1), double engine
return ((_Eng() - _Emin) / ((_Eng.max)() - _Emin));
}
template<class _Engine,
class _Rty>
_Rty _Nrand(_Engine& _Eng, long double _Emin, _Rty)
{ // scale random value to [0, 1), long double engine
return ((_Eng() - _Emin) / ((_Eng.max)() - _Emin));
}
// I/O HELPERS FOR FLOATING-POINT VALUES
static const int _Nwords = 4;
template<class _Elem,
class _Traits>
_STD basic_ostream<_Elem, _Traits>& _Write(
_STD basic_ostream<_Elem, _Traits>& _Os, long double _Dx)
{ // write long double to stream
int _Ex;
long double _Frac = _CSTD frexpl(_Dx, &_Ex);
for (int _Nw = 0; _Nw < _Nwords; ++_Nw)
{ // break into 31-bit words
_Frac *= _Two31;
long _Digits = (long)_Frac;
_Frac -= _Digits;
_Os << ' ' << _Digits;
}
_Os << ' ' << _Ex;
return (_Os);
}
template<class _Elem,
class _Traits>
_STD basic_istream<_Elem, _Traits>&
_Read(_STD basic_istream<_Elem, _Traits>& _Is, long double& _Dx)
{ // read long double from stream
long double _Frac = 0.0;
long _Digits;
for (int _Nw = 0; _Nw < _Nwords; ++_Nw)
{ // accumulate 31-bit words
_Is >> _Digits;
long double _Temp = _Digits / _Two31;
for (int _Idx = 0; _Idx < _Nw; ++_Idx)
_Temp /= _Two31;
_Frac += _Temp;
}
_Is >> _Digits;
_Dx = _CSTD ldexpl(_Frac, _Digits);
return (_Is);
}
template<class _Elem,
class _Traits,
class _Ty>
_STD basic_istream<_Elem, _Traits>&
_In(_STD basic_istream<_Elem, _Traits>& _Is, _Ty& _Dx)
{ // read from stream
long double _Vx;
_Ty _Max = (_STD numeric_limits<_Ty>::max)();
_Read(_Is, _Vx);
if (_CSTD fabsl(_Vx) <= _Max)
_Dx = (_Ty)_Vx;
else if (_Vx < 0)
_Dx = -_Max;
else
_Dx = _Max;
return (_Is);
}
template<class _Elem,
class _Traits,
class _Ty>
_STD basic_ostream<_Elem, _Traits>&
_Out(_STD basic_ostream<_Elem, _Traits>& _Os, _Ty _Dx)
{ // write to stream
return (_Write(_Os, _Dx));
}
template<class _Elem,
class _Traits,
class _Ty>
class _Wrap_istream
{ // wrap input stream as function object
public:
_Wrap_istream(_STD basic_istream<_Elem, _Traits>& _Is)
: _Str(_Is)
{ // construct
}
_Ty operator()()
{ // read next value
_Ty _Data;
_Str >> _Data;
if (!_Str)
_STD _Xinvalid_argument("input stream corrupted");
return (_Data);
}
private:
_Wrap_istream& operator=(const _Wrap_istream&); // not defined
_STD basic_istream<_Elem, _Traits>& _Str;
};
#if _HAS_CPP0X
// CLASS seed_seq
class seed_seq
{ // standard sequence of seed values
public:
typedef unsigned int result_type;
seed_seq()
{ // default constructor
}
template<class _InIt>
seed_seq(_InIt _First, _InIt _Last)
{ // construct from [_First, _Last)
_Construct(_First, _Last, _Val_type(_First));
}
template<class _RanIt>
void generate(_RanIt _First, _RanIt _Last) const
{ // generate randomized interval from seeds
_Generate(_First, _Last, _Val_type(_First));
}
template<class _OutIt>
void param(_OutIt _Dest) const
{ // copy seeds
copy(_Myvec.begin(), _Myvec.end(), _Dest);
}
size_t size() const
{ // get size of seed
return (_Myvec.size());
}
private:
template<class _InIt,
class _Ty>
void _Construct(_InIt _First, _InIt _Last, _Ty *)
{ // construct from [_First, _Last)
for (; _First != _Last; ++_First)
_Myvec.push_back((unsigned int)*_First);
}
template<class _RanIt,
class _Ty>
void _Generate(_RanIt _First, _RanIt _Last, _Ty *) const
{ // generate randomized interval from seeds
const size_t _Nx = _Last - _First;
if (0 < _Nx)
{ // finite interval, fill it
const size_t _Sx = _Myvec.size();
const size_t _Tx = 623 <= _Nx ? 11 : 68 <= _Nx ? 7
: 39 <= _Nx ? 5 : 7 <= _Nx ? 3 : (_Nx - 1) / 2;
const size_t _Px = (_Nx - _Tx) / 2;
const size_t _Qx = _Px + _Tx;
const size_t _Mx = _Nx <= _Sx ? _Sx + 1 : _Nx;
size_t _Kx;
_Ty _Mask = _Ty(1) << 31;
_Mask <<= 1; // build 32-bit mask safely
_Mask -= 1;
for (_Kx = 0; _Kx < _Nx; ++_Kx)
_First[_Kx] = 0x8b8b8b8b;
for (_Kx = 0; _Kx < _Mx; ++_Kx)
{ // scramble and add any vector contributions
result_type _R1 = 1664525 * _Xor27(_First[_Kx % _Nx]
^ _First[(_Kx + _Px) % _Nx] ^ _First[(_Kx - 1) % _Nx]);
result_type _R2 = (result_type)((_R1 + (_Kx == 0 ? _Sx
: _Kx <= _Sx ? _Kx % _Nx + _Myvec[(_Kx - 1) % _Sx]
: _Kx % _Nx)) & _Mask);
_First[(_Kx + _Px) % _Nx] =
(_First[(_Kx + _Px) % _Nx] + _R1) & _Mask;
_First[(_Kx + _Qx) % _Nx] =
(_First[(_Kx + _Qx) % _Nx] + _R2) & _Mask;
_First[_Kx % _Nx] = _R2;
}
for (; _Kx < _Mx + _Nx; ++_Kx)
{ // rescramble
result_type _R3 = 1566083941 * _Xor27(_First[_Kx % _Nx]
+ _First[(_Kx + _Px) % _Nx] + _First[(_Kx - 1) % _Nx]);
result_type _R4 = (result_type)((_R3 - _Kx % _Nx) & _Mask);
_First[(_Kx + _Px) % _Nx] =
(_First[(_Kx + _Px) % _Nx] ^ _R3) & _Mask;
_First[(_Kx + _Qx) % _Nx] =
(_First[(_Kx + _Qx) % _Nx] ^ _R4) & _Mask;
_First[_Kx % _Nx] = _R4;
}
}
}
result_type _Xor27(result_type _Val) const
{ // shift and merge
return (_Val ^ (_Val >> 27));
}
_STD vector<result_type> _Myvec;
};
// TEMPLATE FUNCTION generate_canonical
template<class _Real,
size_t _Bits,
class _Gen>
_Real generate_canonical(_Gen& _Gx)
{ // build a floating-point value from random sequence
int _Minbits = _Bits < 1 ? 1 : _Bits;
if (_STD numeric_limits<_Real>::digits < _Minbits)
_Minbits = _STD numeric_limits<_Real>::digits;
_Real _Gxmin = (_Real)(_Gx.min)();
_Real _Ans = (_Real)_Gx() - _Gxmin;
_Real _Base = (_Real)(_Gx.max)() + (_Real)1 - _Gxmin;
double _Basen = _CSTD ldexp(1.0, _Minbits);
for (; 1.0 < _Basen; _Basen /= _Base)
_Ans = _Ans * _Base + (_Real)_Gx() - _Gxmin;
return (_Ans);
}
#endif /* _HAS_CPP0X */
// TEMPLATE CLASS variate_generator AND HELPERS
template<class _Ty>
class _Wrap_eng
{ // provide uniform interface to engines passed
// by value, reference, and pointer
public:
typedef _Ty _Type;
_Wrap_eng(_Ty _Earg)
: _Eng(_Earg)
{ // construct
}
const _Ty& _Get() const
{ // return reference to engine
return (_Eng);
}
_Ty& _Get()
{ // return reference to engine
return (_Eng);
}
private:
_Type _Eng;
};
template<class _Ty>
class _Wrap_eng<_Ty&>
{ // uniform interface to engines passed by value, reference, or pointer
public:
typedef _Ty _Type;
_Wrap_eng(_Ty& _Earg)
: _Eng(&_Earg)
{ // construct
}
const _Ty& _Get() const
{ // return reference to engine
return (*_Eng);
}
_Ty& _Get()
{ // return reference to engine
return (*_Eng);
}
private:
_Type *_Eng;
};
template<class _Ty>
class _Wrap_eng<_Ty *>
{ // provide uniform interface to engines passed
// by value, reference, and pointer
public:
typedef _Ty _Type;
_Wrap_eng(_Ty *_Earg)
: _Eng(_Earg)
{ // construct
}
const _Ty& _Get() const
{ // return reference to engine
return (*_Eng);
}
_Ty& _Get()
{ // return reference to engine
return (*_Eng);
}
private:
_Type *_Eng;
};
template<class _Engine,
class _Tgt_type>
class _Ewrap
{ // wrap an engine, producing an engine
// returning non-negative values of type _Tgt_type
// INVALID for engine producing [-1, INT_MAX], _Val-_Emin overflows
public:
typedef typename _Wrap_eng<_Engine>::_Type _Engine_value_type;
typedef typename _Engine_value_type::result_type result_type;
_Ewrap(_Engine _Earg, int _Int_eng, int _Int_dist)
: _Eng(_Earg),
_Factor(_Getfactor(_Int_eng, _Int_dist)),
_Emin((_Eng._Get().min)())
{ // construct
}
_Tgt_type operator()()
{ // return wrapped value
return (_Scale(_Eng._Get()()));
}
_Tgt_type (min)() const
{ // return minimum value in range
return (_Tgt_type(0));
}
_Tgt_type (max)() const
{ // return maximum value in range
return (_Scale((_Eng._Get().max)()));
}
_Engine_value_type& _Get()
{ // return reference to engine object
return (_Eng._Get());
}
const _Engine_value_type& _Get() const
{ // return const reference to engine object
return (_Eng._Get());
}
private:
_Wrap_eng<_Engine> _Eng;
const _Tgt_type _Factor;
typename _Engine_value_type::result_type _Emin;
_Tgt_type _Scale(typename _Engine_value_type::result_type _Val) const
{ // translate and scale _Val to match range of _Tgt_type
return ((_Tgt_type)((_Val - _Emin) * _Factor));
}
_Tgt_type _Getfactor(int _Int_eng, int _Int_dist) const
{ // return scale factor to map engine's range to _Tgt_type
if (_Int_eng)
{ // engine's result type is integer
if (_Int_dist)
return (1);
else
return (_Tgt_type(1.0) / (_Tgt_type((_Eng._Get().max)())
- _Tgt_type((_Eng._Get().min)()) + _Tgt_type(1)));
}
else
{ // engine's result type is not integer
if (_Int_dist)
return (_Tgt_type((_STD numeric_limits<_Tgt_type>::max)()
/ ((_Eng._Get().max)() - (_Eng._Get().min)())));
else
return ((_Tgt_type)(1.0 / (_Tgt_type((_Eng._Get().max)())
- (_Eng._Get().min)())));
}
}
_Ewrap& operator=(const _Ewrap&);
};
template<class _Engine,
class _Distrib>
class variate_generator
{ // template class combines engine and distribution to create generator
public:
typedef _Engine engine_type;
typedef typename _Wrap_eng<_Engine>::_Type engine_value_type;
typedef _Distrib distribution_type;
typedef typename _Distrib::result_type result_type;
typedef _Ewrap<_Engine, typename _Distrib::input_type> _Eng_wrapper;
variate_generator(_Engine _Earg, _Distrib _Dx)
: _Eng(_Earg, _STD numeric_limits<
typename engine_value_type::result_type>::is_integer,
_STD numeric_limits<
typename _Distrib::input_type>::is_integer),
_Dist(_Dx)
{ // construct
}
result_type operator()()
{ // return next value
return (_Dist(_Eng));
}
template<class _Ty>
result_type operator()(_Ty _Value)
{ // return next value that doesn't exceed _Value
return (_Dist(_Eng, _Value));
}
engine_value_type& engine()
{ // return reference to engine object
return (_Eng._Get());
}
const engine_value_type& engine() const
{ // return const reference to engine object
return (_Eng._Get());
}
distribution_type& distribution()
{ // return reference to distribution object
return (_Dist);
}
const distribution_type& distribution() const
{ // return const reference to distribution object
return (_Dist);
}
result_type (min)() const
{ // return minimum value in distribution's range
return ((_Dist.min)());
}
result_type (max)() const
{ // return maximum value in distribution's range
return ((_Dist.max)());
}
private:
_Eng_wrapper _Eng;
distribution_type _Dist;
};
// MULTIPLE PRECISION MATH FUNCTIONS
#ifdef _ULONGLONG
typedef _ULONGLONG _Max_type;
#else /* _ULONGLONG */
typedef unsigned long _Max_type;
#endif /* _ULONGLONG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -