Вероятность — Как смоделировать бросок костей несколько раз, используя Переполнение стека

Я хочу смоделировать бросок двух шестигранных кубиков X количество раз, используя PHP, чтобы увидеть, как часто происходит каждая возможная комбинация (2, 3, 4, 5, 6, 7, 8, 9, 10, 11 или 12). Что было бы хорошей отправной точкой?

1

Решение

Вот полный PHP-скрипт, который будет симулировать бросок двух кубиков столько раз, сколько вы захотите, а затем отобразить промежуточные итоги результатов каждого броска:

<?php

/**
* If your machine is low on memory, try uncommenting the following line:
*/
//ini_set('memory_limit', '512M');

/**
* If you still don't have enough memory, reduce the value of $number_of_rolls
* Note: with memory_limit at 512M, the max number of times I can roll at a time
* is about 325000
*/
$number_of_rolls = 20000;
print dice_roll_output($number_of_rolls);

/**
* Array of 6 sides in a single die
*/
function die_render() {
$die = array(1 => 1, 2, 3, 4, 5, 6);
return $die;
}

/**
* Roll a single die
*/
function die_roll($die_sides) {
// First function (less random)
//$number_rolled = array_rand($die_sides);

// Second function (more random)
$number_rolled = mt_rand(1, count($die_sides));

return $number_rolled;
}

/**
* Roll both dice
*/
function dice_roll() {
// Create the first die
$die1 = die_render();
// Create the second die
$die2 = die_render();
// Roll the first die
$die_roll_1 = die_roll($die1);
// Roll the second die
$die_roll_2 = die_roll($die2);
// Add the two rolls up to get the total
$total = $die_roll_1 + $die_roll_2;
// Return the first die, second die, and the total of the two
return array($die_roll_1, $die_roll_2, $total);
}

/**
* Much of this function is not necessary unless the
* area toward the bottom is un-commented out.
*/
function dice_roll_output($numrolls) {
$numrolls = (int) $numrolls;
// Abort if $numrolls is less than 1
if ($numrolls < 1) {
return 'Number of rolls must be greater than zero';
}
$rolled_arr = array();
$die1 = array();
$die2 = array();
$dice_sum = array();
for ($i = 0; $i < $numrolls; $i++) {
$dice_roll[$i] = dice_roll();
$die1[$i] = $dice_roll[$i][0];
$die2[$i] = $dice_roll[$i][1];
$dice_sum[$i] = $dice_roll[$i][2];
$rolled_arr[$i] = array($die1[$i], $die2[$i], $dice_sum[$i]);
}
// How many times each total (somewhere between 2 and 12) was rolled
$frequencies = array_count_values($dice_sum);
// Sort the displayed output from high to low
arsort($frequencies);
// For later use with calculating percentages
$rolled_tot = array_sum($frequencies);
// Begin actual display -- line 1
$out = "<pre><b>Rolled\t\tFrequency\tPercent</b>\n";
// Double-checking to make sure all percentages add up to 100%
$freqency_total = 0;
foreach ($frequencies as $dice_roll => $frequency) {
// Don't round the numbers using number_format until after they've been used
// for double-checking
$percent_raw = ($frequency / $rolled_tot) * 100;
// Add to the running total of the double-checked percentage
$freqency_total += $percent_raw;
// Now we can round the numbers up to two decimal places
$percent_display = number_format($percent_raw, 2);
// More display -- should be 11 lines maximum (lines 2 through 12)
$out .= "{$dice_roll}\t\t{$frequency}\t\t{$percent_display}\n";
}
// Format the running total of the double-checked percentage (optional)
$freqency_total = number_format($freqency_total, 2);
// Aesthetic purposes only
$out .= "\t\t\t\t-----\n";
// Line 13 of the display
$out .= "\t\t\t\t{$freqency_total}%\n";

// The following is the above-referenced "area toward the bottom"// NB: displaying this part could cause a LOT of output to be displayed

/*
if (!empty($rolled_arr)) {
// Uncomment the next line if you want to sort the output
//array_multisort($dice_sum, SORT_DESC, $rolled_arr);

// Aesthetic purposes only
$out .= "---------------------------------------\n";
// Line 14 of the display
$out .= "<b>Die #1\t\tDie #2\t\tTotal</b>\n";
foreach ($rolled_arr as $key => $arr) {
// Lines 15 and up of the display -- quantity determined by $numrolls
$out .= "{$arr[0]}\t\t{$arr[1]}\t\t{$arr[2]}\n";
}
}
*/
// End actual display
$out .= "</pre>";
return $out;
}
0

Другие решения

Вот короткий сценарий с простыми комментариями о том, что делает что.

<?php

// this will be our final result
$combinations = array();

// for as many times as we want to run the experiment (1000 here)
for ($i = 0; $i < 1000; $i++) {
// mt_rand returns random whole number in the specified range
$die1roll = mt_rand(1, 6);
$die2roll = mt_rand(1, 6);

// add the sum of two dice
$sum = $die1roll + $die2roll;

// if this sum hasn't happened yet, mark it so - it's happened zero times
if (!isset($combinations[$sum])) $combinations[$sum] = 0;

// increase number of times this sum has happened
$combinations[$sum] += 1;
}

// order the results array by keys (sums) ascending
ksort($combinations);

// print it out
print_r($combinations);
0

По вопросам рекламы [email protected]