重み付きの抽選ロジックは既に色々なところで紹介されていますが、ちょっと必要になったので作ってみました。配列要素の値に重み(確率)となる整数値を入れて渡すと抽選された要素のキーを返します。サンプルでは、hash配列を渡していますが、array配列でも同様に要素のキーを返します。
/* * 配列から1つの要素キーを抽選する。 * * $entries: array($key => $weight, ...) * 配列の値に抽選の割合(重み)を整数値で指定。 */ function array_rand_weighted($entries){ $sum = array_sum($entries); $rand = rand(1, $sum); foreach($entries as $key => $weight){ if (($sum -= $weight) < $rand) return $key; } } // 抽選候補となる配列 $entries = array( "1等" => 10, "2等" => 20, "3等" => 30, "ハズレ" => 40, ); // 抽選 $result_key = array_rand_weighted($entries);
本当に確率通りに抽選されているか、100回と、1000回動作させてみた結果です。
ちゃんと確率通りに分布しているようです。
// ▼100回実行 抽選結果をカウント $result = array(); for($i=0; $i<100; $i++){ $key = array_rand_weighted($entries); @$result[$key]++; } print_r($result); /* Array ( [ハズレ] => 40 [3等] => 32 [2等] => 21 [1等] => 7 ) */ // ▼1000回実行 抽選結果をカウント $result = array(); for($i=0; $i<1000; $i++){ $key = array_rand_weighted($entries); @$result[$key]++; } print_r($result); /* Array ( [ハズレ] => 418 [3等] => 291 [2等] => 203 [1等] => 88 ) */
0 件のコメント:
コメントを投稿