C++ 带有g+的随机整数+;4.4.5

C++ 带有g+的随机整数+;4.4.5,c++,random,integer,gcc4.4,C++,Random,Integer,Gcc4.4,我想在某个时间间隔内生成随机整数。我不想使用带有时间(NULL)的srand的基本实现作为种子,因为我已经了解到这不是最“随机”的实现方式 我已经看到很多文章描述了如何在C++11中使用std::uniform_int_分布,但不幸的是,我工作的计算集群仍然使用g++4.4.5,它没有这种功能。此编译器是否有类似的功能?/*rand31pmc.c(cX)2015 adolfo。dimare@gmail.com */ /* rand31pmc.h (cX) 2015 adolfo.dimare@g

我想在某个时间间隔内生成随机整数。我不想使用带有时间(NULL)的srand的基本实现作为种子,因为我已经了解到这不是最“随机”的实现方式

我已经看到很多文章描述了如何在C++11中使用std::uniform_int_分布,但不幸的是,我工作的计算集群仍然使用g++4.4.5,它没有这种功能。此编译器是否有类似的功能?

/*rand31pmc.c(cX)2015 adolfo。dimare@gmail.com */
/* rand31pmc.h (cX) 2015 adolfo.dimare@gmail.com */

/**  \file  rand31pmc.h
     \brief Park && Miller && Carta 32 bit random number generator.

     Park, Stephen K. && Miller, Keith W.:
        "Random Number Generators Good Ones Are Hard To Find",
         Computing Practices, Communications of the ACM,
         Volume 31 Number 10, pp 1192-1201, October 1988

     This is the Park-Miller "minimal standard"
     Linear Congruential Generator (LCG):
     (seed * 16807 mod(2^31 - 1))
     \see http://www.firstpr.com.au/dsp/rand31/

     \see http://www.di-mare.com/adolfo/p/src/rand31pmc.zip
*/

#ifndef    rand31pmc_h
#define    rand31pmc_h /**< Used to avoid multiple inclusion */

#include <stdint.h> /* int32_t [available since C99] */
/* #include <cstdint> // requires compiling with option '-std=c++11' [GCC] */

#ifdef __cplusplus /* C++ wrap for C language routines */
extern "C" {
#endif

    /* This is the C language implementation */
    void    pm_seed(  int32_t * SEED , int32_t new_seed );
    int32_t pm_next(  int32_t * SEED );
    int32_t pmc_next( int32_t * SEED );
    int32_t pm_range( int32_t * SEED , int32_t n , int32_t(*next)(int32_t*) );

#ifdef __cplusplus /* C++ wrap for C language routines */
} /* extern "C" */
#endif


#ifdef __cplusplus /* __cplusplus -> This is the C++ implementation  */

/// Trick to avoid using a 'rand31pmc.cpp' file
template <class T> class rand31pmc;
/*
    This is a template specialization for 'rand31pmc<>'. As the C++ compiler
    requires template implementations to be in the header file, there is no
    need to use file 'rand31pmc.cpp' to implement class methods. This means
    that using the directive '#include "rand31pmc.h"' (to include this
    header file) is all that needs to be done to use this random number
    generator.
*/

