Bugün şans oyunları ve simülasyon üzerinde örnekler paylaşmak istiyorum. Gecenin ilk sorusu, sayısal loto oyunun daki gibi 1 ile 49 arasında tekrarsız 6 adet rastgele tamsayı üreten bir Java programı olsun, takip edecek sorularda da önce kupon doldurarak kaç adet tutturduğumuza bakarız, sonra da bir simülasyon uygulaması yaparak mesela 1000 kupon doldurduğumuzda kaç adet 6 tutturduğumuza (ya da tutturamadığımıza) bakar ve ikramiyeler ile ödemelerimizi karşılaştırarak sayısal loto oynamanın beklenen kazancını ve kaybını hesaplarız.
Edit: Kupon doldurma ve kaç tane tutturduğunu kontrol eden program kodları eklendi
Edit 2: Çekiliş yapan algoritma kodları eklendi
Önce 6 adet 1 ile 49 arasında rastgele tamsayı üretelim ve bu sayılar tekrar etmesin. Buna benze bir örneği Java'da rastgele elemanlardan oluşan bir dizi (vektör) üretmek paylaşımımda zaten yaptığım için oradan da esinlenerek;
Hatalı Çözüm:
int[] cekilis = new int[6];
for (int i=0; i<6; i++)
{
cekilis[i]=(int)(Math.random()*49)+1;
System.out.println((i+1)+". top:"+cekilis[i]);
}
Çıktı:
1. top:39
2. top:39
3. top:25
4. top:28
5. top:38
6. top:49
Bu çözüm hatalıdır, çünkü bir top birden çok kez gelemez. Bunun yerine iki alternatif çözüm üretebiliriz. Bu iki çözümden ilki 1 ile 49 arasında sayılardan oluşan bir vektör (toplar vektörü olsun) daha ekleyerek rastgele üretilen sayı ile bu vektördeki sayıyı cekilis vektörüne aktarmak, aktardıktan sonra da toplar vektöründen kaldırmak olabilir. İkinci çözüm ise, 1 ile 49 arasındaki rastgele sayı üretme işlemini bir metod olarak güncellemek ve bu metodu cekilis vektörünün her bir elemanına kendinden önceki elemanlar içinde kendisi olmadığına emin olarak yaptırabiliriz. Bu işle için de iki vektör arasındaki ortak elemanları bulma algoritmasını kullanabiliriz, ya da daha kolayı vektör içinde arama yapabiliriz. İkinci yoldan çözelim;
Doğru Çözüm:
public static void main(String [] args) {
int[] cekilis = new int[6];
for (int i=0; i<6; i++)
{
boolean kontrol=true;
while (kontrol)
{
int top=topCek();
kontrol = IntStream.of(cekilis).anyMatch(x -> x == top);
if(!kontrol)
cekilis[i]=top;
}
System.out.println((i+1)+". top:"+cekilis[i]);
}
}
public static int topCek()
{
return (int)(Math.random()*49)+1;
}
Çıktı:
1. top:41
2. top:46
3. top:40
4. top:31
5. top:19
6. top:4
Peki bu 6 sayının birbirinden farklı gelmiş olması tesadüf olamaz mı? Bunu anlayabilmek için 1 ile 49 arasında 100 adet top çekelim, eğer çıktımız 49'da bitiyor ve 50. topta sonsuz döngüye düşüyorsak doğru yapmışız demektir.
Kontrol:
public static void main(String [] args) {
int[] cekilis = new int[100];
for (int i=0; i<100; i++)
{
boolean kontrol=true;
while (kontrol)
{
int top=topCek();
kontrol = IntStream.of(cekilis).anyMatch(x -> x == top);
if(!kontrol)
cekilis[i]=top;
}
System.out.println((i+1)+". top:"+cekilis[i]);
}
}
public static int topCek()
{
return (int)(Math.random()*49)+1;
}
Çıktı:
1. top:3
2. top:29
3. top:11
4. top:26
5. top:1
6. top:49
7. top:18
8. top:46
9. top:9
10. top:23
11. top:19
12. top:24
13. top:44
14. top:41
15. top:30
16. top:43
17. top:38
18. top:48
19. top:10
20. top:37
21. top:8
22. top:31
23. top:28
24. top:13
25. top:39
26. top:15
27. top:27
28. top:32
29. top:4
30. top:2
31. top:47
32. top:5
33. top:6
34. top:16
35. top:20
36. top:34
37. top:17
38. top:21
39. top:42
40. top:36
41. top:35
42. top:7
43. top:33
44. top:12
45. top:25
46. top:14
47. top:45
48. top:40
49. top:22
...Sonsuz Döngü
Sonuç: Çözümümüz çalışıyor