Witam,
Z nudów i z ciekawości zacząłem pisać program do analizowania liczb losowych oraz liczb wylosowanych w grze Lotto.
Na początku skupiłem się na generowaniu liczb pseudolosowych w C# i analizowania wyników.
Pierwszy podstawowy test to oczywiście ilość wypadnięć danej liczby w świetle wszystkich losowań.
Zrobiłem pierwszy test - 500 tysięcy losowań... i zdziwiłem się. Spodziewałem się wyników równomiernie rozłożonych. W rezultacie osiągnąłem taki oto wynik:
Liczba 1 wylosowana została 141404 razy. Procent: 28,2808%
Liczba 2 wylosowana została 140471 razy. Procent: 28,0942%
Liczba 3 wylosowana została 139442 razy. Procent: 27,8884%
Liczba 4 wylosowana została 139094 razy. Procent: 27,8188%
Liczba 5 wylosowana została 139571 razy. Procent: 27,9142%
Liczba 6 wylosowana została 138831 razy. Procent: 27,7662%
Liczba 7 wylosowana została 138793 razy. Procent: 27,7586%
Liczba 8 wylosowana została 137627 razy. Procent: 27,5254%
Liczba 9 wylosowana została 137215 razy. Procent: 27,443%
Liczba 10 wylosowana została 136781 razy. Procent: 27,3562%
Liczba 11 wylosowana została 136712 razy. Procent: 27,3424%
Liczba 12 wylosowana została 135734 razy. Procent: 27,1468%
Liczba 13 wylosowana została 135398 razy. Procent: 27,0796%
Liczba 14 wylosowana została 135204 razy. Procent: 27,0408%
Liczba 15 wylosowana została 134530 razy. Procent: 26,906%
Liczba 16 wylosowana została 134305 razy. Procent: 26,861%
Liczba 17 wylosowana została 134765 razy. Procent: 26,953%
Liczba 18 wylosowana została 133481 razy. Procent: 26,6962%
Liczba 19 wylosowana została 133494 razy. Procent: 26,6988%
Liczba 20 wylosowana została 132398 razy. Procent: 26,4796%
Liczba 21 wylosowana została 132128 razy. Procent: 26,4256%
Liczba 22 wylosowana została 132176 razy. Procent: 26,4352%
Liczba 23 wylosowana została 131723 razy. Procent: 26,3446%
Liczba 24 wylosowana została 131242 razy. Procent: 26,2484%
Liczba 25 wylosowana została 130863 razy. Procent: 26,1726%
Liczba 26 wylosowana została 129823 razy. Procent: 25,9646%
Liczba 27 wylosowana została 129588 razy. Procent: 25,9176%
Liczba 28 wylosowana została 129728 razy. Procent: 25,9456%
Liczba 29 wylosowana została 129276 razy. Procent: 25,8552%
Liczba 30 wylosowana została 127909 razy. Procent: 25,5818%
Liczba 31 wylosowana została 127955 razy. Procent: 25,591%
Liczba 32 wylosowana została 127869 razy. Procent: 25,5738%
Liczba 33 wylosowana została 127760 razy. Procent: 25,552%
Liczba 34 wylosowana została 126849 razy. Procent: 25,3698%
Liczba 35 wylosowana została 126121 razy. Procent: 25,2242%
Liczba 36 wylosowana została 126235 razy. Procent: 25,247%
Liczba 37 wylosowana została 125541 razy. Procent: 25,1082%
Liczba 38 wylosowana została 125186 razy. Procent: 25,0372%
Liczba 39 wylosowana została 124942 razy. Procent: 24,9884%
Liczba 40 wylosowana została 124153 razy. Procent: 24,8306%
Liczba 41 wylosowana została 124566 razy. Procent: 24,9132%
Liczba 42 wylosowana została 123595 razy. Procent: 24,719%
Liczba 43 wylosowana została 123485 razy. Procent: 24,697%
Liczba 44 wylosowana została 123111 razy. Procent: 24,6222%
Liczba 45 wylosowana została 122667 razy. Procent: 24,5334%
Liczba 46 wylosowana została 122482 razy. Procent: 24,4964%
Liczba 47 wylosowana została 121707 razy. Procent: 24,3414%
Liczba 48 wylosowana została 121618 razy. Procent: 24,3236%
Liczba 49 wylosowana została 121358 razy. Procent: 24,2716%
Liczba 50 wylosowana została 120983 razy. Procent: 24,1966%
Liczba 51 wylosowana została 120580 razy. Procent: 24,116%
Liczba 52 wylosowana została 120200 razy. Procent: 24,04%
Liczba 53 wylosowana została 119923 razy. Procent: 23,9846%
Liczba 54 wylosowana została 119610 razy. Procent: 23,922%
Liczba 55 wylosowana została 119328 razy. Procent: 23,8656%
Liczba 56 wylosowana została 119221 razy. Procent: 23,8442%
Liczba 57 wylosowana została 118587 razy. Procent: 23,7174%
Liczba 58 wylosowana została 117993 razy. Procent: 23,5986%
Liczba 59 wylosowana została 118177 razy. Procent: 23,6354%
Liczba 60 wylosowana została 117478 razy. Procent: 23,4956%
Liczba 61 wylosowana została 117436 razy. Procent: 23,4872%
Liczba 62 wylosowana została 116982 razy. Procent: 23,3964%
Liczba 63 wylosowana została 116547 razy. Procent: 23,3094%
Liczba 64 wylosowana została 116274 razy. Procent: 23,2548%
Liczba 65 wylosowana została 115702 razy. Procent: 23,1404%
Liczba 66 wylosowana została 115704 razy. Procent: 23,1408%
Liczba 67 wylosowana została 114550 razy. Procent: 22,91%
Liczba 68 wylosowana została 115058 razy. Procent: 23,0116%
Liczba 69 wylosowana została 114740 razy. Procent: 22,948%
Liczba 70 wylosowana została 114091 razy. Procent: 22,8182%
Liczba 71 wylosowana została 114269 razy. Procent: 22,8538%
Liczba 72 wylosowana została 113114 razy. Procent: 22,6228%
Liczba 73 wylosowana została 113113 razy. Procent: 22,6226%
Liczba 74 wylosowana została 112901 razy. Procent: 22,5802%
Liczba 75 wylosowana została 113168 razy. Procent: 22,6336%
Liczba 76 wylosowana została 112136 razy. Procent: 22,4272%
Liczba 77 wylosowana została 112216 razy. Procent: 22,4432%
Liczba 78 wylosowana została 111376 razy. Procent: 22,2752%
Liczba 79 wylosowana została 111017 razy. Procent: 22,2034%
Liczba 80 wylosowana została 110620 razy. Procent: 22,124%
Jest to dosyć zaskakujący wynik, gdyż według mnie wyniki powinny być rozłożone równomiernie po każdych liczbach (około 25% dla każdej). Pierwsze założenie: błąd w kodzie.
Zacząłem szukać i zauważyłem (co nie było trudne), że wyniki są PRAWIE posortowane (widać powyżej, że liczba 1 wypadała najczęściej a 80 najmniej razy). Podczas wyświetlania wyników Lotto sortuje sobie liczby by łatwiej je było czytać i analizować.
Problem w tym, że to sortowanie nie ma nic wspólnego z powyższymi wynikami (posortowane liczby to losowania, a tutaj tylko ilość wypadnięć danych liczb).
Mimo to wyłączyłem losowanie i uzyskałem wynik poprawny - czyli liczby równomiernie rozłożone.
Jednak... według mnie błędu w kodzie nie ma. Mam podejrzenie, że to randomizer C# zachowuje się dziwnie.
Oto kawałek kodu formatki:
private void MultiLotekMake()
{
this.SetStatus("Trwa losowanie...");
StringBuilder builder = new StringBuilder();
this.ProgressRandomizer.Maximum = (int)this.NumbersRandomBox.Value;
for (int i = 0; i < this.NumbersRandomBox.Value; i++)
{
this.multiLotek.MakeLotto();
builder.AppendLine("Numer losowania: " + (i+1).ToString() + " - " + this.multiLotek.GetNumbersLottoInString());
this.ProgressRandomizer.Value++;
}
this.SetStatus("Trwa wyświetlanie wyników...");
this.tbRandomNumbers.Text = builder.ToString();
this.tbCountNumbers.Text = this.multiLotek.GetCountNumbersInString((int)this.NumbersRandomBox.Value);
this.ProgressRandomizer.Value = 0;
this.SetStatus(DONE);
}
private void btnMultiLotek_Click(object sender, EventArgs e)
{
try
{
this.MultiLotekMake();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Oto fragment kodu losowania:
private int GetNewNumber()
{
int randomNumber = 0;
do
{
randomNumber = this.rand.Next(1, this.maxNumbersInLotto);
} while (this.IsNumberInList(randomNumber));
return randomNumber;
}
public void MakeLotto()
{
for (int i = 0; i < this.numbers.Length; i++)
{
int numberRandom = this.GetNewNumber();
this.numbers[i] = numberRandom;
this.stats.SetAddToNumbers(numberRandom);
}
Array.Sort(this.numbers);
}
Prosze zwrócić uwagę na linię:
Array.Sort(this.numbers);
wyłączenie tego sortowania ukazuje poprawne wyniki, ale...
Oto kod statystyk:
public class Stats
{
private int[] numbers;
public Stats(int maxNumber)
{
this.numbers = new int[maxNumber];
HelperMethods.ZeroArray(this.numbers);
}
public string GetCountNumbersInString(int countRandom)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < this.numbers.Length; i++)
builder.AppendLine("Liczba " + (i+1).ToString() + " wylosowana została " + this.numbers[i] + " razy." +
" Procent: " + ((this.numbers[i] * 100.0) / countRandom).ToString() + "%");
return builder.ToString();
}
public void SetAddToNumbers(int number)
{
number--;
this.numbers[number]++;
}
Czy ktoś widzi może tutaj błąd w kodzie, który powodowałby błędne losowania liczb?
Z sorotwaniem: Array.Sort(this.numbers);
wyniki są "dziwne", natomiast gdy wyłączę to sortowanie to wyniki wydają się być poprawne.
Problem w tym, że owo sortowanie wykonuję na sam koniec losowania i nie ma ono wpływu na nic.
Czy to jest dziwne zachowanie randomizera C#?
Pozdrawiam.