// Park && Miller && Carta 32 bit random number generator.
// (seed * 16807 mod(2^31 - 1)) Linear Congruential Generator (LCG)
// http://www.firstpr.com.au/dsp/rand31/
template <> class rand31pmc<int32_t> {
    private: int32_t m_seed; ///< Used to generate next random number.

    /// Constructor.
    public: rand31pmc( int32_t sd=1 ) : m_seed(1) {
        seed( sd );
    }

    /** Sets the seed value used by this generator.
        - This generator must be initialized by assigning seed a
          value between 1 and 2147483646.
        - Neither 0 nor 2^31-1 are valid seed values.
    */
    public: void seed( int32_t sd=1 ) {
        if ( 0<sd && sd<2147483647 ) {
            m_seed = sd;
        }
    }

    /// Return next random number in range [0..n-1].
    /// - Returns range(n).
    public: int32_t nextRange(int32_t n) {
        return range(n);
    }

    private: enum {
        a = 16807,      ///<  16807
        m = 2147483647, ///< 2^31-1
        q = m / a,      ///< 127773
        r = m % a       ///<   2836
    };

    /** Returns next random number in range [1..2^31-2].
        - This is a "full-period-multiplier".
        - This is the original Parker && Miller implementation
          <code> (seed * 16807 mod(2^31 - 1)) </code>
    */
    public: int32_t pm_next();

    /** Returns next random number in range [1..2^31-2].
        - This is a "full-period-multiplier".
        - Carta's improvement yields an implementation that
          does not use division.
        <code> (seed * 16807 mod(2^31 - 1)) </code>
        \see http://www.firstpr.com.au/dsp/rand31/
    */
    public: int32_t pmc_next();

    // Return next random number in range [0..n-1].
    public: int32_t range(int32_t n);

    /// Informal test to verify this implementation against the original.
    public: static bool test_rand31pmc();
}; // class rand31pmc<int32_t>


// template<> not used for a member of a specialization
int32_t rand31pmc<int32_t>::pm_next() {
    int32_t lo, hi, test;

    hi = m_seed / q;
    lo = m_seed % q;
    test = a * lo - r * hi;
    m_seed = ( test>0 ? test : test+m );
    return m_seed;
}

// template<> not used for a member of a specialization
/* *** Carta's no division implementation *** */
int32_t rand31pmc<int32_t>::pmc_next() {
    uint32_t lo, hi;

    lo = 16807 * (m_seed & 0xFFFF);
    hi = 16807 * (m_seed >> 16);

    lo += (hi & 0x7FFF) << 16;
    lo += hi >> 15;

    if (lo > 0x7FFFFFFF) lo -= 0x7FFFFFFF;

    return ( m_seed = lo );
}

/* Original Park && Miller Pascal implementation:

***************************************************************
* Park, Stephen K. && Miller, Keith W.:                       *
*     "Random Number Generators Good Ones Are Hard To Find",  *
*      Computing Practices, Communications of the ACM,        *
*      Volume 31 Number 10, pp 1192-1201, October 1988        *
***************************************************************

The following integer version of rand31pmc is correct
on any system for which maxint is 2^31 - 1 or larger.
First declare var seed : integer and then use

function rand31pmc : real;
(* Integer Version 2 *)
const
    a = 16807;
    m = 2147483647;
    q = 127773; (* m div a *)
    r = 2836;   (* m mod a *)
var
    lo, hi, test : integer;
begin
    hi := seed div q;
    lo := seed mod q;
    test := a * lo - r * hi;
    if test > 0 then
        seed := test
    else
        seed := test + m;
    rand31pmc := seed / m
end;
*/

/** Converts the next random into range [0..n-1]==[0..n[.
    - Returns cero when (n<=0).
    - Uses 'pmc_next()' to get random numbers.
    - Uses 64 bit multiplication and 32 bit division.
    - This algorithm rejects values that would result in an uneven
      distribution; the expected number of rejections before is 2.
    - Translated from Java class Random.
    \see http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt%28int%29
*/
int32_t rand31pmc<int32_t>::range(int32_t n) {
    if (n <= 0)
        { return 0; }

    if ((n & -n) == n)  // i.e., n is a power of 2
        return (int32_t)((n * (int64_t)(pmc_next())) >> 31);

    int32_t bits, val;
    do {
        bits = pmc_next();
        val = bits % n;
    } while (bits - val + (n-1) < 0);
    return val;
}


