【问题标题】:How to implement a random number generator that is not random?如何实现非随机的随机数生成器?
【发布时间】:2011-07-03 12:20:49
【问题描述】:

我需要一个随机数生成器,它可以生成 n 和 m 之间的各种数字,但不具有相同的概率。我想在 n 和 m 之间设置一个值 x,其中可能性最高:

有没有使用 Random 类的简单方法来做到这一点?可能性应该具有二项分布或类似的形式(精确的二项分布并不重要,粗略的近似也可以)

编辑

也许我必须澄清一下:我不是在寻找二项式或高斯分布,而是在寻找这样的东西:

我想定义值 x 应该是最高可能性的位置。

编辑

不幸的是,以前接受的答案does not seem to work 我是多么怀疑。所以我还在寻找答案!

【问题讨论】:

标签: c# .net algorithm random


【解决方案1】:

您可以使用Box-Muller 转换从均匀分布在 0 和 1 之间的数字序列生成伪随机正态分布数字序列。

【讨论】:

  • 请注意,此方法生成 两个 高斯分布数从均匀分布数。因此,与仅在您发布时生成一个相比,它的速度大约是其两倍。
【解决方案2】:

您需要一个用于“正态分布”的生成器。看看这里: http://www.csharpcity.com/reusable-code/random-number-generators/

【讨论】:

    【解决方案3】:

    Java SDK 有很好的实现 Random.nextGaussian(取自http://download.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#nextGaussian())

    我希望很清楚如何从java源解析到c#

    synchronized public double nextGaussian() {
        if (haveNextNextGaussian) {
                haveNextNextGaussian = false;
                return nextNextGaussian;
        } else {
                double v1, v2, s;
                do { 
                        v1 = 2 * nextDouble() - 1;   // between -1.0 and 1.0
                        v2 = 2 * nextDouble() - 1;   // between -1.0 and 1.0
                        s = v1 * v1 + v2 * v2;
                } while (s >= 1 || s == 0);
                double multiplier = Math.sqrt(-2 * Math.log(s)/s);
                nextNextGaussian = v2 * multiplier;
                haveNextNextGaussian = true;
                return v1 * multiplier;
        }
     }
    

    更新:我如何改变中位数:

    public static float gaussianInRange(float from, float mean, float to)
    {
        if( !(from < mean && mean < to) )
            throw new IllegalArgumentException(MessageFormat.format("RandomRange.gaussianInRange({0}, {1}, {2})", from, mean, to));
    
        int p = _staticRndGen.nextInt(100);
        float retval;
        if (p < (mean*Math.abs(from - to)))
        {
            double interval1 = (_staticRndGen.nextGaussian() * (mean - from));
            retval = from + (float) (interval1);
        }
        else
        {
            double interval2 = (_staticRndGen.nextGaussian() * (to - mean));
            retval = mean + (float) (interval2);
        }
        while (retval < from || retval > to)
        {
            if (retval < from)
                retval = (from - retval) + from;
            if (retval > to)
                retval = to - (retval - to);
        }
        return retval;
    }
    

    【讨论】:

    • 是的,这很清楚。但是我现在如何才能将最大可能性设置为我的值?
    • @Roflcoptr - nextGaussian 的每个 SDK 返回值是一个大约 0.0 的值,偏差为 1.0(因此结果在范围(-1;1)内)。因此,只需附加 +2 即可获得范围 (1..3) 内的值
    • @Dewfy:是的,我明白这一点,但最高的可能性是 0 和 1.5。但是,如果最高可能性应该接近 3 怎么办?
    • @Roflcoptr - 好吧,实际上我也遇到了同样的问题 - 将 shift 设为相对中位数,所以请查看我的更新答案。
    • @Dewfy 非常感谢,这正是我正在寻找的整个方法!
    【解决方案4】:

    smth 比较简单。 您可以生成 2 个随机数: 1st 定义了第二个随机数与 x 的接近程度。

    您可以使用任何您喜欢的断点/函数级别。

    【讨论】:

      猜你喜欢
      • 2010-12-04
      • 2012-08-10
      • 1970-01-01
      • 2013-01-08
      • 1970-01-01
      • 2011-11-24
      • 2019-08-03
      • 2023-03-15
      • 2023-01-03
      相关资源
      最近更新 更多