人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPで下記のような確率で答えを求めたいのですが、こんなソースしか思いつきません。
何か良いアドバイスをお願いします。

【確率】
A:60%
B:20%
C:10%
D:7%
E:3%

【こんなソース】
$pro = rand(1, 100);

switch ($pro) {
case ($pro <= 60):
$ans = "A";
break;
case ($pro <= 80):
$ans = "B";
break;
case ($pro <= 90):
$ans = "C";
break;
case ($pro <= 97):
$ans = "D";
break;
default:
$and = "E";
}


●質問者: atoly
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:CASE PHP Rand switch アドバイス
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● ukiya
●23ポイント

こんな感じでは如何ですか。

$foo=array(
 "A" => 60,
 "B" => 20,
 "C" => 10,
 "D" => 7,
 "E" => 3,
);
$r = rand(1, 100);
foreach($foo as $k => $v){
 if($r<=$v){
 $ans=$k;
 break;
 }
 $r-=$v;
}
echo $ans;

配列に確率が大きい順に値を格納するのが高速化のポイントです。


2 ● takfjt
●23ポイント

こんな感じでしょうか

$p = array(
 array("kakuritu"=>60, "output"=>"A"),
 array("kakuritu"=>20, "output"=>"B"),
 array("kakuritu"=>10, "output"=>"C"),
 array("kakuritu"=>7, "output"=>"D"),
 array("kakuritu"=>3, "output"=>"E")
);

$pro = rand(1, 100);

for ($i = 0, $sum = 0; $i < count($p); $i++) {
 $kakuritu = $p[$i]["kakuritu"] + $sum;
 if ($pro <= $kakuritu) {
 $ans = $p[$i]["output"];
 break;
 }
 $sum += $p[$i]["kakuritu"];
}

3 ● tezcello
●23ポイント
$answers = array('A'=>'60', 'B'=>'20', 'C'=>'10', 'D'=>'7', 'E'=>'3');
$i = rand(1, 100);
$j = 0;
foreach ($answers as $key=>$val){
 $j += $val;
 if ($i <= $j) {
 $ans = $key;
 break;
 }
}

僕もこんなのしか思いつきませんが。


4 ● Mook
●25ポイント ベストアンサー

ご自身で考えられた例で十分だと思いますが、

関数で実装したサンプルです。

<?
// -----------------------------------
// 出現確率の定義 : 合計が100でなくともOK
// -----------------------------------
$randArray = Array(
 "A"=> 60,
 "B"=> 20,
 "C"=> 10,
 "D"=> 7,
 "E"=> 3 );

// -----------------------------------
// 出現確率に応じて回答を返す関数
// -----------------------------------
function rndAnswer( $rndArray ) {
 $rndNum = rand(1, array_sum( $rndArray ) ); // 1 ?合計 の中で乱数を発生

 $subTotal = 0;
 foreach( $rndArray as $key => $num ) {
 $subTotal += $num;
 if ( $subTotal >= $rndNum ) {
 return $key;
 }
 }
}
// -----------------------------------
// 実際に100回実行してみるテスト
// -----------------------------------
print "RANDOM TEST<br>\n";
print '<table border="1">'."\n";
foreach( $randArray as $key => $num ) {
 $ansCount[$key] = 0;
}

for( $i=0 ; $i<10 ; $i++ ) {
 print "<tr>\n";
 for( $j=0 ; $j<10 ; $j++ ) {
 $ans = rndAnswer( $randArray );
 $ansCount[$ans]++;
 print "<td>$ans</td>\n";
 print "</td>\n";
 }
 print "</tr>\n";
}
print "</table>\n";
 // キー順にソート
ksort( $ansCount );
 // 回答の回数を表示
foreach( $randArray as $key => $num ) {
 print "$key({$num})... {$ansCount[$key]}回<br>\n";
}
?>

おまけで、実際の出現回数をテストするルーチンを実装しています。

F5 を押すごとに、テストできます。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