bool rand31pmc<int32_t>::test_rand31pmc() {
/*  Pascal implementation from Park && Miller pp 1195

    seed := 1;
    for n := 1 to 10000 do
        u := rand31pmc;
    Writeln('The current value of seed is : ', seed);

    produces 1043618065.
*/
{
    /* Check Carta's implementation for all values */
    rand31pmc<int32_t> pm,carta;
    pm.seed(1), carta.seed(1);
    for ( int32_t i=1; i<2147483647; ++i ) {
        int32_t pmN  = pm.pm_next();
        int32_t pmcN = carta.pmc_next();

        if ( pmN != pmcN ) {
            return false; // abort!
        }
    }
    return true;
}

{{  // Example -> rand31pmc<>
    int32_t u=-1; // seed should be in range [1..2^31-2]
    rand31pmc<int32_t> rand(u); // 'seed' for 'rand' is 1
    rand.seed(1);               // redundant
    for ( int32_t i=0; i<10000; ++i ) {
        u = rand.pmc_next();    // pmc-> Park && Miller && Carta
    }
    return (u==1043618065);
}}
}

/** \class rand31pmc<int32_t>
    \brief Park && Miller && Carta 32 bit random number generator.
        (seed * 16807 mod(2^31 - 1)) Linear Congruential Generator (LCG)
        \see http://www.firstpr.com.au/dsp/rand31/
    \dontinclude rand31pmc.h
    \skipline    Example -> rand31pmc<>
    \until       }}
*/


#endif

#endif  /* rand31pmc_h */

/*
    Source code available here:
    http://www.di-mare.com/adolfo/p/src/rand31pmc.zip
*/

/* http://stackoverflow.com/questions/22999513/ */
/* EOF: rand31pmc.h */
/**\file rand31pmc.c \\C rand31pmc.h的简短C语言实现文件。 \看http://www.di-mare.com/adolfo/p/src/rand31pmc.zip */ /*Park&Miller 32位随机数发生器*/ #包括“rand31pmc.h” #include/*int32\t[自C99起提供]*/ /**设置*种子以生成更多随机数。 -必须通过分配种子来初始化此生成器 值介于1和2147483646之间。 -0和2^31-1都不是有效的种子值。 */ 无效pm_种子(int32_t*种子、int32_t新种子){ 若(0 31),; int位,val; 做{ 比特=下一个(31); val=位%n; }而(位-val+(n-1)<0); 返回val; } 套期保值“近似”仅在上述说明中使用 因为下一种方法只是近似的无偏源 独立选择的位。如果它是一个完美的来源 选择位,则显示的算法将从 规定的范围与完美的一致性。 算法有点复杂。它拒绝会导致错误的值 不均匀分布(由于2^31不能被 n) 。值被拒绝的概率取决于n。最坏的 情况为n=2^30+1,拒绝概率为1/2,且 循环终止前的预期迭代次数为2。 该算法特别处理n是2的幂的情况:it 从底层返回正确数量的高阶位 伪随机数发生器。在没有特殊待遇的情况下 将返回正确数量的低位。线性同余 伪随机数生成器,例如由 类在其值序列中具有短周期 低阶位。因此,这种特殊情况大大增加了 如果n,则连续调用此方法返回的值序列 是二的小幂。 参数: n-要返回的随机数的界。必须是积极的。 返回: 下一个伪随机、均匀分布的int值介于0之间 (包括)和n(不包括)来自此随机数生成器的 序列 */ } /* 此处提供的源代码: http://www.di-mare.com/adolfo/p/src/rand31pmc.zip */ /* http://stackoverflow.com/questions/22999513/ */ /*EOF:rand31pmc.c*/
您可以复制Java.Random.nextInt(int n)实现:

我想你需要这些随机数来进行统计,而不是加密。只需使用

