Saturday, 4 October 2008
Not More Yahtzee Maths
The route to my conclusion was far more tortuous that I will outline here. I used about 100 sheets of paper proving what could be written down in only a few lines. So I will now present the shortcut solution... But first the question..... Oh Guru Tim please can you provide me with a formula to give me the probability of getting a specific 5-of-a-kind, 4-of-a-kind, 3-of-a-kind and so on when playing Yahtzee.
Throwing One Dice Three Times
To answer the question we need to realize that you need three attempts (see www.yahtzee.org.uk for the rules). So lets start there, and only consider throwing one dice... regular dice p=1/6 (successful throw) q=5/6 (unsuccessful throw)
1st Attempt, success p, failure q
2nd Attempt, success qp, failure q2
3rd Attempt, success q2p, failure q3
So adding this up p + pq + pq2 + q3 ==> p(1+q+q2) + q3 which is == 1
And
Extending this further for n throws 1 = p(1+q+q2+ .. +q(n-1)) + qn
The first thing to note is that is not normally how one would write it. Normally one would expect a binomial expansion e.g.
(p+q)3 = p3+3pq2+3p2q+q3 == 1
However, the way in which we progress is different. The binomial expansion means that you would throw the dice 3 times no matter what you got, hence there is an option for throwing 3 correct dice in a row. So what the new expansion does for us is to allow us to stop throwing when the target is reached. The expansion is no less valid than the binomial, but it simply describes a different set of mechanics.
Throwing Five Dice Three times
OK Now we have a simple expression for throwing 1 dice three times, lets use five dice, and have 3 attempts. We are now armed with a new set of formula which is expressed like so
Probability of getting target number P = p(1+q+q2)
Probability of failing to get Target number Q = q3
Now remember that P+Q = 1 (and also p+q=1, p=1/6, q=5/6), Throwing the 5 dice with 3 attempts will yield a binomial expansion of (P+Q)5 = 1
So
Throwing 5-of-a-kind is P5 or p5(1+q+q2)5 or 1.33%
Throwing 4-of-a-kind is 5P4Q or 5p4(1+q+q2)4q3 or 9.12%
Throwing 3-of-a-kind is 10P3Q2 or 10p3(1+q+q2)3q6 or 25.04%
Throwing 2-of-a-kind is 10P2Q3 or 10p2(1+q+q2)2q9 or 34.40%
Throwing 1-of-a-Kind is 5PQ4 or 5p(1+q+q2)q12 or 23.63%
Throwing 0-of-a-kind is Q5 or q15 or 6.49%
The Long Way 'round
So taking a look at the above, one might say .. hey this is way too simple, I don't believe it. Well the as I said at the start I used up a small forest working the above through the long way round. If you wish to do it feel free. The long way round is to simply look at the binomial expansion for all the permutations (you can get a flavor from my previous posts), but remember that when you get the target number you stop. So look at the chances of getting 5 in one go (5M), then 5 in two goes, (4M:5M 3M:5M; 2M;5M; 1M:5M; 0M;5M), then in three goes (4M:4M;5M 3M:4M:5M 3M:3M:5M etc.... ) .. This will give you 5-of-a-kind, then repeat whole process for 4-of-a-Kind
etc... after a few forests and a couple of pencils you should end up with the above set of simple formulas.....
Time to go now, kids are suspiciously quiet...
Saturday, 26 January 2008
Double Maths (again!)
last time we left off with the result of getting a specific Yhatzee was p5 [1+q(1+q)]5 . Which I thought was a very neat (p=1/6, q=5/6). The next, and probably more realistic question is "what are the chances of throwing ANY Yahtzee". My first attempts were very much based on the previous attempts, and indeed I came up with a result of p4 [1+q(1+q)]4 . This However was wrong, this evaluates to 3.15%, when I did my test runs on it I came up with a value closer to 4.5%. My first thoughts were, the Java random algorithm was poor, but it did match the previous formulae for a specific Yahtzee, so I was wondering if my algorithm was wrong or I had a bug!!
After some further thought I realised that a potential for getting more Yahtzees was obvious.
- When you are going for a specific yahtzee and you have 0 1 or 2 matching numbers, you forge on...
- BUT if you need ANY old Yahtzee, then of you have 2 matching numbers, you are not tied to these. So lets say roll 1 gave you 2,2, 3,4,6 You hold the twos, roll again ... now there is a chance that you then roll a full house say 2,2,5,5,5. At this point you abandon yahtzees in 2's and go for the more fruitful 5's. And this is what my Yahtzee algorithm will do. Hence the extra Yahtzees.
So I perseveered. The eventual formula was derrived is a very similar way to previous with inspiration from the above paper. I'll not do all the maths but, here is a summary
5M (Yahtzee) --> 6/7776 == 6.p5
4M (4-of-a-kind) --> 150/7776 == 6.5.p4q
3M (3-of-a-kind) --> 1500/7776 == 6.10.10p3q2
2M(a pair) --> 5400/7776 == 6.Q.p2
0M(nothing) --> 720/7776 == 6.R.p
so p = 1/6, q=5/6, Q is a fudge and is 5400/1296 R is also a fudge and is 720/7776
1st Attempt
This is simple, roll a Yahtzee probability is 6.p5
- 5M --> 6.p5
2nd Attempt
A few more combinations here
- 4M:5M --> 6.5.p4q . p
- 3M:5M --> 6.10.10p3q2 . p2
- 2M:5M --> 6.Qp2 .p3
- 0M:5M --> 6.p5
6p5(1 + 5q + 10q2 + Q + R), or 1.26%
4 of a kind, 4 of a kind, then yahtzee ..
- 4M:4M:5M --> 6.5p4q . q . p
- 3M:4M:5M --> 10.6.p3q2 . 2pq . p
- 3M:3M:5M --> 10.6.p3q2 . q2 . p2
- 2M:4M:5M --> 6Qp2 . 3p2q . p
- 2M:3M:5M --> 6Qp2 . 3pq2 . p2
- 2M:2M:5M --> 6Qp2 . q3 . p3
- 2M:2N:5N --> 6Qp2 . 5p3 . p2
- 0M:0-4M:5M --> 6Rp . 6P5(5q + 10q2 + Q + R)
6p5{1+ (5q + 10q2 + Q + R)(1+6Rp) + 5q2 + 10q2[(1+q)2 – 1] + q[(1+q)3 -1] + 5Qp2}
Not so nice but is 4.610%, which is 3.47 times larger than a specific Yahtzee.If anyone has suggestions for substitutions for P & Q (preferably to fit in with the binomial expansions) that make the above simpler feel free to comment..
Tally ho, I'm going to be running 10,000,000 games tonight.
Wednesday, 23 January 2008
Some Mathematics and Yahtzee
Probability of getting a Yahtzee...
OK, quick recap of what a Yahtzee is. You roll 5 regular cubic dice, and if all the dice score are the same it is a Yahtzee (e.g. 5 dice each showing 1). That said, you don't have to do it on the first go. You can have up to 3 attempts, and you can roll as many dice you choose. So if you wanted a Yahtzee in 1s you might roll 1,2,1,4,5.. You can keep the two 1s and roll the remaining 3 dice.
So now look at some of the mathematics. Let
p = probability of rolling a specific number on one dice (1/6)
q = the probability of not throwing the specific number (1-p) or (5/6)
I'm using p & q as it is easier than writing 1/6 and 5/6 each time. Additionally, there are some arithmetic simplifications that are easier to deal with using algebra, rather than hard numbers.
Some fundamental probability combinations. I will use these latter. Rolling 5,4,3,2 or 1 dice gives the following binomial permutations
..............0M ......1M.....2M........3M......4M.......5M
(p+q)5 = q5 + 5pq4 + 10p2q3 + 10p3q2 + 5p4q+ p5 ... rolling all 5 dice
(p+q)4 = q4 + 4pq3 + 6p2q2 + 4p3q+ p4 ... rolling 4 dice
(p+q)3 = q3 + 3pq2 + 3p2q+ p3 ... rolling 3 dice
(p+q)2 = q2 + 2pq + q2 ... rolling 2 dice
(p+q)1 = q + p ... rolling just 1 dice
Note that each row adds to 1 (as p+q=1, and 1x = 1), this fact will be used (lots) later on.
The top row (5M, 4M etc) shows the number of matching dice rolled (so Yahtze is 5M, 4 of the same number is 4M, and so on). Each row corresponds to throwing 5 dice, 4 dice etc. These permutations will be used latter on, and it is assumed that the reader is familiar with the concept of binomial permutations... if not .. sorry no tutorial here
Also below I will use some short hand to denote the way the dice were rolled. So 1M:3M:5M represents 3 attempts, 1st attempt rolled 1 target number, the next attempt the remaining 4 dice were rolled and 3 target numbers (in total) were matched (or two new target numbers), and the last attempt gave a Yahtzee with 5 matching target numbers.
The last thing is that if you roll a target number, it is assumed you hold it, thus the following combination would not occur 4M:3M:5M, if you rolled 4 target numbers you would hold all four, so it would be impossible (stupid) to have less than 4 target numbers after the second roll.
1st Attempt
Only 1 permutation to get Yahtzee, roll 5 dice & get it, the probability is
5M is p5
2nd Attempt
There a few permutations here, you could roll 4,3,2,1 or 0 matching dice, then throw a Yahtzee from the remaining, the combinations are listed below along with the probabilities.
- 4M:5M is 5p4q . p
- 3M:5M is 10p3q2 . p2
- 2M:5M is 10p2q3 . p3
- 1M:5M is 5pq4 . p4
- 0M:5M is q5 . p5
Adding these up
p5 {5q + 10q2 + 10q3 + 5q4 + q5}
The expression within the { } brackets is (1+q)5 – 1, so this simplifies further to
p5 {(1+q)5 – 1}
3rd Attempt
There are lots of permutations here (as one might expect)
4M:4M:5M is 5p4q . q . p
==> p5{ 5q2 } ==>
p5 { 5q (( 1+q) -1)} (this complication will become apparent as the other terms are calculated)
- 3M:4M:5M is 10p3q2 . 2pq . p
- 3M:3M:5M is 10p3q2 . q2 . p2
So 3M:3-4M:5M is the sum of the above
==> p5{ 10q2 ( 2q + q2 ) } == > (note that 2q + q2 == (1+q)2 -1, hence the above complication!)
p5 { 10q2 ((1+q)2 -1) }
- 2M:4M:5M is 10p2q3 . 3p2q . p
- 2M:3M:5M is 10p2q3 . 3pq2 . p2
- 2M:2M:5M is 10p2q3 . q3 . p3
So 2M:2-4M:5M is the sum of the above
==> p5{ 10q3( 3q + 3q2 + q3 ) } == > (again note 3q+3q2+q3=(1+q)3-1)
p5 { 10q3((1+q)3 -1) }
- 1M:4M:5M is 5pq4 . 4p3q . p
- 1M:3M:5M is 5pq4 . 6p2q2 . p2
- 1M:2M:5M is 5pq4 . 4pq3 . p3
- 1M:1M:5M is 5pq4 . q4 . p4
So 1M:1-4M:5M is the sum of the above
==> p5{ 5q4( 4q + 6q2 + 4q3 + q4) } == > (you should be getting the idea now..)
p5 { 5q4((1+q)4 -1) }
- 0M:4M:5M is q5 . 5p4q . p
- 0M:3M:5M is q5 . 10p3q2 . p2
- 0M:2M:5M is q5 . 10p2q3 . p3
- 0M:1M:5M is q5 . 5pq4 . p4
- 0M:0M:5M is q5 . q5 . p5
So 0M:0-4M:5M is the sum of the above
==> p5{ q5( 5q + 10q2 + 10q3 + 5q4 + q5) } == >
p5 { q5((1+q)5 -1) }
The 3rd attempt can now be summed up and reduced (if that is the word!!) to
p5 { 5q(1+q) + 10q2(1+q)2 + 10q3(1+q)3 + 5q4(1+q)4 + q5(1+q)5 – [(1+q)5 -1]}
Adding it All Up
Adding together the 3 terms for 1st attempt, 2nd attempt and 3rd attempt
- 5M is p5
- 1-4M:5M is p5 {(1+q)5 – 1}
- 1-4M:1-4M:5M is p5 { 5q(1+q) + 10q2(1+q)2 + 10q3(1+q)3 + 5q4(1+q)4 + q5(1+q)5 – [(1+q)5 -1]}
This simplifies as the bit in [...] cancels with 2nd attempt expression, to
p5 { 1 + 5q(1+q) + 10q2(1+q)2 + 10q3(1+q)3 + 5q4(1+q)4 + q5(1+q)5}
Replacing q(1+q) with x gives
p5 {1 + 5x + 10x2 + 10x3 + 5x4 + x5}
The bit in the { } is a simple expansion of (1+x)5 becomes
p5 (1 + x)5
Now as the above is a very simple expression (considering where we started), and back substituting x=q(1+q) gives the final result
Of probability of getting a specific Yahtzee in 3 attempts is
p5 [1+q(1+q)]5
Putting in some numbers the result is 915/615 or 0.01327. So to get any Yahtzee is 6 times this or
915/614, or 0.0796, or just under 8%. This is much larger than I had originally thought.
As each game has 13 sets, then one would expect to see 0.66 Yahtzees per game.
Max Score YahtzeeThe maximum score yopu can get in Yahtzee is 1575, and means not only you get 13 Yahtzees in a row, but you some are specific Yhatzees. Doing some more maths the first two yahtzees can be any type of yahtzee, then you have 8 specific Yahtzees and 3 any old yahtzees, this. So denoting p(ay) for any Yahtzee, and p(y) as a specific Yahtzee
p(ay).p(ay).[any order of 8 p(y), 3 p(ay)]
The way to arrange 11 things with 8 and 3 is 11*10*9/3*2 ==> 165
also p(ay) = 3.47*p(y) (see next blog, Double Maths (again!) )
so
(3.47)2 p(y)2 . 165 . p(y)8 . (3.47)3p(y)3
orp(y)13.(3.47)5. 165
as above p(y) = 0.01327, doing some maths, if my computer can run 130 games per second, to have a relatively good chance of getting this I need to run the simulation for 7.4 billion years!Thursday, 13 December 2007
Lies, damn lies and measurements
OK lets move onto the where to measure the data. The answer is every where and any where it is produced. But specifically, lets look at unit and module tests. Unit tests are generally run very regularly, many times a day (especially for XP developments). One may use unit tests as profiling and run the occasional test looking for which unit tests take the longest. But there is more information to be gleaned from them... if you care to log it .. imagine a database being populated in the following manner
- Test suite resources utilisation: Contiguously (well every 5 minutes) on the test suite, the CPU, memory, network, disk utilisation of all the systems was also logged and the results automatically loaded into a database
- Test results: If when every unit tests were run, the result was automatically uploaded to a database with, date, time, package, build no, time taken to run each test and number of times or loops in the test
- Test suite configuration: On a weekly basis the test suite uploaded it's configuration, CPU type & speed, total memory, OS and version, patches, java/c/c++/c# version, number of disks and so on
- Firstly we can track how each test is performing over time, from it's first run 'till now
- Secondly we can spot any step changes (either up or down) in the way a single test is performing
- Lastly, we could pick some specific tests and use these are our KPI, a standard unit of performance, that future versions of the code can be compared to. This could be simple or a string of system states
- Correlate software measurements such as throughput, latency with resource utilisation, CPU, disk IO etc.
- look at resource utilisation over time.
So how would all this work on a day-to-day basis.
Bedding in: After an initial period of development of the infrastructure and tools, data would be collected. At first it will seem complicated, and far too much detail.
gaining acceptance: Then after a while, the general data patterns will be recognisable, and some general rules of thumb may develop (e.g. each unit test adds about 1-2ms to total test time, each unit test generates 20 IO, 15 read, 5 write and so on).
acceptance: Then deeper patterns will start to emerge. What will also become apparent is when things start to differ. If a new unit test (note new, not existing) takes more than 5ms, look carefully. Or what about a unit test that used to take 1ms to run is now consistently taking 3 ms to run. Once these features are being spotted, the performance of the system is far more quantitative, and far less subjective.
predictive: When the results are being used as engineering data. Performance of module x (as determined by one or more unit test results) is degrading. It will become a bottleneck. redesign activity required. Or even, a better disk subsystem would improve the performance of the tests by 2/3 and mean the unit tests run 1 minute faster.
historical: imagine being able to give quantitative answers to questions like "Architecture have decided to re-arrange the system layout like so (insert diagram here), what will be the effect of this layout compared to the current?". Unusually it would require re-coding the system under the various architectures and performing tests, but all that is now required is to understand the average effects of each of the components, and a good engineering estimate can be arrived at. Taking this a step further imagine "The system's performance indicates that the following architecture would be best like so (insert diagram here), and we/I believe that it would allow 20% more throughput".
Taking stock... Once upon a time tests were done infrequently, but it was realised that testing is the only sure fire way of ensuring features remain stable and bug free. The reduction of the time from bug introduction to bug detection is crucial. Why stop at bugs? Why not use the same approach to performance? When is it easiest to change the software architecture? at the beginning, when is it hardest, at the end? Why change software architecture, there are many reasons, but performance is one.
Lastly the quantification of the software performance is a key feature, because this is the only way to truly make engineering decisions. Developing software is full of contradictions and pro's and cons, it is only be quantifying them that you can confidently take the decisions .
Thursday, 6 December 2007
How do you measure the good?
Having read "Zen and the art of motor cycle maintenance" [and "Zen and the art of archery"] I'm of the opinion that you cannot easily measure or quantify good (or quality, or excellence, or angles). But we all seem to know what is good when we see it. That.. TV program is good, that dinner is good. That film is good. When you push someone to explain WHY it was so good, you get rather less than quantifiable answers it made it made me laugh, it was tasty, I enjoyed it. In essence not very objective quantities, but certainly positive subjective comments.
This spin on quality ( .. as more than eloquently expressed in Zen & bikes book above) is not new. But it was not until a recent project that I realised the reason you can't quantify how good something is is because you can't count the number of good points. .... BUT you can count the bad points, moreover, you can count specific bad points. Say number of spelling mistakes in a text, and add this to number of words and bingo you have a spelling error rate (e.g. 1 spelling mistake per 100 words or 5 spelling mistakes in the 500 word article).
So let us assume that we want to measure the quality of a text and decide to count number of spelling mistakes, the number of grammatical errors. Lets say we now have an article which scores zero on those counts .. does that make it a high quality article? Does it make the article inherently good? Interesting? compulsive reading? The answer to that is obviously no. But then again these are characteristics of high quality writing. That said, if an article is well written with respect to grammar and spelling it obviously means that the author has taken more than a passing interest in the subject, and so has a fair chance of grabbing your attention.
If we move onto code quality.. told you this was related to Java. I know I'm on a loosing footing if I talk about code quality, so I'm going to change the rules (sign of a cheat!!). For the sake of argument I will not call it "code quality" I will call it "code QQnty". QQnty is like quality, but is a lot more quantifiable. QQnty will have a value, or set of values that you can point at and measure. You can take someones product and say it has a QQnity of X and someone else's product and say it is X+1. To judge if a piece of code is quality code is far too subjective, rather you will need to measure its QQnity. What you want to measure the QQnity against is an open question, but none-the-less, once defined the QQnity of that code will be a measurable number. The reason for this is that judging code quality is far harder than judging the quality of a piece of writing, or how good a film was. The reason for this is two fold
- Code developers are a mixed bunch of people, and the chances of any two of them agreeing on any subject, trivial or not, are about as slim as winning the lottery. It does happen, to someone, but I've never witnessed it first hand
- Code developers are generally quite passionate about their art (science). Anyone who may have even the slightest difference of opinion from themselves is a heretic. Heretics must die, or at least be argued with.
Well that is at least the theory, when you think a bit harder about it QQnity will itself become a subjective measure as different people will put different models together to measure what they want. What is interesting (to me anyway), it is extremely difficult to measure the good in a piece of code, but much easier to count bad points...
- number of bugs (# bugs).. this is certainly a quantifiable point, how bad each bug is may or may not be quantifiable, but each bug counts as one.
- number of functional points achieved/failed (FPA/FPF). it is more usual to use the failed version as there are fewer to count. Again, how important each functional point is is subjective, but you can count it
- number of lines of code (LOC). This is very misleading. A large code base may mean that the code is highly complex, but it also probably means it is inflexible, or difficult to maintain. Similarly it could be lots of lines of junk. However, a measure none the less.
- number of passed/failed tests (# PT/ # FT). Again the negative is more common than the positive
QQnty = total FP/LOC
This measure means that if you succeed in producing the total functional points in fewer LOC, then you do better!! This may lead to more code re-use (should not impact LOC), simpler code (one hopes)
Or
QQnty = total tests/LOC
This way the programmer can either increase total tests, or reduce LOC, either way both would likely (but no certainty) improve quality
However, watch out for .. QQnty = # bugs/LOC
This way the only way to improve (well reduce) QQnty is to increase LOC
This is the end of my splurge, now you've reached the bottom of this text... you can go to bed/work/school satisfied you completed one task today (but how good it is is subjective, but it still counts as one!!)
Monday, 5 November 2007
The Journey ... caught in a trap
One of the driving forces behind doing this was to see if the computer would be able to answer this question for me. I did tentatively try a pen and paper analytical approach. A small tip for anyone who would like to pursue this further than I was able to. If you come quickly at the problem from behind, you can distract it with the pen and bash it with the paper, this is why it is advisable to have lots of paper for these types of problems, a hefty weight of paper can stun or even knock out problems of this sort. But be warned, problems have a habit of striking back!!
Back to the analysis stuff.
- Should you be aggressive from the start? If you have 2x6 and 2x1 and a 3 is it better to be optimistic and hold the 6s or play defensively and go for the 1s?
- Is it ever right to give up on attempt and not hold anything, and just re-roll all 5 dice?
- If a game is going badly is it worth logging a poor score in Yahtzee, as you are unluckily to get a Yahtzee anyway, and logging it in another slot will mean you will loose the chance of achieving that score.
- If you do stick to never filling the Yahtzee with a non-Yahtzee roll, when logging the score in a less than optimal pattern, do you log it in the highest scoring (least likely) slot (say large straight) or in a low scoring slot (say 1s) where you might be able to make up for the difference latter in the game.
So my basic questions about Yahtzee were strategy based. My attempt to write a genetic algorithm to solve the above has been listed in earlier blogs. The fundamental thing is... the methods I've used (up to now), will not be any use in answering the questions!!! Why, because
- My maps/genes to play the game took no account of the number of rolls one was on. This means you cannot re-roll (otherwise you will end up in an infinite loop, and never finish the game)
- If you make no differentiation between the first and third roll you cannot truly say you are throwing away points, as you may be on the first roll being optimistic (e.g. 2x6 and you hold the 6s going for 3x6s, or 4x6s or 5x6s, where as logging 2x6s against 6s is a different matter).
- It was a gross over simplification to only have one map/gene for the game. (but it sort of worked!!)
- Using a genetic algorithm to search a 20x18 space is a large problem, in the order of 20x18! (that contains lots of zeros). Now I had triplied this space. It took a long time to previously, now it will take even longer
- The code I had written was expressly written with the assumption that there was only one map... I have to unpick the code to accommodate the new maps. This is proof that my java design was poor.. (I can at least say I'm a beginner at Java ... but it is a fair criticism)
This is my trap. can I re-write the code plus unit tests to reliable re-structure (re-factor) my code? Or should I continue on my current path with less than perfect maps/genes (in that they do not have a "roll again" genome/instruction).
Well that is Tim inTheBlogOSphere signing out. Boldly going nowhere fast, but finding all train to nowhere are delayed or cancelled.
Saturday, 3 November 2007
The Journey Continues .. to Darwin and beyond
- Not enough games being played, so actual game statistics are too unreliable. In other words you can't tell the difference between lucky games and good maps (genes).
- Not enough generations.. well I suppose we took millions of years to evolve
- Not enough mixing of the maps (genes)
- Expectations too high. I was rather hoping that this approach would yield a good set of results. In fact I was half expecting someone to say .. of course this sequence is correct because .. insert some mumbo jumbo here .. If you were to ask the same person before hand, you would get a very non committal reply. This is the difference between doers and thinkers. Sometimes doers think and do, where as thinkers just think, and usually of reasons of why inaction is the best course of action (or is it inaction).
- My generation breeding technique was unique, in his experience (translation, wrong!) the pruning was far too sever, usually 40%ish makes it through to next generation.
- Because of this I was probably only able to "hill climb" to a local maximum value.
- Select the best 40% (there were a couple of methods)
- Mutate 1% from the population
- breed 59% from randomly selecting parents from the population
This basically means, in Darwin terms, you can't be too selective. If you are, you risk only settling on a less than optimum values (breeds) as you end up not being able to cross the valley (because you throw results away that too far frpm where you are, your hill top). To put this in a different way, if you breed too selectively, it is likely that the resulting population will contain defects. Isn't this what dog breeders do!!! No wonder some animal activists are up in arms about breeding and selection. I did not realise!!! (OK.. this looks strange, I must have my geek hat on today. I don't believe people, when they say "selective breeding is bad", but am quite convinced by running an abstract computer simulation of a game of chance, and bingo I see the light.. hmmm. too much beer tonight)
Objective1: use above method to breed from a totally random generated game rules (see previous blog)..
Objective2: Use above method but with a seed of the best I have achieved.
My main problem is that these missions will eat severely into my free time. Kids need attention, wife needs compliments, work needs to be attended. Hey ho, who said this was going to be simple. When the results are in I'll publish a few more results...
result of objective2: I did some tests and it does look like things are getting better. I used a population of 101, each gene/map was given 100 games to prove their worth (probably too small, but 100 games takes about 1 second). I ran this for 20 generations. This takes 30 minutes or so to run. I then take the best map and run it for 100,000 games (get a really good statistical average), this takes about 15 minutes or so. This will really show what the map/genes are really made of. results for 100,000 games
max score 720, max number of Yahtzees 5, average score 218 top 1% score 477, bottom 1% 105. Average number of Yahtzees per game 0.48. The game logic takes 25% of the computers time and the response (interpreting the map/gene) takes 75% of the time.
Pretty good results. Lets take a look at how the system converged...
What you can see here is all the results per generation plotted at each generation. At generation 7 (gens 0-6 disappeared, never to be seen again.. probably a good explanation for this but I suspect a higher intelligence has whipped them from my computer files, they may appear in some remote desktop somewhere at some point ion the future... lets get back to the graph). Where was I oh yeah, generation 7 is essentially 3 groups of solutions, the top one around 215 average score, the next at 175, and the lowest at 90 ish. The lowest one disappears and becomes extinct by generation 12. No way for me to know if this generation X migrated to one of the two solutions or it simply became extinct. The next two remain until the last generation, but the 175 solution set thins out (like my hair). This leaves the biggest set. This set not only grows in size but also the best value increases to 235 ish. This is the map/genes I used for the 100,000 games run.The astute reader (that means you!!) will realise that the above set of runs topped out at 235 average score, but the 100,000 runs ended up at 218 average score. Well I'm putting this down to statistical variation.. The sceptical reader (at the back wearing the black tee shirt and very dirty shoes) may suggest poor Java programming or sloppy organisation. I must confess, that may be true as well, but I'm trying to put the kids to bed, chasing them with a tooth brush saying.. "brush your teeth to keep the tooth-decay gnome away" (evil uncle of the tooth fairy).. and do this.
More results as and when they come in... I might give up on objective 1... objective2 is more fruitful than I thought...
Boldly going where no sane Java programmer would dare admit.. Continually repeating "your mistakes will guide you a a safer harbour than fair winds and a good navigator would ever lead you"
Tim inTheBlogOSphere signing out.