Java Forum / General / August 2006
can this code be improved
Print Guy - 17 Aug 2006 00:53 GMT Hi all.
To most of you, what I have been working on is probably trivial and easy, but it's taken me the good part of a week working 2 or 3 hrs a day to finally figure out how to do what I needed to do. Here in Canada, we have a lottery called 6-49. You pick 6 numbers between 1 and 49. Those numbers are put on a ticket and there is a draw twice a week.
I wanted to come up with a statistically solid way to pick my numbers so I figured that if I were to pick 6 numbers 1,000,000 times and count the number of times each number is selected, the top six would be good numbers to bet on during the lottery.
With that being said, I thought I could write a Java program to do the job. It proved to be a bit more difficult than I thought it would be; the hardest part being ensuring that each of the 6 numbers were unique.
Here is my code. What I am hoping for is some constructive criticism which could help me to make the code more efficient.
(Normally I would not comment my code so much, but I wanted you to see what I was trying to accomplish)
package lotto;
import java.util.Arrays; import java.util.Date;
import java.util.Random;
public class Sample { public static void main(String args[]) { Date today=new Date(); System.out.println("Starting:" + today); // the original array of 6 numbers picked int [] list = new int[6]; // the new array containing unique numbers only int[] newList = new int[6]; int number = 0; // this array is used to count the number of occurances (1-49) int [] BigList = new int[50]; // initialize BigList for ( int x=0;x<=BigList.length-1;x++) BigList[x]=0; // do this whole thing a million times for (int y=1;y<=1000000;y++) { // initialize newList for (int t=0;t<=newList.length-1;t++) newList[t]=0; // put 6 random numbers into an array for ( int z=0;z<6;z++) { Random rand = new Random() ; number=rand.nextInt(49) + 1; list[z]=number; } int count=0; // what this loop does is check each member of "list" to see // if it's a duplicate. Copy the current element to the newList // if it's not a duplicate. boolean dupLocated=false; for ( int b=0;b<=list.length-1;b++) { int chkNum=list[b]; int temp = b; boolean found = false; for ( int a=0;a<=newList.length-1;a++) { if ( newList[a] == chkNum) { found=true; dupLocated=true; } } if ( ! found ) newList[temp]=chkNum; } // now that we have at least one duplicate, we need to replace // the zero space holder with a new random number. So // to do that, we select a random number and then check to see // if it is the array. If it isn't then stick in in the list otherwise, keep // selecting and checking until we can put it in (usually takes one or two // iterations if ( dupLocated ) { for (int x=0;x<=newList.length-1;x++) if ( newList[x] == 0 ) { boolean t=false; while ( !t ) { Random rand = new Random() ; int number1=rand.nextInt(49) + 1; int tt = 0; for (int r=0;r<=newList.length-1;r++) if ( newList[r] != 0 ) if ( newList[r] == number1 ) tt++; if ( tt == 0 ) { newList[x]=number1; t=true; } } } } // so now we have a list of 6 unique numbers. and we need to increment // the value in BigList that corresponds to each of the six numbers. for (int j=0;j<=list.length-1;j++) { int idx=list[j]; BigList[idx]++; }
} // now find the top six and create a new array called topSix int [] topSix = new int[6]; for (int count=0;count<=topSix.length-1;count++) { int lIndex=0; int largest=BigList[0]; // compare each element of BigList with each "other" element // of BigList (I created this algorithm on my own, or maybe I rememered // it from somewhere. for (int x=0;x<=BigList.length-1;x++) { for ( int y=x+1;y<=BigList.length-2;y++) if ( BigList[y] > largest ) { largest=BigList[y]; BigList[y]=0; lIndex=y; topSix[count]=lIndex; }
} } // now print out the list of topSix for (int i=0;i<=topSix.length-1;i++) System.out.println("Rank " + (i+1) + " number is " + topSix[i]); Date today2=new Date(); System.out.println("Ending:" + today2); } }
------------------------------------------------------------------------------ Sample output
Starting:Wed Aug 16 20:51:49 ADT 2006 Rank 1 number is 43 Rank 2 number is 48 Rank 3 number is 29 Rank 4 number is 30 Rank 5 number is 35 Rank 6 number is 46 Ending:Wed Aug 16 20:52:04 ADT 2006
15 seconds isn't too bad... but maybe it could be faster?
Andrew Thompson - 17 Aug 2006 01:05 GMT > Hi all. > [quoted text clipped - 9 lines] > the number of times each number is selected, the top six would be good > numbers to bet on during the lottery. I am no statistician, so this is more a question than a strategy, but woul it not be just as valid to have a Vector of 'number of values in lottery' and simply remove any number that comes up?
E.G. start with a vector of 49 elements, if '35' is first chosen, remove that element and choose randomly from the the remaining 48 elements.
> public class Sample { > public static void main(String args[]) { > Date today=new Date(); And please change 'tab's to a couple of spaces before posting, that line is this wide... Date today=new Date(); ..in my 'news client'.
Andrew T.
Print Guy - 17 Aug 2006 01:22 GMT > > Hi all. > > [quoted text clipped - 29 lines] > > Andrew T. Sorry man... eclipse did the "indentation" all I did was copy and paste into google.groups
Yeah.. the vector idea sounds good except that I haven't gotten that far in my self-education process... I wanted to see if I could accomplish my goal with the tools and knowledge I currently have.... but... I like your idea and as soon as I get that far in my learning process I will try to write something..
Stefan Ram - 17 Aug 2006 01:33 GMT >Here in Canada, we have a lottery called 6-49. No, this lottery in fact is located here in Germany, and it's called "6 aus 49".
>I wanted to come up with a statistically solid way to pick my >numbers so I figured that if I were to pick 6 numbers 1,000,000 >times and count the number of times each number is selected, >the top six would be good numbers to bet on during the lottery. Actually the numbers are best, which are most rarely chosen by other players, because then the rates will be higher.
>Here is my code. What I am hoping for is some constructive criticism >which could help me to make the code more efficient. Destructive criticism is much more fun!
>Rank 1 number is 43 class NumericMapUtils { public static <D> void addTo ( final java.util.Map<D,java.lang.Integer> map, final D d, final int i ) { map.put( d, i +( map.containsKey( d )? map.get( d ): 0 )); }}
public class Main { static final java.util.Random rand = new java.util.Random(); public static void main( java.lang.String[] args ) { final java.util.Map<java.lang.Integer,java.lang.Integer> map = new java.util.HashMap<java.lang.Integer,java.lang.Integer>( 50 ); for( int i = 0; i < 1000; ++i ) NumericMapUtils.<java.lang.Integer>addTo( map, rand.nextInt( 49 ), 1 ); final java.util.SortedMap<java.lang.Integer,java.lang.Integer> sort = new java.util.TreeMap<java.lang.Integer,java.lang.Integer>(); for( final java.lang.Integer i : map.keySet() )sort.put( -map.get( i ), i ); int c = 0; for( final int i : sort.keySet() ) { java.lang.System.out.println ( "Rank " +( c + 1 )+ " number is " + sort.get( i )); if( ++c >= 6 )break; }}}
Rank 1 number is 21 Rank 2 number is 14 Rank 3 number is 34 Rank 4 number is 15 Rank 5 number is 47 Rank 6 number is 20
However, there is a small chance that »nextInt« will return the same number for 1000 times, so that the program would only output one number; but I tried to implement your general description.
Stefan Ram - 17 Aug 2006 02:10 GMT >sort.put( -map.get( i ), i ); This attempt to "invert" a map still has a bug: If two keys of the original map have the same value, one of them will be lost. The following solution uses a small "bias" added to each value, to make it different from every other value. (It might fail under some conditions.)
class NumericMapUtils { public static <D> void addTo ( final java.util.Map<D,java.lang.Integer> map, final D d, final int i ) { map.put( d, i +( map.containsKey( d )? map.get( d ): 0 )); }}
public class Main { static final java.util.Random rand = new java.util.Random(); public static void main( java.lang.String[] args ) { final java.util.Map<java.lang.Integer,java.lang.Integer> map = new java.util.HashMap<java.lang.Integer,java.lang.Integer>( 50 ); final int k = 1000; for( int i = 0; i < k; ++i ) NumericMapUtils.<java.lang.Integer>addTo( map, rand.nextInt( 49 ), 1 ); final java.util.SortedMap<java.lang.Double,java.lang.Integer> sort = new java.util.TreeMap<java.lang.Double,java.lang.Integer>(); int j = 0; for( final java.lang.Integer i : map.keySet() ) sort.put( -map.get( i )+ j++ * .8 / k, i ); int c = 0; for( final java.lang.Double d : sort.keySet() ) { java.lang.System.out.println ( "Rank " +( c + 1 )+ " number is " + sort.get( d )); if( ++c >= 6 )break; }}}
A more clean solution might replace each key of the map "sort" by a ComparablePair of both the key and its value.
I even have implemented such a beast
http://www.purl.org/stefan_ram/html/ram.jar/de/dclj/ram/type/pair/ComparablePair.html
Luke Webber - 17 Aug 2006 02:12 GMT > Hi all. > [quoted text clipped - 19 lines] > (Normally I would not comment my code so much, but I wanted you to see > what I was trying to accomplish) [snip]
If you're asking this just as a Java question, then there are certainly things you can do to improve on it. But I have to point out that you're not modelling the real world here. You'll mostly be testing for bias in the Java random number generator, when you should really be testing for bias in whatever process/equipment the lottery agency is using.
If they keep historical records for downloading (as our Australian agency does), you'd be better served to download that and massage it.
Cheers, Luke
Patricia Shanahan - 17 Aug 2006 06:15 GMT > Hi all. > [quoted text clipped - 9 lines] > the number of times each number is selected, the top six would be good > numbers to bet on during the lottery. You are assuming that any bias in the Java Random class also applies to the lottery's random number generation method? I suspect it is using genuinely random numbers, not just pseudo-random, and monitors them for bias.
> With that being said, I thought I could write a Java program to do the > job. It proved to be a bit more difficult than I thought it would be; > the hardest part being ensuring that each of the 6 numbers were unique. Here is an alternative method for picking the 6 numbers.
There is a well-known linear time algorithm for shuffling an array, the Fisher-Yates shuffle. On iteration i, the element with index i is swapped with a randomly selected element between i and the end of the array.
There are two important loop invariants:
1. At the end of every iteration, the array contains a permutation of its original contents.
2. After N iterations, the first N elements of the array are randomly selected with equal probability.
In a normal shuffle, the number of iterations is equal to the size of the array minus one, and all elements have been shuffled. (The last iteration is not needed because it makes a random choice from one element, and swaps that element with itself).
Why not run Fisher-Yates for 6 iterations, and then pick up the first 6 elements of the array?
Patricia
/** * Partially shuffle the elements of an int * array * * On completion, data contains a permutation of * its original contents, with the elements in * the first count spaces selected randomly. * There is no assurance of randomness for * elements data[count] and later, and many of * those elements may remain in their original * positions. * * @param data * The array * @param count * The number of elements to shuffle. * If count is negative or greater than * data.length, all elements are * shuffled. * @param rand * partialShuffle gets its random * numbers from this generator. */ public static void partialShuffle(int[] data, int count, Random rand) { if (count > data.length || count < 0) { count = data.length; } for (int i = 0; i < count; i++) { int pickIndex = rand.nextInt(data.length - i) + i; int temp = data[pickIndex]; data[pickIndex] = data[i]; data[i] = temp; } }
Daniel Dyer - 18 Aug 2006 01:32 GMT > Why not run Fisher-Yates for 6 iterations, and then pick up the > first 6 elements of the array? OK, but if you are going to generate 6 random numbers between 1 and 49 in order to decide which elements to swap, why not just use those random numbers as your selected lottery numbers?
Dan.
 Signature Daniel Dyer http://www.dandyer.co.uk
Patricia Shanahan - 18 Aug 2006 03:21 GMT >> Why not run Fisher-Yates for 6 iterations, and then pick up the >> first 6 elements of the array? > > OK, but if you are going to generate 6 random numbers between 1 and 49 > in order to decide which elements to swap, why not just use those random > numbers as your selected lottery numbers? Because they may contain duplicates, and the OP wants unique numbers.
Patricia
Daniel Dyer - 18 Aug 2006 09:23 GMT >>> Why not run Fisher-Yates for 6 iterations, and then pick up the >>> first 6 elements of the array? [quoted text clipped - 3 lines] > > Because they may contain duplicates, and the OP wants unique numbers. Of course. I guessed you'd have a good reason, thanks.
Dan.
 Signature Daniel Dyer http://www.dandyer.co.uk
bugbear - 17 Aug 2006 10:04 GMT > Hi all. > [quoted text clipped - 6 lines] > > I wanted to come up with a statistically solid way to pick my numbers This requires analysis, not code.
BugBear
AndrewMcDonagh - 17 Aug 2006 20:07 GMT > Hi all. > [quoted text clipped - 16 lines] > Here is my code. What I am hoping for is some constructive criticism > which could help me to make the code more efficient. snipped
ok, to be brutal - you have created a Procedural solution not an Object Oriented solution. Given that Java is aimed at being an OO language (lets not get into an argument about what that is nor Java's flaws) it would be good to see the solution using the tools and techniques from an OO perspective.
That said, even if we stick with a procedural solution your current one needs a lot of work to improve its readability (never mind logic changes to remove unneeded loops, conditions or state)
HTH
Andrew...........
A simple starting point would be to turn comments into executable comments.
For example,
// the original array of 6 numbers picked int [] list = new int[6]; // the new array containing unique numbers only int[] newList = new int[6]; // this array is used to count the number of occurances (1-49) int [] BigList = new int[50];
becomes something like...
int [] originalPickedNumbers = new int[6]; int [] uniqueNumbers = new int[6]; int [] numberOfOccurancesCount = new int[50];
Another example would be for each of those comments blocks to become method names and move the code they refer to, into these new methods.
for example....
public class Sample {
public static void main(String args[]) { Date today = new Date(); System.out.println("Starting:" + today);
//the original array of 6 numbers picked int[] list = new int[6]; //the new array containing unique numbers only int[] newList = new int[6]; int number = 0; //this array is used to count the number of occurances (1-49) int[] BigList = new int[50];
initializeBigList(BigList); //do this whole thing a million times for (int y = 1; y <= 1000000; y++) { initializeNewList(newList); put6RandomNumbersIntoAnArray(list); boolean dupLocated = copyAllUniqueNumbersIntoNewList(list, newList);
if (dupLocated) { replaceAnyZeroSpaceHolderWithRandomNumber(newList); }
incrementBigListValuesThatMatchEachOfTheSixNumbers(list, BigList); }
int[] topSix = createNewListContainingOnlyTopSix(BigList); printListOfTopSix(topSix); }
private static void printListOfTopSix(int[] topSix) { //now print out the list of topSix for (int i = 0; i <= topSix.length - 1; i++) System.out.println("Rank " + (i + 1) + " number is " + topSix[i]); Date today2 = new Date(); System.out.println("Ending:" + today2); }
private static int[] createNewListContainingOnlyTopSix(int[] BigList) { //now find the top six and create a new array called topSix int[] topSix = new int[6]; for (int count = 0; count <= topSix.length - 1; count++) { int lIndex = 0; int largest = BigList[0]; //compare each element of BigList with each "other" element //of BigList (I created this algorithm on my own, or maybe I rememered //it from somewhere. for (int x = 0; x <= BigList.length - 1; x++) { for (int y = x + 1; y <= BigList.length - 2; y++) if (BigList[y] > largest) { largest = BigList[y]; BigList[y] = 0; lIndex = y; topSix[count] = lIndex; }
} } return topSix; }
private static void incrementBigListValuesThatMatchEachOfTheSixNumbers(int[] list, int[] BigList) { //so now we have a list of 6 unique numbers. and we need to increment //the value in BigList that corresponds to each of the six numbers. for (int j = 0; j <= list.length - 1; j++) { int idx = list[j]; BigList[idx]++; } }
private static void replaceAnyZeroSpaceHolderWithRandomNumber(int[] newList) { //now that we have at least one duplicate, we need to replace //the zero space holder with a new random number. So //to do that, we select a random number and then check to see //if it is the array. If it isn't then stick in in the list //otherwise, keep //selecting and checking until we can put it in (usually takes one ortwo //iterations for (int x = 0; x <= newList.length - 1; x++) if (newList[x] == 0) { boolean t = false; while (!t) { Random rand = new Random(); int number1 = rand.nextInt(49) + 1; int tt = 0; for (int r = 0; r <= newList.length - 1; r++) if (newList[r] != 0) if (newList[r] == number1) tt++; if (tt == 0) { newList[x] = number1; t = true; } } } }
private static boolean copyAllUniqueNumbersIntoNewList(int[] list, int[] newList) { //what this loop does is check each member of "list" to see //if it's a duplicate. Copy the current element to the newList //if it's not a duplicate. boolean dupLocated = false; for (int b = 0; b <= list.length - 1; b++) { int chkNum = list[b]; int temp = b; boolean found = false; for (int a = 0; a <= newList.length - 1; a++) { if (newList[a] == chkNum) { found = true; dupLocated = true; } } if (!found) newList[temp] = chkNum; } return dupLocated; }
private static void put6RandomNumbersIntoAnArray(int[] list) { int number; //put 6 random numbers into an array for (int z = 0; z < 6; z++) { Random rand = new Random(); number = rand.nextInt(49) + 1; list[z] = number; } }
private static void initializeNewList(int[] newList) { //initialize newList for (int t = 0; t <= newList.length - 1; t++) newList[t] = 0; }
private static void initializeBigList(int[] BigList) { //initialize BigList for (int x = 0; x <= BigList.length - 1; x++) BigList[x] = 0; } }
Print Guy - 17 Aug 2006 21:44 GMT > > Hi all. > > [quoted text clipped - 28 lines] > needs a lot of work to improve its readability (never mind logic changes > to remove unneeded loops, conditions or state) Brutal is good. My background is procedural languages even though I do some scripting and attempt to employ a OO design technique.
What you are suggesting here is great. What I am really hoping for is the implementation of my solution using classes and methods for objects like
class bigListElement int element; int count;
void insert() void delete() void display()
But I thought that if I started out using the stuff I knew about I would eventually be able to refine my design to the point where it was a true Object Oriented program, not a Java translation of a Cobol program :-)
Thanks muchly for your help.... you and Patricia have given me alot to think about.
AndrewMcDonagh - 17 Aug 2006 23:03 GMT >>> Hi all. >>> [quoted text clipped - 34 lines] > the implementation of my solution using classes and methods for objects > like Now that you have the first refactored version of your code, you can start to look for duplication*.
Removing the duplication will create abstractions or behavior styled methods. Once you have a number of these you should easily see that there are logical groupings of the methods.
Once you see these groupings you can refactor further, by moving them into their own class.
*duplication is not just code duplication - its also behavior or algorithm duplication.
A quick review of the current design shows a number of Loops on lists, doing something specific.
Each loop logic is the same. Its the specifics that different. These specifics could either be extracted into a new class or the loop logic called many times with different parameters for the loop to work on
for example...
we currently have.....
private static void initializeNewList(int[] newList) { //initialize newList for (int t = 0; t <= newList.length - 1; t++) newList[t] = 0; }
private static void initializeBigList(int[] BigList) { //initialize BigList for (int x = 0; x <= BigList.length - 1; x++) BigList[x] = 0; }
The duplication is obvious now we have these two methods. And you should see that the only difference is the array being used.
so if we renamed one of the two methods above to 'initializeList(...)
we could simply call the same method twice, once with 'newList' and another time with 'bigList'
as in....
public static void main(String args[]) { Date today = new Date(); System.out.println("Starting:" + today); //the original array of 6 numbers picked int[] list = new int[6]; //the new array containing unique numbers only int[] newList = new int[6]; int number = 0; //this array is used to count the number of occurances (1-49) int[] BigList = new int[50];
initializeList(BigList);
for (int y = 1; y <= 1000000; y++) { initializeList(newList);
// snipped remaining... }
private static void initializeList(int[] list) { for (int x = 0; x <= list.length - 1; x++) list[x] = 0; }
> class bigListElement > int element; [quoted text clipped - 8 lines] > a true Object Oriented program, not a Java translation of a Cobol > program :-) Thats fine, but do keep in mind that its not a problem doing a procedural approach per se.
The main problem comes should you need to use the solution in a program where two different implementations of the Sample class could be chosen.
In other words, static functions don't support polymorphism, so a program would not be able to accept/call a different version at runtime.
With your example, just moving the entire body of the 'main()' method into an 'instance' method would allow the start of polymorphism to be possible.
e.g.
class SampleRunner {
public void main(String[] args) {
Sample sample = new Sample(); sample.prinoutTopSixRandomNumbers(); }
}
class Sample {
public void printoutTopSixRandomNumbers() { // insert code from your main() method here.... }
}
> Thanks muchly for your help.... you and Patricia have given me alot to > think about. np - glad to help...
Luke Webber - 17 Aug 2006 22:27 GMT [snip]
> A simple starting point would be to turn comments into executable comments. > [quoted text clipped - 12 lines] > int [] uniqueNumbers = new int[6]; > int [] numberOfOccurancesCount = new int[50]; Say what? Let's skip the spelling mistake for a minute here and ask one simple question. Why "numberOf" AND "Count"? I mean, I like meaningful names, but I'd go insane trying to work with code like that.
[snip]
> private static int[] createNewListContainingOnlyTopSix(int[] BigList) { [snip]
> private static void > incrementBigListValuesThatMatchEachOfTheSixNumbers(int[] list, int[] > BigList) { [snip]
> private static void replaceAnyZeroSpaceHolderWithRandomNumber(int[] > newList) { [snip]
> private static boolean copyAllUniqueNumbersIntoNewList(int[] list, > int[] newList) { [snip]
> private static void put6RandomNumbersIntoAnArray(int[] list) { With the greatest respect, this is taking things WAY too far.
Luke
AndrewMcDonagh - 17 Aug 2006 22:42 GMT > [snip] >> A simple starting point would be to turn comments into executable [quoted text clipped - 18 lines] > simple question. Why "numberOf" AND "Count"? I mean, I like meaningful > names, but I'd go insane trying to work with code like that. I agree - but thats what the comments say the vars are ....
Once we rename them to be 'meaningful' i.e. get rid of the redundant comment, we can start to look for other changes to the entire design.
The initial renaming is simply a starting point to make sure the usages of the vars is more meaningful than 'list, biglist, newList' who's purpose is as clear as mud unless you constantly refer back to where they are defined.
> [snip] >> private static int[] createNewListContainingOnlyTopSix(int[] BigList) { [quoted text clipped - 10 lines] > [snip] >> private static void put6RandomNumbersIntoAnArray(int[] list) {
> With the greatest respect, this is taking things WAY too far. Why? Because the method names are long? I type them once and let Eclipse auto-complete from then on. Longer, more descriptive names help reveal and have a better chance of staying up to date than comments.
Besides, you missed the main part, its a starting point.
The aim of these small refactorings are not to keep the methods, but to reveal the algorithm used by the main() method.
Now we can see what the algorithm is within a few lines of code. We can't nor need to see the implementation of the algorithm.
Once we have this ability to see the algorithm we are better placed to refactor it further or rewrite it entirely.
> Luke Luke Webber - 18 Aug 2006 08:03 GMT >>> int [] originalPickedNumbers = new int[6]; >>> int [] uniqueNumbers = new int[6]; [quoted text clipped - 5 lines] > > I agree - but thats what the comments say the vars are .... So it's occurrenceCount or numOccurrences maybe, or even numberOfOccurrences if you really must, but I'd prefer something a little short, though still meaningful.
> Once we rename them to be 'meaningful' i.e. get rid of the redundant > comment, we can start to look for other changes to the entire design. [quoted text clipped - 3 lines] > purpose is as clear as mud unless you constantly refer back to where > they are defined. True, no doubt. As we used to say in the "old days", "real programmers can write FORTRAN in any language". <g>
>> [snip] >>> private static int[] createNewListContainingOnlyTopSix(int[] [quoted text clipped - 16 lines] > Why? Because the method names are long? > I type them once and let Eclipse auto-complete from then on. Which doesn't work for variable names. And doesn't even work for methods withing the current class unless you preface it with "this.", which is still more typing. But it;s not just typing it in that concerns me. It's /reading/ it as well. When the method names get that long, they actually start to /lose/ meaning for me, because I kind of zone out on the difference between "aReallyReallyLongNameThatGoesOnForever" and "aReallyReallyLongNameThatGoesOnForeverAndADay". There is a happy middle ground somewhere, where the names are meaningful, but not so long that you have difficulty parsing them in your head.
For me, you don't have to be able to look at a method name and have it tell you exactly what the method does. That's what documentation for. As long as the method is sufficiently meaningful to give me a fairish idea of its function, I'm frabjous.
> Longer, > more descriptive names help reveal and have a better chance of staying > up to date than comments. And if you decide that you want to handle Powerball numbers and system 5 entries as well, then what? You have to change the method name AND ALL CALLS TO IT, because it's no longer strictly six numbers?
And for that matter, why "IntoAnArray"? Your argument is an array, so that tells the story right there.
> Besides, you missed the main part, its a starting point. Ah, but when you tell a new programmer that "this is a starting point", they're likely to take it even /further/, and you never know where he'll end up <g>.
> The aim of these small refactorings are not to keep the methods, but to > reveal the algorithm used by the main() method. > > Now we can see what the algorithm is within a few lines of code. We > can't nor need to see the implementation of the algorithm. That's what Javadoc is for, IMO. I'm pleased to note that there are no examples if this level of verbosity in the standard libraries.
> Once we have this ability to see the algorithm we are better placed to > refactor it further or rewrite it entirely. Maybe. OTOH, as I've said before, once you start rewriting those methods, you're going to have to change the names to reflect their new function. But if they were at least slightly more generic, you wouldn't need to.
Luke
Print Guy - 19 Aug 2006 01:14 GMT So why are the result of your program so much differnent from the ones by the responder from gmail.com
Starting:Fri Aug 18 21:07:14 ADT 2006 Rank 1 number is 44 Rank 2 number is 40 Rank 3 number is 48 Rank 4 number is 43 Rank 5 number is 47 Rank 6 number is 45 Ending:Fri Aug 18 21:07:28 ADT 2006
vs
[27, 28, 3, 19, 45, 15]
My (your) numbers were all in the 40's where the other ones were more scattered.
Patricia Shanahan - 19 Aug 2006 04:01 GMT > So why are the result of your program so much differnent from the ones > by the responder from gmail.com [quoted text clipped - 14 lines] > My (your) numbers were all in the 40's where the other ones were more > scattered. Your method for finding the six most frequent numbers does not make sense to me. Could you explain how it is supposed to work? Specifically, why do you assign 0 to BigList[y] where you do? And why the three loops?
// now find the top six and create a new array called topSix int[] topSix = new int[6]; for (int count = 0; count <= topSix.length - 1; count++) { int lIndex = 0; int largest = BigList[0]; // compare each element of BigList with each "other" // element // of BigList (I created this algorithm on my own, or maybe // I // rememered // it from somewhere. for (int x = 0; x <= BigList.length - 1; x++) { for (int y = x + 1; y <= BigList.length - 2; y++) if (BigList[y] > largest) { largest = BigList[y]; BigList[y] = 0; lIndex = y; topSix[count] = lIndex; }
} }
I would have done something like the following, except I've kept your variable names to make the relationships clearer:
***** Warning! Warning! untested code ahead! ******
int[] topSix = new int[6]; for(int count = 0; count < topSix.length; count++){ int lIndex = 0; int largest = BigList[0]; for( int x = 1; x < BigList.length; x++){ if(BigList[x] > largest){ largest = BigList[x]; lIndex = x; } } topSix[count] = lIndex; BigList[lIndex] = 0; }
only zeroing out a BigList element when I definitely commit to its index being in the topSix.
Print Guy - 19 Aug 2006 20:52 GMT > > So why are the result of your program so much differnent from the ones > > by the responder from gmail.com [quoted text clipped - 63 lines] > only zeroing out a BigList element when I definitely commit to its index > being in the topSix. Well if each element of "BigList" contains the number of times it was picked when I did 6 selections, 1 million times then a) I need the top six (outer most loop) b) I need to compare each number (inner loop number 1) c) with each other number (inner loop number 2)
Seems to me that topSix should now contain the top six picks but I could be wrong..
Patricia Shanahan - 19 Aug 2006 22:08 GMT >>> So why are the result of your program so much differnent from the ones >>> by the responder from gmail.com [quoted text clipped - 69 lines] > b) I need to compare each number (inner loop number 1) > c) with each other number (inner loop number 2) Nope, you only need to compare each number to the best so far.
And you have not said why you zero out a value before you have committed to putting its index in topSix.
> Seems to me that topSix should now contain the top six picks but I > could be wrong.. Try separating it out into a method, and taking it for a test drive with known data.
Patricia
Patricia Shanahan - 19 Aug 2006 23:12 GMT ...
> Seems to me that topSix should now contain the top six picks but I > could be wrong.. I'm afraid you are wrong, and the apparent over-selection of the high numbers is due to bugs in your top six selection.
I've written a simple test program comparing the two methods. Take a look at it, and take it for a test drive:
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random;
public class TopSixTest {
public static void main(String[] args) { int[] data = new int[49]; // Fixed seed for reproducibility Random rand = new Random(5);
for (int i = 0; i < data.length; i++) { data[i] = 5; } System.out.println("data[i]==5"); test(data);
for (int i = 0; i < data.length; i++) { data[i] = i + 1; } System.out.println("data[i]==i+1"); test(data);
for (int i = 0; i < data.length; i++) { data[i] = 100 - i; } System.out.println("data[i]=100-i"); test(data);
testRandomData(rand); testRandomData(rand); testRandomData(rand); }
/** * Test random permutation of numbers from 1000 through 1048 * * @param rand */ private static void testRandomData(Random rand) { int[] data = new int[49]; List<Integer> dataList = new ArrayList<Integer>(); for (int i = 0; i < data.length; i++) { dataList.add(new Integer(1000 + i)); } Collections.shuffle(dataList, rand); for (int i = 0; i < data.length; i++) { data[i] = dataList.get(i).intValue(); } System.out .println("Random permutation of 1000 through 1048"); test(data); System.out.println("Actual positions of largest 6 elements"); for (int i = 1048; i > 1042; i--) { System.out.printf("%d %d", i, dataList .indexOf(new Integer(i))); System.out.println(); } }
/** * Print the results of both methods on the input data * * @param data * "BigList" data, a 49 element frequency array. */ private static void test(int[] data) { int[] printsTop = printsVersion(data.clone()); int[] patsTop = patsVersion(data.clone()); for (int i = 0; i < 6; i++) { System.out.printf("%d Print's %d Pats's %d", i, printsTop[i], patsTop[i]); System.out.println(); } }
private static int[] printsVersion(int[] BigList) { int[] topSix = new int[6]; for (int count = 0; count <= topSix.length - 1; count++) { int lIndex = 0; int largest = BigList[0]; for (int x = 0; x <= BigList.length - 1; x++) { for (int y = x + 1; y <= BigList.length - 2; y++) if (BigList[y] > largest) { largest = BigList[y]; BigList[y] = 0; lIndex = y; topSix[count] = lIndex; }
} } return topSix; }
private static int[] patsVersion(int[] BigList) { int[] topSix = new int[6]; for (int count = 0; count < topSix.length; count++) { int lIndex = 0; int largest = BigList[0]; for (int x = 1; x < BigList.length; x++) { if (BigList[x] > largest) { largest = BigList[x]; lIndex = x; } } topSix[count] = lIndex; BigList[lIndex] = 0; } return topSix; }
}
Patricia Shanahan - 20 Aug 2006 04:13 GMT > ... >> Seems to me that topSix should now contain the top six picks but I [quoted text clipped - 5 lines] > I've written a simple test program comparing the two methods. Take a > look at it, and take it for a test drive: ...
> private static int[] patsVersion(int[] BigList) { > int[] topSix = new int[6]; [quoted text clipped - 9 lines] > topSix[count] = lIndex; > BigList[lIndex] = 0; This line should be:
BigList[lIndex] = -1;
Zero is a possible count of the number of instances of a result. -1 is not.
> } > return topSix; > } > > } Daniel Dyer - 19 Aug 2006 20:01 GMT > So why are the result of your program so much differnent from the ones > by the responder from gmail.com [quoted text clipped - 14 lines] > My (your) numbers were all in the 40's where the other ones were more > scattered. While the first output does look suspicious, it could just be a freak occurrence. Have you only run it once or does it favour high numbers over repeated runs?
This may not be the cause of the anomaly, but both programs make the mistake of creating a new Random object for each random number generated. You should only ever use one Random instance and instead make multiple calls to it. Not only is it more efficient this way, it will avoid potential problems with the seeds of the instances being the same or very similar when they are used to generate only one number before being discarded.
Dan.
 Signature Daniel Dyer http://www.dandyer.co.uk
jgrabell@gmail.com - 17 Aug 2006 23:49 GMT import java.util.ArrayList; import java.util.Random; public class SixFourNine { ArrayList winningNumbers = null; public static int NUM_CHOICES = 6; public static int MAX_NUMBER = 49; int[][] simulationArray = new int[MAX_NUMBER][2]; /** creates a new SixFourNine object**/ public SixFourNine() { initializeSimulationArray(); } /** initializes the array for storing the simulation **/ public void initializeSimulationArray() { for (int i=0; i <MAX_NUMBER; i++) { simulationArray[i][0] = (i+1); simulationArray[i][1] = 0; } } /** default simulation -- 1 million trials **/ public void runSimulation() { runSimulation(1000000); } /** simulation -- specify # trials **/ public void runSimulation(int numTrials) { if (numTrials <= 0 ) return; Random rand = null; int number = 0; for (int i = 0; i < numTrials; i++ ){ rand = new Random() ; number=rand.nextInt(MAX_NUMBER) + 1; simulationArray[number-1][1]++; } } /** get the winning numbers. throws an exception if you have not run a simulation **/ public ArrayList getWinningNumbers() throws SixFourNineSimulationNotRunException { if (simulationArray == null) throw new SixFourNineSimulationNotRunException(); winningNumbers = new ArrayList(); for (int i = 0; i < NUM_CHOICES; i++) { Integer r = new Integer(findAndRemoveMax()); winningNumbers.add(r); } initializeSimulationArray(); return winningNumbers /*NOT A GUARANTEE*/; } /** finds the most picked number from the simulations, in the case of a tie, largest number (index) wins **/ private int findAndRemoveMax() { int max = 0; int count = 0; for (int i = 0; i < MAX_NUMBER; i++) { if (simulationArray[i][1] > count) { count = simulationArray[i][1] ; max = i; } } simulationArray[max][1] =0; return max+1; } /** program main **/ public static void main(String[] args) { SixFourNine sfn = new SixFourNine(); sfn.runSimulation(1000000); try { System.out.println(sfn.getWinningNumbers()); } catch (SixFourNineSimulationNotRunException sfnnre) { // this cannot happen in this example but we must catch; System.out.println("Sorry, there was a problem; you need to run a simulation before you can guess the winning numbers!"); System.exit(42); } System.exit(0); } public class SixFourNineSimulationNotRunException extends Exception {}; }
Daniel Dyer - 18 Aug 2006 01:14 GMT > Hi all. > [quoted text clipped - 9 lines] > the number of times each number is selected, the top six would be good > numbers to bet on during the lottery. How do you mean "statistically solid"? Unless you know of some flaw in the machine that picks the numbers, any set of six numbers is equally likely to come up as any other. You may as well pick 1, 2, 3, 4, 5 and 6 and be done with it. Unless, as Stefan suggested, you want to maximise your winnings if you ever hit the jackpot, in which case you need data about how often each number is selected by other players. In the absence of any hard data, I would guess that picking high numbers is the way to go as many people pick numbers that correspond to dates (birthdays, anniversaries etc.), which are all in the range 1-31.
> With that being said, I thought I could write a Java program to do the > job. It proved to be a bit more difficult than I thought it would be; > the hardest part being ensuring that each of the 6 numbers were unique. java.util.Random is not very good at generating statistically random numbers. See Roedy Green's page (http://mindprod.com/jgloss/pseudorandom.html) for more details. An improvement would be to use the SecureRandom class, which has a better distribution but is a bit slower.
Dan.
 Signature Daniel Dyer http://www.dandyer.co.uk
Print Guy - 18 Aug 2006 20:06 GMT > How do you mean "statistically solid"? Unless you know of some flaw in > the machine that picks the numbers, any set of six numbers is equally [quoted text clipped - 5 lines] > as many people pick numbers that correspond to dates (birthdays, > anniversaries etc.), which are all in the range 1-31. I thought that picking 6 random numbers between 1 and 49 a million times would be a reasonably good estimate of the real world odds. I guess I was wrong.
Actually, the odds are that if you roll a dice, you will get a 3 or 4 more than any other number so I was trying to sort of simulate that.
Patricia Shanahan - 18 Aug 2006 20:21 GMT >> How do you mean "statistically solid"? Unless you know of some flaw in >> the machine that picks the numbers, any set of six numbers is equally [quoted text clipped - 12 lines] > Actually, the odds are that if you roll a dice, you will get a 3 or 4 > more than any other number so I was trying to sort of simulate that. There is no one set of "real world" odds.
A single dice roll, a java.util.Random nextInt(), the numbers picked by a lottery machine, are all approximations to the uniform probability distribution, in which on each pick every number is exactly equally likely.
In each case, there may be bias due to the specific implementation.
A physical dice may not be perfectly fair, especially if it is at all worn, or the person throwing it is skilled. As already pointed out, there are defects in the java.util.Random implementation that may make it not perfectly fair.
The lottery machine is probably the closest of them all to being exactly uniform. A state lottery can afford to spend a lot more than the cost of a dice on buying their machine and testing it for uniformity.
Patricia
Print Guy - 19 Aug 2006 00:06 GMT > There is no one set of "real world" odds. > [quoted text clipped - 14 lines] > > Patricia So how do they do it? In the old days, there used to be 49 balls in a tumbler, one would fall out, then another, then another, then another until there were six. In fact, I seem to recall seeing on TV some of the televised American lotteries where the same methods were employed. If you wanted to simulate that, you would need an array of 49 numbers, then pick a number at random, drop that number out of the array, shrink it by one and then pick 1 - 48, then 1-47 etc. I guess the issue here isn't the way that the picking is simulated, but the way that the randomness is implemented. Is there any computer language, or program or whatever that is capable of true random number selection based on "statistically proven techniques" or is everything we consider to be random just a close approximation?
Patricia Shanahan - 19 Aug 2006 00:52 GMT >> There is no one set of "real world" odds. >> [quoted text clipped - 27 lines] > "statistically proven techniques" or is everything we consider to be > random just a close approximation? The algorithm I suggested, a truncated Fisher-Yates, essentially simulates the ball dropping process. After N iterations, the first N elements of the array contain the numbers that have been picked. The remaining length-N elements contain the numbers that were in the original array but have not yet been picked, and so can be picked in the future.
However, its accuracy is dependent on the quality of the underlying random number generator.
There are several approaches to getting random numbers.
The ball dropping machine, rolling dice, tossed coins, and spinning roulette wheels all depend on physical processes that are designed so that very small changes in the initial conditions can make large, hard to predict, changes in the outcome.
The strongest sources of random numbers are really unpredictable physical processes. For example, each atom of some isotope has a known probability of decaying in any given time interval, but we have no way of predicting which will decay when. The clicks of a Geiger counter are as close to true randomness as we can get.
java.util.Random, and similar software random number generators, are "pseudo-random". It takes a seed value, and does a repeated computation on it to get the next seed. Selected bits of the seed are returned as e.g. nextInt(). The results are designed to LOOK random, but the complete sequence of results is fixed once the seed has been chosen.
Patricia
Daniel Dyer - 19 Aug 2006 19:13 GMT > So how do they do it? In the old days, there used to be 49 balls in a > tumbler, one would fall out, then another, then another, then another [quoted text clipped - 8 lines] > "statistically proven techniques" or is everything we consider to be > random just a close approximation? I think you're right, the more important issue is the source of the randomness. That's not to say that the question which you posed was not an interesting programming problem. I think that Patricia's solution is particularly elegant (once I switched on my brain and understood why she was doing it that way).
This article (http://www.cigital.com/papers/download/developer_gambling.pdf) is an interesting story of how flaws in random number generation and shuffling algorithms allowed the authors to exploit an online poker site.
I'm not sure what you mean by "statistically proven techniques" for generating random numbers. There are however several tests that can be applied to a sequence of numbers in order to obtain a measure of "how random" the sequence is (or more correctly, a measure of how confident we should be that the sequence is truly random, since the statistics don't actually *prove* anything about the sequence). The most well-known of these tests is the Diehard suite (http://stat.fsu.edu/pub/diehard/). java.util.Random performs poorly on the Diehard suite, whereas java.security.SecureRandom performs well. I would imagine that the revelant gaming authorities have tested the performace of the lottery machines, using Diehard or similar, before awarding a licence in order to satisfy themselves that the outcomes are sufficiently random.
People who are seriously interested in good quality, unpredictable random numbers (i.e. cryptographers and online gaming operators) will typically use hardware devices that extract entropy from physical processes such as radioactive decay or electronic noise. The random bits from these devices (which are invariably slow) are often used as a seed for a PRNG with known statistical properties rather than relied upon in their own right.
A cheaper variation on this theme is to rely on sources of randomness that are already present in the computer hardware. The Solaris kernel, for example, extracts entropy from I/O timings in order to provide random numbers via /dev/random.
Are you interested in lotteries just as a programming exercise or are you seriously hoping to find a way to beat the system?
If you are interested in this kind of thing, maybe you should consider other types of gambling (i.e. roulette, blackjack, poker). For a start, the expected return on the lottery is abysmal (only about 50% of the money staked goes into the prize pool). So you have to have a huge edge in order to overcome the inherent disadvantage of playing the game in the first place. Blackjack on the other hand has an expected return of somewhere in the region of 99.4% (depending on the exact rules in use). In other words, if you play optimally (and it's not difficult to learn to do so), on average you will only lose 3 cents for every $5 you stake. This is still a losing proposition in the long-run, but you'd only need to find a slight edge to turn it around. Traditionally professional gamblers found this edge by card-counting, but the casinos have since introduced measures to prevent this such as using more decks and a continous shuffling machine.
The book "Fortune's Formula", by William Poundstone, is a good read. Among other things, it discusses money-making systems that have been used for Roulette, Blackjack and the stock market and looks at the ideas behind them, dating back to Shannon's work on information theory in the 1940s.
Dan.
 Signature Daniel Dyer http://www.dandyer.co.uk
Luke Webber - 19 Aug 2006 00:29 GMT > I thought that picking 6 random numbers between 1 and 49 a million > times would be a reasonably good estimate of the real world odds. I > guess I was wrong. > > Actually, the odds are that if you roll a dice, you will get a 3 or 4 > more than any other number so I was trying to sort of simulate that. That doesn't sound right. The statistical bias in dice generally kicks in when you roll multiple dice. Because there are more ways to make a seven than, for example, a twelve or a two.
Luke
Print Guy - 19 Aug 2006 01:21 GMT > > I thought that picking 6 random numbers between 1 and 49 a million > > times would be a reasonably good estimate of the real world odds. I [quoted text clipped - 8 lines] > > Luke Agreed but if you roll one dice say 10 or 20 times, you are more apt to get a 3 or 4 than any other number... let me see if I can find a link to verify this...
And of course I can't find it... I'll search some more tomorrow.... I like the way this thread turned out.... I got lots of good ideas and now it's time to continue reading.... I wonder if Ruby can do this kind of stuff ;-) (**ducks***)
Print Guy - 19 Aug 2006 01:26 GMT Apparently 4 is the best number of of 6
http://en.wikibooks.org/wiki/Image:Histogramofdice.png
Patricia Shanahan - 19 Aug 2006 02:37 GMT > Apparently 4 is the best number of of 6 > > http://en.wikibooks.org/wiki/Image:Histogramofdice.png You are taking a single image badly out of context. See http://en.wikibooks.org/wiki/Statistics:Displaying_Data/Histograms. It is an example of a hypothetical set of dice rolls, for part of a statistics course. As the page says "This could be the result of chance, or it could represent an actual anomaly in the data and it is something to take note of keep in mind.".
If I had been the person constructing the page, I would have used a biased "dice" to ensure an interesting histogram.
Patricia
Patricia Shanahan - 19 Aug 2006 02:55 GMT >>> I thought that picking 6 random numbers between 1 and 49 a million >>> times would be a reasonably good estimate of the real world odds. I [quoted text clipped - 10 lines] > get a 3 or 4 than any other number... let me see if I can find a link > to verify this... That may be a property of dice from some manufacturer, though they would probably not stay in business long if people found out. However, I think you may be confusing the single roll situation with the effect of adding the results of a lot of rolls.
For example, if you roll two fair dice, there is only one combination, a=6, b=6, that gives a 12. On the other hand, there are 6 ways of getting a total of 7.
According to http://en.wikipedia.org/wiki/Loaded_dice, "There is some controversy over whether manufacturing processes create genuinely "fair" dice (dice that roll with even distributions over their number span). Casino dice are legally required to be fair; those used by all others hold no such requirement." Note that if dice were consistently and measurably biased towards 4 there would be no controversy - it would be easy to prove. For there to be a controversy, any bias must be tiny.
Also, http://en.wikipedia.org/wiki/Craps discusses craps strategy solely in terms of the odds that would apply if the dice are fair. That suggests that there is no common bias.
Patricia
David Segall - 19 Aug 2006 15:52 GMT >Actually, the odds are that if you roll a dice, you will get a 3 or 4 >more than any other number Not true. The chances of rolling any number are exactly one in six if the dice has been perfectly made. It is true that for real physical devices there will be a bias but it is unlikely that will be apparent over the statistics available from Lotto draws. It is obviously impossible for you to simulate that bias with any computer program.
[OT] 1 http://www.random.org/ offers a source of "true" random numbers based on the noise you hear when your radio is not tuned to a station.
[OT] 2 A friend spent a week observing a roulette wheel in a casino and decided he had located a bias. As soon as he started betting the staff picked up the wheel he was at and dropped in a different one.
Print Guy - 19 Aug 2006 20:57 GMT > >Actually, the odds are that if you roll a dice, you will get a 3 or 4 > >more than any other number [quoted text clipped - 10 lines] > and decided he had located a bias. As soon as he started betting the > staff picked up the wheel he was at and dropped in a different one. Yes, the odds are 1 in 6 if you roll a dice once. But what if you roll a 6 sided dice 5000000 times? I still think that 4 or 5 will occur more times... I don't have time to roll a dice that many times, but it makes sense that it should apply no matter how many times you roll the die as long as it is a large number of times.
Daniel Dyer - 19 Aug 2006 21:35 GMT > Yes, the odds are 1 in 6 if you roll a dice once. But what if you roll > a 6 sided dice 5000000 times? I still think that 4 or 5 will occur > more times... I don't have time to roll a dice that many times, but it > makes sense that it should apply no matter how many times you roll the > die as long as it is a large number of times. If the odds are 1 in 6 for the first roll, wouldn't they be 1 in 6 for the second roll too? And for the third roll, and so on.
Why do you think 4 and 5 are more likely?
Perhaps you are confusing a uniform distribution with a normal distribution (a.k.a "bell curve")?
Dan.
 Signature Daniel Dyer http://www.dandyer.co.uk
Patricia Shanahan - 19 Aug 2006 22:26 GMT >>> Actually, the odds are that if you roll a dice, you will get a 3 or 4 >>> more than any other number [quoted text clipped - 16 lines] > makes sense that it should apply no matter how many times you roll the > die as long as it is a large number of times. What is your definition of "odds"?
It seems clear that you are not following the frequency interpretation of probability because in that approach the probability of a four on a single rolls is defined to be the limit, as N tends to infinity, of the proportion of fours in N rolls.
You seem to have different opinions about the proportion of fours in a large number of rolls and the probability of a four on a single roll?
Patricia
David Segall - 20 Aug 2006 09:40 GMT >Yes, the odds are 1 in 6 if you roll a dice once. But what if you roll >a 6 sided dice 5000000 times? I still think that 4 or 5 will occur >more times... I don't have time to roll a dice that many times, but it >makes sense that it should apply no matter how many times you roll the >die as long as it is a large number of times. If you agree that the odds are 1 in 6 for the first roll then the odds must be 1 in 6 for the second roll since the dice has no way of "knowing" that it has been rolled once already. That is still true for the third roll right up to the 5000000th roll.
Incidentally, why did you decide that it was four or five that would come up more often? Why not one or six?
Print Guy - 20 Aug 2006 14:22 GMT > >Yes, the odds are 1 in 6 if you roll a dice once. But what if you roll > >a 6 sided dice 5000000 times? I still think that 4 or 5 will occur [quoted text clipped - 8 lines] > Incidentally, why did you decide that it was four or five that would > come up more often? Why not one or six? Experience? Anyway this whole discussion has been fantastic. But I didn't win last night. I used some of the programs we came up with in this thread (including my original) and didn't come close to picking the right numbers.. Even a piece of code that I found in the Horstman book didn't pick the numbers... oh well
Patricia Shanahan - 20 Aug 2006 14:55 GMT >>> Yes, the odds are 1 in 6 if you roll a dice once. But what if you roll >>> a 6 sided dice 5000000 times? I still think that 4 or 5 will occur [quoted text clipped - 10 lines] > > Experience? But you said you didn't have time to do the number of rolls at which you expected the bias to show up?
> Anyway this whole discussion has been fantastic. But I didn't win last > night. I used some of the programs we came up with in this thread > (including my original) and didn't come close to picking the right > numbers.. Even a piece of code that I found in the Horstman book didn't > pick the numbers... oh well Assuming a difference in probabilities of numbers may be one of the worst strategies for picking lottery numbers.
The people running the lottery can monitor their own equipment for bias, and they have far more data than you do. You only get to see the few numbers from actual lottery runs. They get all the output, including as many test runs as they feel like doing between lottery runs.
On the other hand, there may be enough people assuming a bias that the numbers that happen to have shown up most in recent lottery runs are particularly popular. If so, picking those numbers would increase the risk that, in the extremely unlikely event of a win, you would have to share the prize.
Almost any strategy you can think of for picking the number will be chosen by others. There is one strategy, picking your numbers at random, with equal probability, for which that doesn't matter.
Patricia
Print Guy - 20 Aug 2006 21:58 GMT > >>> Yes, the odds are 1 in 6 if you roll a dice once. But what if you roll > >>> a 6 sided dice 5000000 times? I still think that 4 or 5 will occur [quoted text clipped - 39 lines] > > Patricia 20 rolls 1 = 4 2 = 4 3 = 3 4= 1 5=5 6=3
So I guess it would take more than 20 rolls before any kind of bias would show up.
A while ago, I went back in "time" and wrote down all the winning number combination for about 10 draws... if I remember correctly 14 was a good number....
zero - 20 Aug 2006 16:58 GMT >> >Yes, the odds are 1 in 6 if you roll a dice once. But what if you >> >roll a 6 sided dice 5000000 times? I still think that 4 or 5 will [quoted text clipped - 10 lines] > > Experience? Seems to me like you're confusing Gaussian distributed values (for example test scores, or people's heights) with truly random values (such as lottery numbers - if the lottery is fair - or dice rolls). For people's heights its it indeed true that there will be more people of say 1.8m (6') than people of 2.3m (7'5"). With dice however there is no reason to assume that the number 4 is likely to come up more often than the number 1. Although it may be counterintuitive, rolling the number 6 5 times in a row is just as likely as rolling the (exact) sequence 5 2 4 5 3.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|