您有增压器吗?我的答案中有一个例子,我还使用
rand
提供了C常见问题解答建议。我不认为声明反对使用
srand()
time()
的文本对您的备选方案有任何建设性的意见?(如果你要去网站基金会的话,链接会很好)。不管怎样,在紧要关头,你可以通过一个像样的加密摘要(并非罕见)或使用第三方库,如boost、OpenSSL、Windows加密库等,来实现你自己的加密。我建议你访问www.agner.org,你使用的是哪种操作系统?在Linux上有供您使用的
/dev/random
/dev/uradom
,谢谢大家的评论。我有boost(无论哪个版本不包含boost::random::uniform\u int\u分布)。沙菲克,我以前在谷歌搜索时遇到过你的答案,但它与我必须使用的设置不兼容。关于操作系统,它是科学的Linux 6,但是我更喜欢使用C++内部的东西而不是调用BASH随机数生成器。问题特别提到了
uniform_int_distribution
,它使用了发电机遵循分布的C++11/Boost模型。这表明发电机已经是一个解决了的问题。Boost和C++11都有Mersenne Twister作为生成器选择,顺便说一句。@MSalters:由于OP不想使用
srand()
作为源代码,我建议使用MT。您可以从中获得任何分布。有了更流行的GCC g++,OP就已经拥有了他所需要的东西。
/* rand31pmc.c (cX) 2015 adolfo.dimare@gmail.com */

/**  \file  rand31pmc.c
     \brief C language Implementation file for \c rand31pmc.h.

     \see http://www.di-mare.com/adolfo/p/src/rand31pmc.zip
*/

/* Park && Miller 32 bit random number generator */
#include  "rand31pmc.h"

#include <stdint.h> /* int32_t [available since C99] */

/** Set *SEED to generate further random numbers.
   - This generator must be initialized by assigning seed a
     value between 1 and 2147483646.
   - Neither 0 nor 2^31-1 are valid seed values.
*/
void pm_seed( int32_t * SEED , int32_t new_seed ) {
    if ( 0<(new_seed) && (new_seed) < 2147483647 ) {
        *SEED = new_seed;
    }
}

/** Returns the next random value in range [1..2^31-2].
    - This is the Park && Miller 32 bit random number generator.
    - This is a "full-period-multiplier".
    - Carta's improvement yields an implementation that
      does not use division.
    \see http://www.firstpr.com.au/dsp/rand31/
    \see http://www.firstpr.com.au/dsp/rand31/rand31-park-miller-carta-souce-no-comments.png
*/
int32_t pmc_next( int32_t * SEED ) {
    uint32_t lo, hi;

    lo = 16807 * (*SEED & 0xFFFF);
    hi = 16807 * (*SEED >> 16);

    lo += (hi & 0x7FFF) << 16;
    lo += hi >> 15;

    if (lo > 0x7FFFFFFF) lo -= 0x7FFFFFFF;

    return ( *SEED = lo );
}

/** Returns the next random value in range [1..2^31-2].
    - This is the Park && Miller 32 bit random number generator.
    - This is a "full-period-multiplier".
*/
int32_t pm_next( int32_t * SEED ) {
    enum {
        a = 16807,
        m = 2147483647, /* 2^31-1 */
        q = m / a,      /* 127773 */
        r = m % a       /*   2836 */
    };

    {
        int32_t lo, hi, test;

        hi = *SEED / q;
        lo = *SEED % q;
        test = a * lo - r * hi;
        *SEED = ( test>0 ? test : test+m );
        return *SEED;
    }

    /* Original Pascal Implementation:

    ***************************************************************
    * Park, Stephen K. && Miller, Keith W.:                       *
    *     "Random Number Generators Good Ones Are Hard To Find",  *
    *      Computing Practices, Communications of the ACM,        *
    *      Volume 31 Number 10, pp 1192-1201, October 1988        *
    ***************************************************************

    The following integer version of Random32 is correct
    on any system for which maxint is 2^31 - 1 or larger.
    First declare var seed : integer and then use

    function Random32 : real;
    (* Integer Version 2 *)
    const
        a = 16807;
        m = 2147483647;
        q = 127773; (* m div a *)
        r = 2836;   (* m mod a *)
    var
        lo, hi, test : integer;
    begin
        hi := seed div q;
        lo := seed mod q;
        test := a * lo - r * hi;
        if test > 0 then
            seed := test
        else
            seed := test + m;
        Random32 := seed / m
    end;
    */
}

