2

我想知道使用这个中值函数的原因可能是什么,而不是仅仅计算min + (max - min) / 2

// used by the random number generator
private static final double  M_E12 = 162754.79141900392083592475;

/**
 * Return an estimate of median of n values distributed in [min,max)
 * @param min the minimum value 
 * @param max the maximum value
 * @param n 
 * @return an estimate of median of n values distributed in [min,max)
 **/
private static double median(double min, double max, int n) 
{
    // get random value in [0.0, 1.0)
    double t = (new Random()).nextDouble();

    double retval;
    if (t > 0.5) {
        retval = java.lang.Math.log(1.0-(2.0*(M_E12-1)*(t-0.5)/M_E12))/12.0;
    } else {
        retval = -java.lang.Math.log(1.0-(2.0*(M_E12-1)*t/M_E12))/12.0;
    }
    // We now have something distributed on (-1.0,1.0)
    retval = (retval+1.0) * (max-min)/2.0;
    retval = retval + min;
    return retval;
}

我的方法的唯一缺点可能是它的确定性,我会说?

整个代码可以在这里找到,http://www.koders.com/java/fid42BB059926626852A0D146D54F7D66D7D2D5A28D.aspx? s= cdef%3atree#L8,顺便说一句。

谢谢

4

2 回答 2

8

[试图在这里覆盖一个范围,因为我不清楚你不理解什么]

首先,中位数是中间值。[0,0,1,99,99] 的中位数为 1。

所以我们可以看到给出的代码没有计算中位数(它没有找到中间值)。相反,它是从一些理论分布中估算出来的。正如评论所说。

你给的forumla是中点。如果许多值在最小值和最大值之间均匀分布,那么是的,这是对中位数的一个很好的估计。在这种情况下(大概)这些值不是以这种方式分布的,因此需要一些其他方法。

您可以通过计算上述数字的中点来了解为什么这可能是必要的——您的公式将给出 49.5。

使用估计的原因可能是它比找到中位数要快得多。进行随机估计的原因可能是避免多次调用出现最坏的情况。

最后,抱歉,我不知道这种情况下的分布是什么。您可能需要搜索数据结构和/或作者姓名以查看是否可以找到论文或书籍参考(我认为它可能假设幂律,但请参阅下面的编辑 - 它似乎添加了一个非常小的更正)(我不确定这是否是您要问的,或者您是否更普遍感到困惑)。

[编辑] 再看一些,我认为 log(...) 对均匀随机 t 产生了中心偏差。所以它基本上是按照你的建议做的,但有一些分布在 0.5 左右。这是一个案例的情节,表明这retval实际上是一个很小的调整。

于 2012-02-25T19:35:55.250 回答
4

我不能告诉你这段代码试图达到什么目的。首先它甚至不使用n

但从外观上看,它只是在 range 中生成某种指数分布的随机值[min,max]。请参阅http://en.wikipedia.org/wiki/Exponential_distribution#Generating_exponential_variates


Interestingly, Googling for that magic number brings up lots of relevant hits, none of which are illuminating: http://www.google.co.uk/search?q=162754.79141900392083592475.

于 2012-02-25T19:35:58.097 回答