Calculating the odds distribution using 6-sided dice

I am trying to calculate the distribution of the chances of changing the number of six-sided dice rolls. For example, 3d6 ranges from 3 to 18 as follows:

3:1, 4:3, 5:6, 6:10, 7:15, 8:21, 9:25, 10:27, 11:27, 12:25, 13:21, 14:15, 15:10, 16:6, 17:3, 18:1 

I wrote this php program to calculate it:

 function distributionCalc($numberDice,$sides=6) { for ( $i=0; $i<pow($sides,$numberDice); $i++) { $sum=0; for ($j=0; $j<$numberDice; $j++) { $sum+=(1+(floor($i/pow($sides,$j))) % $sides); } $distribution[$sum]++; } return $distribution; } 

Inside the $ j for-loop, the magic of the floor and module functions is used to create a sequence of counting the base-6 with the number of digits being the number of dice, so 3d6 will count as:

 111,112,113,114,115,116,121,122,123,124,125,126,131,etc. 

The function accepts the sum of each, so it will read: 3,4,5,6,7,8,4,5,6,7,8,9,5, etc. He pushes all 6 ^ 3 possible results and adds 1 to the corresponding slot in the $ distribution array between 3 and 18. Pretty simple. However, it only works until 8d6, after which I get server timeouts, because now it does billions of calculations.

But I do not think this is necessary, because the probability of probability follows the distribution of the sweet bell tower. I am wondering if there is a way to skip the crunch number and go straight to the curve itself. Is there a way to do this, for example, 80d6 (range: 80-480)? Is it possible to project a distribution without doing 6 ^ 80 calculations?

I am not a professional coder, and the probability for me is still new, so thanks for the help!

Stephen

+4
source share
4 answers

In PERL:

 #! my( $DieType, $NumDice, $Loaded ) = @ARGV; my $subname = "D" . $DieType . ( ( $Loaded eq "Loaded" ) ? "Loaded" : "Normal" ); my $Prob = \&$subname; my $width = 12; my $precision = $width - 2; printf "%5s %-${width}s \n", "Pip:", "Frequency:"; for ( my $j = $NumDice; $j <= $DieType * $NumDice ; $j++ ) { printf "%5d %${width}.${precision}f \n", $j, Frequency( $DieType, $NumDice, $j ); } sub D6Normal { my $retval = 1/6; } sub D6Loaded { my $retval = 1/6; CASE: for ($_[0]) { /1/ && do { $retval -= 0.02/6; last CASE; }; /2..5/ && do { $retval += 0.0025/6; last CASE; }; /6/ && do { $retval += 0.01/6; last CASE; }; } return $retval; } sub D8Normal { my $retval = 1/8; } sub D10Normal { my $retval = 1/10; } sub D10Loaded { my $retval = 1/10; CASE: for ($_[0]) { /1..8/ && do { last CASE; }; /9/ && do { $retval -= 0.01/10; last CASE; }; /10/ && do { $retval += 0.01/10; last CASE; }; } return $retval; } sub D12Normal { my $retval = 1/12; } sub D20Normal { my $retval = 1/20; } sub D32Normal { my $retval = 1/32; } sub D100Normal { my $retval = 1/100; } sub Frequency { my( $DieType, $NumberofDice, $PipCount ) = @_; if ( ( $PipCount > ($DieType * $NumberofDice) ) || ( $PipCount < $NumberofDice ) ) { return 0; } if ( ! exists $Freq{$NumberofDice}{$PipCount} ) { if ( $NumberofDice > 1 ) { for ( my $i = max( 1, $PipCount - $DieType ); $i <= min( $DieType * ($NumberofDice - 1), $PipCount - 1 ); $i++ ) { $Freq{$NumberofDice}{$PipCount} += &$Prob( $PipCount - $i ) * Frequency( $DieType, $NumberofDice - 1, $i ); } } else { $Freq{$NumberofDice}{$PipCount} = &$Prob( $PipCount ); } } return $Freq{$NumberofDice}{$PipCount}; } sub max { my $max = shift(@_); foreach my $arg (@_) { $max = $arg if $max < $arg; } return $max; } sub min { my $min = shift(@_); foreach my $arg (@_) { $min = $arg if $min > $arg; } return $min; } 
+3
source

Are you looking for binomial distribution

+1
source

Ok, let's start by rolling just one die. We know that the average is 3.5. We can also calculate the variance,

sum(p(x) * (x - M)^2) , where M is the average value, x is the result of the bone, and p is the probability of the result in the bone.

Using this formula, the dispersion of a single roll of bone is 35/12 = 1/6 * ((- 2.5) ^ 2 + (-1.5) ^ 2 + (-0.5) ^ 2 + 0.5 ^ 2 + 1.5 ^ 2 + 2.5 ^ 2)

It is also a fact that for several independent samples from the same distribution, their variance is added. So, if you roll N cubes, you should get a new distribution with an average of 3.5 * N and a dispersion of 35 * N / 12.

Thus, if you create a normal distribution with an average value of 3.5 * N and a dispersion of 35 * N / 12, it would be pretty good if you assume that you are rolling a decent amount of dice.

+1
source

I am wondering if there is a way to skip the crunch number and go straight to the curve itself. Is there a way to do this, for example, 80d6 (range: 80-480)? Is it possible to project a distribution without doing 6 ^ 80 calculations?

Yes. The probability function of the sum of independent variables is the convolution of the probability function of each variable.

The convolution in this case is just a special summation. (In a more general sense, convolution is an integral.) Let p and q be two discrete probability functions. Convolution is usually indicated by an asterisk.

 (p * q)[i] = sum_{j=1}^(n_p) p[j] q[i - j + 1] 

where I change from 1 to (n_p + n_q - 1), and n_p is the number of elements p and n_q is the number of elements q. If (i - j + 1) is less than 1 or greater than n_q, then q [i - j + 1] is equal to zero (therefore, these terms simply disappear from the summation).

In this case, you have p = q = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6], n_p = n_q = 6. The distribution of the sum of 3 rolls is (p * p * p). The distribution of the sum of 80 rolls is (p * p * p * ... (another 76 p) ... * p).

I do not know PHP, so I wrote a small program in Maxima .

 discrete_conv (p, q) := makelist (discrete_conv1 (p, q, i), i, 1, length (p) + length (q) - 1); discrete_conv1 (p, q, i) := sum (p [j] * foo (q, i - j + 1), j, 1, length (p)); foo (a, i) := if 1 <= i and i <= length (a) then a [i] else 0; r : [1/6, 1/6, 1/6, 1/6, 1/6, 1/6]; discrete_conv (r, discrete_conv (r, r)); => [1/216,1/72,1/36,5/108,5/72,7/72,25/216,1/8,1/8,25/216,7/72, 5/72,5/108,1/36,1/72,1/216] 

If you keep repeating discrete_conv, you should find that the numbers are becoming more and more like a normal distribution. This is an illustration of the central limit theorem.

It is possible that I made a mistake with indexing, so you will want to check this out. Hope this sheds light on the problem.

0
source

Source: https://habr.com/ru/post/1307568/


All Articles