#ifndef NDEBUG
    /** Informal test to verify this implementation against the original. */
    int test_Random32() {
    /*  Implementation -> Pascal de Park && Miller pp 1195

        seed := 1;
        for n := 1 to 10000 do
            u := Random32;
        Writeln('The current value of seed is : ', seed);

        produces 1043618065.
    */
        int32_t u,i, SEED = -1;
        pm_seed(&SEED,1);
        for ( i=0; i<10000; ++i ) {
            u = pm_next(&SEED);
       }
       return (u==1043618065);
    }
#endif

/** Converts the next random 'SEED' into range [0..n-1]==[0..n[.
    - Returns cero when (n<=0).
    - Uses 'next(SEED)' to get a new random number.
    - Uses 64 bit multiplication and 32 bit division.
    - This algorithm rejects values that would result in an uneven
      distribution; the expected number of rejections before is 2.
    - Copied from Java v7 class Random.
    \see http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt%28int%29
\code
        int32_t seed = 12, next, i;
        assert( "Example usage for random numbers in range [0..32[" );
        for ( i=0; i<10000; ++i ) {
            next = pm_range( &seed, 32, &pmc_next );
            assert( next < 32 );
            printf( "\n next==%d%", next );
        }
\endcode
*/
int32_t pm_range( int32_t * SEED , int32_t n , int32_t (*next)( int32_t * ) ) {
    int32_t bits, val;
    if (n <= 0)
        { return 0; }

    if ((n & -n) == n)  /* i.e., n is a power of 2 */
        return (int32_t)((n * (int64_t)( (*next)(SEED) ) ) >> 31);

    do {
        bits = pmc_next(SEED);
        val = bits % n;
    } while (bits - val + (n-1) < 0);
    return val;
/*
    Translated from Java class Random:
    http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt%28int%29
*/
/*
    public int nextInt(int n)

    Returns a pseudorandom, uniformly distributed int value between 0
    (inclusive) and the specified value (exclusive), drawn from this random
    number generator's sequence. The general contract of nextInt is that one
    int value in the specified range is pseudorandomly generated and
    returned. All n possible int values are produced with (approximately)
    equal probability. The method nextInt(int n) is implemented by class
    Random as if by:

     public int nextInt(int n) {
       if (n <= 0)
         throw new IllegalArgumentException("n must be positive");

       if ((n & -n) == n)  // i.e., n is a power of 2
         return (int)((n * (long)next(31)) >> 31);

       int bits, val;
       do {
           bits = next(31);
           val = bits % n;
       } while (bits - val + (n-1) < 0);
       return val;
     }

    The hedge "approximately" is used in the foregoing description only
    because the next method is only approximately an unbiased source of
    independently chosen bits. If it were a perfect source of randomly
    chosen bits, then the algorithm shown would choose int values from the
    stated range with perfect uniformity.

    The algorithm is slightly tricky. It rejects values that would result in
    an uneven distribution (due to the fact that 2^31 is not divisible by
    n). The probability of a value being rejected depends on n. The worst
    case is n=2^30+1, for which the probability of a reject is 1/2, and the
    expected number of iterations before the loop terminates is 2.

    The algorithm treats the case where n is a power of two specially: it
    returns the correct number of high-order bits from the underlying
    pseudo-random number generator. In the absence of special treatment, the
    correct number of low-order bits would be returned. Linear congruential
    pseudo-random number generators such as the one implemented by this
    class are known to have short periods in the sequence of values of their
    low-order bits. Thus, this special case greatly increases the length of
    the sequence of values returned by successive calls to this method if n
    is a small power of two.

    Parameters:
        n - the bound on the random number to be returned. Must be positive.
    Returns:
        the next pseudorandom, uniformly distributed int value between 0
        (inclusive) and n (exclusive) from this random number generator's
        sequence
    */
}

/*
    Source code available here:
    http://www.di-mare.com/adolfo/p/src/rand31pmc.zip
*/

/* http://stackoverflow.com/questions/22999513/ */
/* EOF: rand31pmc.c */