早些時候,我在Matlab中爲這種抽獎功能寫了一段代碼,只是爲了測試它是否可行。然而,我真的需要它在PHP中,所以我剛剛重寫了代碼,它似乎工作,但由於它涉及很多循環,我想確保我儘可能有效地做到這一點。如何優化PHP中的「彩票」功能?
的代碼做什麼:
你可以調用函數$lotto -> type($users,$difficulty)
,它將返回兩個數字。以下是解釋,$users
是在網站上註冊的用戶數量,即可能會購買機票的人數。 $difficulty
是1到10之間的數字,其中5是正常的,1是容易的,10是硬的。這裏的困難意味着要匹配彩票上的所有號碼是多麼困難。
那麼函數返回的數字是什麼?那將是$n
和$r
。 $n
是彩票上的號碼數量,$r
是您可以從彩票中選擇的號碼數量。例如,在英國,全國彩票有49個號碼,如果您選擇了6個號碼,即E。$n = 49
和$r = 6
。
函數如何計算這兩個數字?在英國國家彩票中有13,983,816種不同的機票組合。如果我運行$lotto -> type(13983816,1)
它將返回array(49,6)
。基本上它試圖做到這一點,所以有與註冊用戶一樣多的門票組合。
TL;博士,這裏是代碼:
<?php
class lotto {
public function type($users,$difficulty){
$current_r = $r = 2;
$current_n = 0;
$difficulty = ($difficulty + 5)/10; // sliding scale from 1 - 10
$last_tickets_sold = 200; // tickets sold in last lotto
$last_users = 100; // how many users there were in the last lotto
$last_factor = $last_tickets_sold/$last_users; // tickets per user
$factor = $last_factor * $difficulty;
$users *= $factor;
while($r <= 10){
$u = 0;
$n = $r;
while($u < $users && $n < 50){
$u = $this -> nCr(++$n,$r);
}
if($r == 2){
$current_n = $n;
} elseif(abs($this -> nCr($n,$r) - $users) < abs($this -> nCr($current_n,$current_r) - $users)){
// this is a better match so update current n and r
$current_r = $r;
$current_n = $n;
}
$r++;
}
return array($current_n,$current_r);
}
private function nCr($n,$r){
return $this -> factorial($n)/(
$this -> factorial($r) * $this -> factorial($n - $r)
);
}
private function factorial($x){
$f = $x;
while(--$x){
$f *= $x;
}
return $f;
}
}
$lotto = new lotto;
print_r($lotto -> type(1000,5));
?>
一個小的優化是將以前的階乘結果存儲在一個數組中,因此您不必每次都進行長時間的計算。這將映射輸入=>輸出的映射。這應該大大減少階乘的處理時間。您還可以存儲最後一個已知值,因爲您有兩個始終增加的數字。 – sean 2012-07-26 19:01:13