调整算法以生成随机强度值

时间:2009-06-03 18:24:51

标签: php algorithm random statistics

几天前,you helped me to find out an algorithm for generating random strength values in an online game (thx especially John Rasch)

function getRandomStrength($quality) {
    $rand = mt_rand()/mt_getrandmax();
    $value = round(pow(M_E, ($rand - 1.033) / -0.45), 1);
    return $value;
}

此函数生成介于1.1和9.9之间的值。现在我想调整这个函数,以便它给出相同概率的值,但在另一个区间,例如, 1.5到8.0。如果你能用额外的参数实现这一点,那将是完美的。

如果你能帮助我,那就太好了。提前谢谢!

3 个答案:

答案 0 :(得分:5)

原始代码中的值1.033和-0.45是提供标度1.1 - 9.9的幻数。如果在下面的代码中传入1.1和9.9作为参数$low$high,则应该得到相同的结果。

function getRandomStrength($low, $high) {
    // TODO: validate the input
    $ln_low = log( $low, M_E );
    $ln_high = log( $high, M_E );
    $scale = $ln_high - $ln_low;

    $rand = ( mt_rand() / mt_getrandmax() ) * $scale + $ln_low;
    $value = round( pow( M_E, $rand), 1 );
    return $value;
}

您应该能够传递$low$high的任何范围,并获得该范围内的对数分布。 (我会将范围有效性检查留给您,但0< $low< $high应为真。)

这通过反向计算在所提供的范围内生成对数标度所需的线性标度来工作。例如,如果我希望我的对数比例为1.1 - 9.9,我会得到每个值的自然对数,给我0.0953 - 2.2925。然后,我在此线性范围内生成一个随机数,并将e提升为随机功率,将其转换回日志范围。

答案 1 :(得分:3)

一种方法是缩放值:

function getRandomStrength($quality,$min,$max) {
    $rand = mt_rand()/mt_getrandmax();
    $value = round(pow(M_E, ($rand - 1.033) / -0.45), 1);
    $value = $value - 1.1
    $value = $value * ((max-min) / 8.8)
    $value = $value + $min
    return $value;
}

答案 2 :(得分:2)

在归一化范围内缩放和取代分布:

D(a,b) = (D(0,1)*(b-a))+a

首先从原函数D(c,d)得到D(0,1),做反求:

D(0,1) = (D(c,d)-c)/(d-c)

在你的情况下,D是原始函数(指数函数),a是1.5,b是8.5,c是1.1,d是9.9