コードを見ると、問題は非常に簡単だと思います。ランダム化された配列があります(配列はランダム化する必要があります。実際の問題には関係しないため、一部のコードは除外されていますが、ランダム化が必要です)。配列内の各要素には、$rules
他の条件が満たされた場合(関連性がないためにここでは削除されます)を示唆する「確率」インデックス(ここでは値自体として説明されています)があります。配列要素が「トリガー」される確率(この場合、配列要素のスコアは1ずつ増加します)
コードを考えてみましょう:
<?php
// Taken from php.net/shuffle user notes
// Shuffles an array order for the sake of foreach while maintaining
// key => value associations
function shuffle_assoc(&$array) {
$keys = array_keys($array);
shuffle($keys);
foreach($keys as $key) {
$new[$key] = $array[$key];
}
return $new;
}
$i = 1000000; // How many tests to perform
// This is my rule list. Each key is a simple color
// and each value is a probability represented as a percent
$rules = array(
'black' => 20,
'white' => 10,
'red' => 40,
'green' => 5,
'blue' => 25,
);
// Initialize the scores array with all 0's
// The "outs" will be used when the probability does not
// occur in any of the rules
$scores = array('outs' => 0);
foreach($rules as $k => $v) {
$scores[$k] = 0;
}
$count = count($rules);
for($x = 0; $x < $i; $x++) {
$rules = shuffle_assoc($rules);
foreach($rules as $k => $probability) {
$rand = mt_rand(1,100);
//$probability = ??; I've tried applying many different operations here to "correct" the probability
if($rand > $probability) {
continue;
} else {
$scores[$k]++;
continue 2;
}
}
$scores['outs']++;
}
foreach($scores as $k => $v) {
echo "$k: " . (($v/$i)*100) . "% ($v/$i)\n";
}
?>
期待される出力(疑似)。パーセンテージはの値に対応していることに注意してください$rules
outs: less than 1% (.../1000000)
black: 20% (.../1000000)
white: 10% (.../1000000)
red: 40% (.../1000000)
green: 5% (.../1000000)
blue: 25% (.../1000000)
出力例:
outs: 30.7128% (307128/1000000)
black: 13.2114% (132114/1000000)
white: 6.3381% (63381/1000000)
red: 29.5247% (295247/1000000)
green: 3.1585% (31585/1000000)
blue: 17.0545% (170545/1000000)
私が試したことと考慮事項:
ご覧のとおり、ループ内にコメントアウトされたセクションが
$probability = ??
あり、各要素内で使用する実際の確率を計算するさまざまなわかりやすい方法を試しました。これには、$count
(ルールの数)で遊ぶことも含まれます。そのため、変数が存在し、使用されていません。明らかに正確である必要はありませんが、より少ない数のセット(1,000回の反復など)で安定した結果が得られることが望ましいです。
かなりあいまいになる可能性があります。+/- 5%の分散は、特に反復回数が少ない場合は、私の気持ちを損なうことはありません。ここでは、大きな数の理論が機能するようになることを理解しています。
アウトの数は、1%〜2%未満であれば、大した問題ではありません。また、さまざまな方法を使用してアウトを排除して、アウトだけが歪んでいるかどうかを確認しました。興味深いことに、これを行ったときに、20%の分割が発生しました。
$rules
さらに、「アウト」では、 100から始まる確率「数値」(つまり、の値)を基本的にブルートフォースすることで、アウトがほとんどなく、適切な分割にかなり近づくことができましたが、できませんでした。正確で最適な方法を見つけるために。毎回、ある色の結果に近づき、小さいながらも目立つスケールで他の色を歪めます。これらの数値には把握しやすい相関関係はなく、一見ランダムに見えましたが、結果が確率と大きな数値でうまく機能したことは明らかです。
これを計算する正確な方法があることを教えてください。それは私を狂わせています。
編集:ループが始まる前に確率のパーセンテージを知る必要なしに、そして追加またはネストされたループ(私が特に必要としたものです、私はその部分ではもっと直接的にすべきだと思います)..ある意味では、各反復は、その特定の反復のプロパティに基づいて動的に確率を引き出すことができます..ここでのすべての答えは非常に貴重でした、これが最終的なコードの私のバージョンです: http: //pastebin.com/eB3TVP1E