2017-03-18 117 views
0

在PHP中,我需要用兩個權重選擇1到100之間的隨機數。這些權重也可以在1到100之間。如果兩個權重都很低,我需要隨機數加權低,高權重高。如果一個體重很高,一個體重較低,或者如果他們都是中距離的,那麼我認爲隨機數在50左右隨機加權。帶兩個權重的加權隨機

我不確定最好的方法去做這件事。任何建議都會很棒!

+1

運行所以,如果這兩個權重低,品種齊全的1 -100仍然是可能的,但高價值的可能性不大?還是最大降低?這感覺就像是一種問題,如果你可以更完整地指出它,那麼答案可能就是暗示。 – samgak

+0

如果一個權重是10而另一個權重是90,那麼價值的分佈是相同的,如果一個是40而另一個是60,或者兩個權重是50?在這種情況下,你可能只是平均兩個數字。這個數字意味着什麼?它只是你想得到的隨機數的平均值嗎? – samgak

+0

如果兩者都很低,那麼整個範圍仍然是可能的。我想平均值可能是最好的方法。這樣一個明顯的答案。謝謝! –

回答

0

您需要更多關於這些權重的信息:它們是否會影響該指數的概率,以及該概率增加的幅度會向相鄰指數蔓延多少。

我會在這裏假設可以提供這些參數,並且概率以正態分佈擴散。

我會建議創建一個數組,每個索引的概率。你從他們每個人的常數(例如1)開始,這意味着所有索引具有被選擇的相同概率。

然後,一個函數可以對它應用一個權重,給定一個權重應該以權重爲中心的指數,權重本身(它在多大程度上增加了該指數的現有「權重」),以及價差正態分佈與生成概率分佈的偏差)。

這是做這種事情的代碼。這並不意味着在統計上的聲音,但我相信它會做的工作以令人滿意的方式:

function density($x, $median, $stddev) { 
    // See https://en.wikipedia.org/wiki/Probability_density_function#Further_details 
    return exp(-pow($x - $median,2)/(2*pow($stddev,2))/(2*pi()*$stddev)); 
} 

function homogeneous_distribution($size) { 
    return array_fill(0, $size, 1); 
} 

function add_weight(&$distr, $median, $weight, $spread) { 
    foreach ($distr as $i => &$prob) { 
     $prob += $weight * density($i, $median, $spread); 
    } 
} 

function random_float() { // between 0 and 1 (exclusive) 
    return mt_rand(0, mt_getrandmax() - 1)/mt_getrandmax(); 
} 

function weighted_random($distr) { 
    $r = random_float() * array_sum($distr); 
    foreach ($distr as $i => $prob) { 
     $r -= $prob; 
     if ($r < 0) return $i; 
    } 
} 

// Example use with 20 instead of 100. 
$distr = homogeneous_distribution(20); // range is 0 .. 19 
add_weight($distr, 0, 4, 1); // at index 0, put a weight of 4, spreading with 1 
add_weight($distr, 16, 8, 0.5); // at index 16, put a weight of 8, spreading with 0.2 

// Print distribution (weights for every index): 
echo "DISTRIBUTION:\n"; 
print_r($distr); 

// Get 10 weighted random indexes from this distribution: 
echo "RANDOM SAMPLES:\n"; 
foreach (range(0, 10) as $i) { 
    echo weighted_random($distr) . "\n"; 
} 

看到它在rextester.com