1. Gaussian Distribution Using Dice
- Posted by cklester <cklester at yahoo.com> Jul 30, 2004
- 496 views
What is the formula for calculating the odds of a number appearing from a set of dice? I'm wanting to plot some bell curve graphs of this. I have Googled and searched the forum/archive and nothing I can understand. -=ck "Programming in a state of EUPHORIA." http://www.cklester.com/euphoria/
2. Re: Gaussian Distribution Using Dice
- Posted by cklester <cklester at yahoo.com> Jul 30, 2004
- 480 views
This looks good, but, again, I don't understand the last math part... http://mathforum.org/library/drmath/view/52207.html I'd just like a FAST function like this: aNumber = 13 -- what's the odds of the sum of 13 sides = 6 -- appearing when 6-sided dice rolls = 4 -- are rolled 4 times and added together? xFromY = instances( aNumber, sides, rolls ) Right now, I'm using a recursive algorithm, as follows: -- start of code -- code generated by Win32Lib IDE v0.18.20 include Win32Lib.ew without warning -------------------------------------------------------------------------------- -- Window Window1 constant Window1 = createEx( Window, "Window1", 0, Default, Default, 357, 300, 0, 0 ) constant statBar = createEx( StatusBar, "StatusBar8", Window1, 0, 0, 0, 0, 0, 0 ) constant txt_Rolls = createEx( EditText, "3", Window1, 52, 12, 48, 20, 0, 0 ) constant txt_Faces = createEx( EditText, "6", Window1, 52, 36, 48, 20, 0, 0 ) constant LText4 = createEx( LText, "Faces", Window1, 12, 40, 40, 20, 0, 0 ) constant LText5 = createEx( LText, "Rolls", Window1, 12, 16, 36, 20, 0, 0 ) constant LText6 = createEx( LText, "Distribution", Window1, 12, 72, 68, 20, 0, 0 ) constant pix_Graph = createEx( Pixmap, "pix_Graph", Window1, 216, 8, 100, 28, 0, 0 ) sequence IDEFlags IDEFlags = classDefaults( Window, { {1, {WS_SYSMENU}},{2, {0}} } ) constant CWindow14 = createEx( Window, "CWindow14", Window1, 8, 92, 340, 160, or_all({WS_CHILD, WS_CLIPSIBLINGS, WS_BORDER}), 0 ) openWindow(CWindow14, Normal) moveZOrder( CWindow14, HWND_TOP) --------------------------------------------------------- -------------------------------------------------------------------------------- include xcontrols.ew include get.e object junk sequence rect, origin integer x, y, width, height, pixX, pixY constant GMID = xControl( Geometry, "", Window1, 0, 0, 0, 0, 0, 0 ), GMIDc = xControl( Geometry, "", CWindow14, 0, 0, 0, 0, 0, 0 ) manage( GMID, CWindow14, {0.0, 0}, {0, 90}, {1.0, 00}, {1.0 , 0} ) manage( GMIDc, pix_Graph, {0.0, 0}, {0.0, 0}, {1.0, 0.0}, {1.0 , 0.0} ) rect = getCtlSize(CWindow14) width = rect[1] height = rect[2] setCtlSize( pix_Graph, width, height ) setPenColor( pix_Graph, Black ) function sum(sequence s) integer result result = 0 for t=1 to length(s) do result += s[t] end for return result end function function increment(sequence face, integer which, integer max) face[which] += 1 if face[which] > max then if which > 1 then face[which] = 1 face = increment(face,which-1,max) end if end if return face end function function getMaxIndex(sequence s) atom result, max max = -999999 result = 0 for t=1 to length(s) do if s[t] > max then max = s[t] result = t end if end for return result end function function getMax(sequence s) atom max max = -999999 for t=1 to length(s) do if s[t] > max then max = s[t] end if end for return max end function procedure plotGraph() integer min, max, range, result, sides, rolls, toOne, thickness sequence faces, results, dice, plotBase, plotPoint atom scale rect = getCtlSize(CWindow14) width = rect[1] height = rect[2] origin = { 1 , height-1 } -- get values sides = getNumber(txt_Faces) rolls = getNumber(txt_Rolls) if sides > 0 and rolls > 0 and rolls <= 3 then min = rolls max = min * sides range = max - min + 1 toOne = rolls - 1 thickness = floor(width / range) -- plot graph dice = repeat(1,rolls) results = repeat(0,range) while dice[1] != ( sides + 1 ) do -- for 3d6, starts with {1,1,1} result = sum(dice) results[result-toOne]+=1 dice = increment(dice,rolls,sides) end while scale = height / getMax(results) --plot the results clearWindow(pix_Graph) clearWindow(CWindow14) for t=1 to length(results) do plotBase = origin + {(t-1) * thickness,0} plotPoint = origin + { plotBase[1]+thickness, floor(-results[t]*scale) } if t/2 = floor(t/2) then setPenColor(pix_Graph,Blue) else setPenColor(pix_Graph,Black) end if drawRectangle(pix_Graph,w32True,plotBase[1],plotBase[2],plotPoint[1],plotPoint[2]) copyBlt(CWindow14, 1, 1, pix_Graph ) end for setText(statBar, sprintf("%d,%d",origin)) end if end procedure -------------------------------------------------------------------------------- procedure Window1_onPaint (integer self, integer event, sequence params)--params is ( int x1, int y1, int x2, int y2 ) plotGraph() end procedure setHandler( Window1, w32HPaint, routine_id("Window1_onPaint")) -------------------------------------------------------------------------------- procedure Window1_onActivate (integer self, integer event, sequence params)--params is () plotGraph() end procedure setHandler( Window1, w32HActivate, routine_id("Window1_onActivate")) -------------------------------------------------------------------------------- procedure txt_Rolls_onChange (integer self, integer event, sequence params)--params is () plotGraph() end procedure setHandler( txt_Rolls, w32HChange, routine_id("txt_Rolls_onChange")) -------------------------------------------------------------------------------- procedure txt_Faces_onChange (integer self, integer event, sequence params)--params is () plotGraph() end procedure setHandler( txt_Faces, w32HChange, routine_id("txt_Faces_onChange")) -------------------------------------------------------------------------------- procedure CWindow14_onResize (integer self, integer event, sequence params)--params is ( int style, int cx, int cy ) plotGraph() end procedure setHandler( CWindow14, w32HResize, routine_id("CWindow14_onResize")) WinMain( Window1,Normal ) --end of code -=ck "Programming in a state of EUPHORIA." http://www.cklester.com/euphoria/
3. Re: Gaussian Distribution Using Dice
- Posted by Lewis Townsend <keroltarr at hotmail.com> Jul 31, 2004
- 470 views
ck, Here is my solution but it doesn't do any graffing. I think it is mathematically correct but it could be wrong. I just wrote it real quick. It prints up something that looks right to me.
include get.e function sum( sequence s ) atom a a = 0 for i = 1 to length( s ) do a+= s[i] end for return a end function constant NumOfDice = 3 constant NumOfSides = 6 constant MaximumRoll = NumOfDice * NumOfSides sequence chances, dice chances = repeat( 0, MaximumRoll ) dice = repeat( 1, NumOfDice ) integer roll for d = 1 to power( NumOfSides, NumOfDice ) do chances[sum(dice)] += 1 dice[1]+=1 for i = 1 to NumOfDice -1 do if dice[i] > NumOfSides then dice[i] = 1 dice[i+1] += 1 end if end for end for printf( 1, "The distobution of %d %d sided dice rolls:\n", {NumOfDice,NumOfSides} ) puts( 1, "Value\tChance\n" ) for i = 1 to length( chances ) do printf(1, "%d\t%d\n", i&chances[i] ) end for if wait_key() then end if
Below lies the signature of Lewis Townsend Lewy T
4. Re: Gaussian Distribution Using Dice
- Posted by cklester <cklester at yahoo.com> Jul 31, 2004
- 456 views
Lewis Townsend wrote: > > ck, > > Here is my solution but it doesn't do any graffing. > I think it is mathematically correct but it could be wrong. > I just wrote it real quick. It prints up something that > looks right to me. Well, it's a billion times faster than my recursive counting version. Zowie! Thanks LewyT! :) -=ck "Programming in a state of EUPHORIA." http://www.cklester.com/euphoria/
5. Re: Gaussian Distribution Using Dice
- Posted by "Juergen Luethje" <j.lue at gmx.de> Jul 31, 2004
- 660 views
cklester wrote: > This looks good, but, again, I don't understand the last math part... > > http://mathforum.org/library/drmath/view/52207.html This is not a Gaussian Distribution, BTW. A Gaussian Distribution is a continuous distribution, whereas this is a discrete distribution. However, the probabilities of sums on multiple dice *approach* a Gaussian distribution as the number of dice is increased. > I'd just like a FAST function like this: > > aNumber = 13 -- what's the odds of the sum of 13 > sides = 6 -- appearing when 6-sided dice > rolls = 4 -- are rolled 4 times and added together? > > xFromY = instances( aNumber, sides, rolls ) [big snip] On the URL mentioned above, the formula published 1937 by Uspensky is provided. The formula uses the Binomial Coefficient (named C() there), so we first need a function to calculate this. The Binomial Coefficient is of fundamental meaning for combinatorial calculations, so it's useful to have that function anyway.
global type nonnegative_int (object x) if integer(x) then return x >= 0 end if return 0 end type global type positive_int (object x) if integer(x) then return x > 0 end if return 0 end type global function binomial (integer n, nonnegative_int k) -- Binomial Coefficient ("n choose k"): -- Number of (unordered) subsets of k elements from a set of n elements. -- in : k: nonnegative integer -- n: integer >= k -- out: positive integer (not including 0) atom ret integer start if n < k then return -1 -- Illegal function call end if start = n - k if k > start then -- swap k,start (so k is max.=floor(n/2)) start = k k = n - k end if ret = 1 for i = 1 to k do start += 1 ret = ret*start/i end for return ret end function global function ways_to_roll_given_sum (positive_int x, positive_int n, integer s) -- in : x: number of sides of each die -- n: number of dice -- s: given sum -- out: number of different ways to roll given sum with given dice integer ret ret = 0 for k = 0 to floor((s-n)/x) do ret += power(-1,k) * binomial(n,k) * binomial(s-x*k-1,n-1) end for return ret end function -- Demo integer Sides, Dice, Sum, NumberOfWays atom Probability Sides = 6 Dice = 4 Sum = 13 NumberOfWays = ways_to_roll_given_sum(Sides,Dice,Sum) Probability = NumberOfWays / power(Sides,Dice) printf(1, "Number of ways(%d,%d,%d) = %d\n", {Sides,Dice,Sum,NumberOfWays}) printf(1, "Probability (%d,%d,%d) = %.2f\n", {Sides,Dice,Sum,Probability})
When you want to calculate the number of ways or probabilities for only a few cases, this code might be faster than the code provided by Lewis. Please check yourself. Regards, Juergen
6. Re: Gaussian Distribution Using Dice
- Posted by cklester <cklester at yahoo.com> Jul 31, 2004
- 558 views
Juergen Luethje wrote: > > cklester wrote: > > > This looks good, but, again, I don't understand the last math part... > > > > <a > > href="http://mathforum.org/library/drmath/view/52207.html">http://mathforum.org/library/drmath/view/52207.html</a> > > This is not a Gaussian Distribution, BTW. A Gaussian Distribution is a > continuous distribution, whereas this is a discrete distribution. I'm glad we have geniuses on hand in the Euforum! :) > However, the probabilities of sums on multiple dice *approach* a > Gaussian distribution as the number of dice is increased. Yeah, I knew that. :P > When you want to calculate the number of ways or probabilities for only > a few cases, this code might be faster than the code provided by Lewis. > Please check yourself. I haven't run any benchmarks on them yet, but your code works great! Thank you! -=ck "Programming in a state of EUPHORIA." http://www.cklester.com/euphoria/
7. Re: Gaussian Distribution Using Dice
- Posted by "Juergen Luethje" <j.lue at gmx.de> Jul 31, 2004
- 489 views
Just 2 small comments (see below). Lewis Townsend wrote: > ck, > > Here is my solution but it doesn't do any graffing. > I think it is mathematically correct but it could be wrong. > I just wrote it real quick. It prints up something that > looks right to me. > > }}} <eucode> > include get.e > > function sum( sequence s ) > atom a > a = 0 > for i = 1 to length( s ) do > a+= s[i] > end for > return a > end function > > constant NumOfDice = 3 > constant NumOfSides = 6 > > constant MaximumRoll = NumOfDice * NumOfSides > > sequence chances, dice > chances = repeat( 0, MaximumRoll ) > dice = repeat( 1, NumOfDice ) > > integer roll Local variable roll is not used. > for d = 1 to power( NumOfSides, NumOfDice ) do > chances[sum(dice)] += 1 > dice[1]+=1 > for i = 1 to NumOfDice -1 do > if dice[i] > NumOfSides then > dice[i] = 1 > dice[i+1] += 1 -- this makes it faster: else exit > end if > end for > end for > > > printf( 1, "The distobution of %d %d sided dice rolls:\n", > {NumOfDice,NumOfSides} ) > puts( 1, "Value\tChance\n" ) > for i = 1 to length( chances ) do > printf(1, "%d\t%d\n", i&chances[i] ) > end for > if wait_key() then end if > </eucode> {{{ Regards, Juergen
8. Re: Gaussian Distribution Using Dice
- Posted by Lewis Townsend <keroltarr at hotmail.com> Aug 01, 2004
- 503 views
Juergen Luethje wrote: > > Just 2 small comments (see below). > > Lewis Townsend wrote: > > > ck, > > > > Here is my solution but it doesn't do any graffing. > > I think it is mathematically correct but it could be wrong. > > I just wrote it real quick. It prints up something that > > looks right to me. > > > <font color="#330033">> </font> > <font color="#330033">> </font><font color="#0000FF">include </font><font > color="#330033">get.e</font> > <font color="#330033">></font> > <font color="#330033">> </font><font color="#0000FF">function </font><font > color="#330033">sum( </font><font color="#FF00FF">sequence </font><font > color="#330033">s )</font> > <font color="#330033">> </font><font color="#FF00FF">atom </font><font > color="#330033">a</font> > <font color="#330033">> a = 0</font> > <font color="#330033">> </font><font color="#0000FF">for </font><font > color="#330033">i = 1 </font><font color="#0000FF">to </font><font > color="#FF00FF">length</font><font color="#330033">( s ) </font><font > color="#0000FF">do</font> > <font color="#330033">> a+= s[i]</font> > <font color="#330033">> </font><font color="#0000FF">end for</font> > <font color="#330033">> </font><font color="#0000FF">return </font><font > color="#330033">a</font> > <font color="#330033">> </font><font color="#0000FF">end function</font> > <font color="#330033">></font> > <font color="#330033">> </font><font color="#0000FF">constant </font><font > color="#330033">NumOfDice = 3</font> > <font color="#330033">> </font><font color="#0000FF">constant </font><font > color="#330033">NumOfSides = 6</font> > <font color="#330033">></font> > <font color="#330033">> </font><font color="#0000FF">constant </font><font > color="#330033">MaximumRoll = NumOfDice * NumOfSides</font> > <font color="#330033">></font> > <font color="#330033">> </font><font color="#FF00FF">sequence </font><font > color="#330033">chances, dice</font> > <font color="#330033">> chances = </font><font > color="#FF00FF">repeat</font><font color="#330033">( 0, MaximumRoll )</font> > <font color="#330033">> dice = </font><font color="#FF00FF">repeat</font><font > color="#330033">( 1, NumOfDice )</font> > <font color="#330033">></font> > <font color="#330033">> </font><font color="#FF00FF">integer </font><font > color="#330033">roll</font> > <font color="#330033"></font> > <font color="#330033">Local variable roll is </font><font color="#0000FF">not > </font><font color="#330033">used.</font> > <font color="#330033"></font> > <font color="#330033">> </font><font color="#0000FF">for </font><font > color="#330033">d = 1 </font><font color="#0000FF">to </font><font > color="#FF00FF">power</font><font color="#330033">( NumOfSides, NumOfDice ) > </font><font color="#0000FF">do</font> > <font color="#330033">> chances[sum</font><font color="#993333">(</font><font > color="#330033">dice</font><font color="#993333">)</font><font color="#330033">] > += 1</font> > <font color="#330033">> dice[1]+=1</font> > <font color="#330033">> </font><font color="#0000FF">for </font><font > color="#330033">i = 1 </font><font color="#0000FF">to </font><font > color="#330033">NumOfDice -1 </font><font color="#0000FF">do</font> > <font color="#330033">> </font><font color="#0000FF">if </font><font > color="#330033">dice[i] > NumOfSides </font><font color="#0000FF">then</font> > <font color="#330033">> dice[i] = 1</font> > <font color="#330033">> dice[i+1] += 1</font> > <font color="#330033"></font> > <font color="#FF0055"> -- this makes it faster:</font> > <font color="#0000FF"> else</font> > <font color="#0000FF"> exit</font> > <font color="#330033"></font> > <font color="#330033">> </font><font color="#0000FF">end if</font> > <font color="#330033">> </font><font color="#0000FF">end for</font> > <font color="#330033">> </font><font color="#0000FF">end for</font> > <font color="#330033">></font> > <font color="#330033">></font> > <font color="#330033">> </font><font color="#FF00FF">printf</font><font > color="#330033">( 1, </font><font color="#00A033">"The distobution of %d %d sided > dice rolls:\n"</font><font color="#330033">, </font><font > color="#993333">{</font><font color="#330033">NumOfDice,NumOfSides</font><font > color="#993333">} </font><font color="#330033">)</font> > <font color="#330033">> </font><font color="#FF00FF">puts</font><font > color="#330033">( 1, </font><font color="#00A033">"Value\tChance\n" </font><font > color="#330033">)</font> > <font color="#330033">> </font><font color="#0000FF">for </font><font > color="#330033">i = 1 </font><font color="#0000FF">to </font><font > color="#FF00FF">length</font><font color="#330033">( chances ) </font><font > color="#0000FF">do</font> > <font color="#330033">> </font><font color="#FF00FF">printf</font><font > color="#330033">(1, </font><font color="#00A033">"%d\t%d\n"</font><font > color="#330033">, i&chances</font><font color="#993333">[</font><font > color="#330033">i</font><font color="#993333">] </font><font > color="#330033">)</font> > <font color="#330033">> </font><font color="#0000FF">end for</font> > <font color="#330033">> </font><font color="#0000FF">if </font><font > color="#330033">wait_key() </font><font color="#0000FF">then end if</font> > <font color="#330033">> </font> > > Regards, > Juergen > > Oh yeah, that roll integer don't need to be there. I started to use it then decided I needed the dice sequence instead. Thanks for speeding it up with that exit statement. I forget about stuff like that sometimes. Below lies the signature of Lewis Townsend Lewy T
9. Re: Gaussian Distribution Using Dice
- Posted by Juergen Luethje <j.lue at gmx.de> Aug 03, 2004
- 486 views
cklester wrote: > Juergen Luethje wrote: >> >> cklester wrote: >> >>> This looks good, but, again, I don't understand the last math part... >>> >>> http://mathforum.org/library/drmath/view/52207.html >> >> This is not a Gaussian Distribution, BTW. A Gaussian Distribution is a >> continuous distribution, whereas this is a discrete distribution. > > I'm glad we have geniuses on hand in the Euforum! :) Me too. But that has nothing got to do with the difference between continuous and discrete probability distributions. This difference is explained in any statistical textbook on, say, page 23. >> However, the probabilities of sums on multiple dice *approach* a >> Gaussian distribution as the number of dice is increased. > > Yeah, I knew that. :P So the only remaining mystery is: Who wrote "Gaussian Distribution" in the name of this thread. And why? >> When you want to calculate the number of ways or probabilities for only >> a few cases, this code might be faster than the code provided by Lewis. >> Please check yourself. > > I haven't run any benchmarks on them yet, but your code works great! > > Thank you! Regards, Juergen