Dziwne wyniki losowania - czy tak powinno być? Orzeł/reszka, czarne czerwone.

2

Witam. Programik napisany bardzo mocno z nudów. Nie mogłem zasnąć. ;)
Chodziło mi o sprawdzenie jak długa potrafi być seria czerwonych grając w ruletkę. Potem program trochę się rozwinął, efekt poniżej:

#include "stdafx.h"
#include <iostream>
#include <time.h>

using std::cout;

unsigned short int symulacja()
{
	bool los=rand()%2;
	unsigned short int licz = 1;
	while(los)
	{
		los=rand()%2;
		licz++;
	};
	return licz;
}

int _tmain(int argc, _TCHAR* argv[])
{
	srand(time(NULL));
	static int n=20;
	unsigned int *tab= new unsigned int[n];
	unsigned long int licz_prob=0;
	for(int i=0;i<n;i++)	tab[i]=0;

	do{
		tab[symulacja()-1]++;
		licz_prob++;
		if(licz_prob%100000==0) 
		{
			system("cls");
			cout<<"Liczba prob: "<<licz_prob/1000<<"k\n";
			for(int i=0;i<n;i++)	cout<<i+1<<"\t"<<tab[i]<<"\n";
		}
	}while (tab[9]<=100000);
	
	system("cls");
	cout<<"Liczba prob: "<<licz_prob/1000<<"k\n";
	for(int i=0;i<n;i++)	cout<<i+1<<"\t"<<tab[i]<<"\n";	

	system("PAUSE");
	return 0;
}


Dziwią mnie mocno wyniki. Oto one:

Liczba prob: 107437k
1       53723587
2       26854335
3       13395144
4       6754130
5       3326253
6       1686872
7       855750
8       440987
9       209834
10      100000
11      44264
12      24590
13      8197
14      8196
15      1639
16      3278
17      0
18      0
19      0
20      0
Press any key to continue . . .

Prób było kilka, za każdym razem zwiększałem warunek (ilość serii, w których czerwone wypadają za 10 razem). Za każdym razem były zbliżone proporcje (to akurat mnie nie dziwi) i za każdym razem:

  • Liczba serii w których czerwone wypały za 13 i 14 razem była bardzo mocno zbliżona. Prawdopodobieństwo wskazuje na to, że szansa na to, że czerwone wypadną 14 razy pod rząd jest o połowę mniejsze niż, że wypadną 13 razy. Ta zasada jest widoczna całkiem nieźle do serii 12 czerwonych. Potem zaczynają się dziać dziwne rzeczy.
  • Liczba serii w których czerwone wypadają 15 razy pod rząd jest dużo niższa niż w teorii powinna być. We wklejonym przykładzie jeśli liczba serii, w których czerwony wypadły 14 razy wynosi 8196, to 15 razy powinno wynieść około 4000. Czemu wynosi jedynie 1639?
  • Liczba serii w których czerwone wypadają 16 razy pod rząd przy każdym uruchomieniu programu była około 2 razy wyższa niż liczba prób w których czerwone wypadają 15 razy pod rząd. To też mi się nie zgadza.
  • I ostatnie pytanie. Jakim cudem nie wypadło ani razu 17 lub więcej razy pod rząd czerwone?

PS. Wiem, że w programie jest babol pt "Zwiększasz wartość komórki 20elementowej tabeli, a jeśli wynik symulacji będzie wynosić ponad 20 to wyskoczysz poza pamięć." Wiem, programik był mniej rozbudowany, a szansa na to wynosi jakieś 1/(2^20), więc byłem gotów zaryzykować przy programiku pisanym 4fun.

Jak komuś będzie chciało się pomyśleć i mnie oświecić będę wdzięczny.
Pozdrawiam

1

Co będzie gdy funkcja symulacja() zwróci wartość 21?
Dlaczego taki warunek while (tab[9]<=100000); i co będzie gdy tab[9] ustali się na wartość < 100000'?
Nie używaj gołych new i delete. Uczę się C++, kiedy używać new i delete?
Nie używaj rand(), C++ ma <random>

0

Fachowo to się nazywa seriami Bernoullego:

Dokładny wzór na średnią liczbę prób aż do uzyskania serii k sukcesów jest chyba taki:
n = (1-p^k)/(1-p) * 1/p^k

W tym przypadku masz p = 1/2;
co np. dla liczby sukcesów k = 8, daje: n = (1-1/256)/(1-1/2) * 256 = 510 rzutów (średnio).

0
YooSy napisał(a):

Co będzie gdy funkcja symulacja() zwróci wartość 21?

Piotr Uchman napisał(a):

PS. Wiem, że w programie jest babol pt "Zwiększasz wartość komórki 20elementowej tabeli, a jeśli wynik symulacji będzie wynosić ponad 20 to wyskoczysz poza pamięć." Wiem, programik był mniej rozbudowany, a szansa na to wynosi jakieś 1/(2^20), więc byłem gotów zaryzykować przy programiku pisanym 4fun.

YooSy napisał(a):

Dlaczego taki warunek while (tab[9]<=100000); i co będzie gdy tab[9] ustali się na wartość < 100000'?

Bo takie warunek końca sobie przyjąłem. Równie dobrze program mógłby się kończyć np. kiedy licznik prób będzie większy niż mln.

YooSy napisał(a):

Nie używaj gołych new i delete. Uczę się C++, kiedy używać new i delete?

Dziękuję za cenną uwagę i jak dla mnie wartościowy wpis.

YooSy napisał(a):

Nie używaj rand(), C++ ma <random>

Stosowanie rand() zostało mi z C, którego się uczyłem w LO. Później zacząłem z C++. Postaram się pamiętać o tym na przyszłość.

hehej napisał(a):

Fachowo to się nazywa seriami Bernoullego:

Dokładny wzór na średnią liczbę prób aż do uzyskania serii k sukcesów jest chyba taki:
n = (1-p^k)/(1-p) * 1/p^k

W tym przypadku masz p = 1/2;
co np. dla liczby sukcesów k = 8, daje: n = (1-1/256)/(1-1/2) * 256 = 510 rzutów (średnio).

Wiem. Właśnie pytam skąd wyniki tak bardzo odbiegające od teorii. Tego nie jestem w stanie zrozumieć.

0

Bo takie warunek końca sobie przyjąłem.

Rozumiem. Gdy ustalona wartość nie osiągnie zakresu kończącego i zostanie zapisana na stałe w tab[9], będzie wyjście poza zakres tablicy,
bo pętla będzie nieskończona.

0

Wiem. Właśnie pytam skąd wyniki tak bardzo odbiegające od teorii. Tego nie jestem w stanie zrozumieć.

No bo bzdury tworzysz.

int runs[256] = {0}; // tablica wystąpień runów długości: k = 1,2,3, ... 254

int n = 1000000, // liczba prób
    s = 0; // długość serii

for(i = 0; i < n; i++ )
 {
   if ( random(1000) < 500 ) s++;
   else // koniec serii
    {
      if( s > 254 ) s = 255; // zbyt długie posumujemy sobie wszystkie razem
      runs[s]++;
      s = 0; // idzie następna seria
   }
 }

out(runs);
4

Wygląda na to, że po prostu dotarłeś do limitu presudo losowości tego generatora.
Generatory liczb losowych są pseudo losowe, ergo zawsze pojawia się jakiś moment gdy wystąpią jakieś korelacje, między wartościami.
Robiąc symulacje komputerowe monte carlo, trzeba zawsze o tym pamiętać i wiedzieć, że grozi to fałszowaniem wyników.
Z tego powodu C++11 dostarczył więcej rożnych generatorów liczb losowych oraz API, które powinno wykorzystywać hardware do uzyskania liczb naprawdę losowych.

Klasyczny przykładem pokazującą słabość LCG (do której zwykle należy rand), jest narysowanie obrazka z punktów (x, y) utworzonych z kolejnych liczb pseudo losowych takiego generatora.
Jeśli doda się tych punktów bardzo dużo, to powiększenie obrazka wykażę strukturę. Punkty się układają wzdłuż ciasno upakowanych ukośnych linii.

0

@MarekR22: Chyba wyczerpałeś temat. Widzę, że muszę sporo doczytać o generatorach liczb losowych. Dziękuję za odpowiedź i wartościowe dla mnie linki.

3

Dodam jeszcze, że z moich testów wynika, że rand w Visual Studio jest szczególnie kulawy:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <random>
#include <iomanip>
#include <chrono>

const size_t limitCount = 128;

template <typename Generator>
size_t countConsecutiveEvens(Generator &gen)
{
    size_t count = 0;
    while(gen() % 2 == 0 && count < limitCount) {
         ++count;
    }
    return count;
}

template <typename Generator>
std::vector<size_t> generateHistorgram(size_t index, size_t minimumExpected, Generator gen)
{
       std::vector<size_t> hist(limitCount);
       while (hist[index] < minimumExpected) {
             auto x = countConsecutiveEvens(gen);
             // while (x >= hist.size()) hist.resize(hist.size() * 2);
             ++hist[x];
       }
      return hist;
}

void printHist(std::ostream &out, const std::vector<size_t>& hist)
{
    int zeroCount = 0;
    const int zeroLimit = 5;
    
    for (size_t i = 0; i < hist.size(); ++i) {
        out << std::setw(3) << i 
            << ' ' << std::setw(8) << hist[i] 
            << "  " << hist.front() / (double)hist[i] <<'\n';
        
        if (hist[i] == 0) {
            if (++zeroCount >= zeroLimit) {
                break;
            }
        } else {
            zeroCount = 0;
        }
    }
}

int main() {
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    
    const size_t sample = 9;
    const size_t minValue = 50000;
    
    srand(seed);
    std::cout << "C rand\n";
    printHist(std::cout, generateHistorgram(sample, minValue, rand));
    
    std::cout << "\nC++ std::minstd_rand0\n";
    printHist(std::cout, generateHistorgram(sample, minValue, std::minstd_rand0(seed)));
    
    std::cout << "\nC++ std::mt19937\n";
    printHist(std::cout, generateHistorgram(sample, minValue, std::mt19937(seed)));
    
    return 0;
}
0
MarekR22 napisał(a):

Wygląda na to, że po prostu dotarłeś do limitu presudo losowości tego generatora.
Generatory liczb losowych są pseudo losowe, ergo zawsze pojawia się jakiś moment gdy wystąpią jakieś korelacje, między wartościami.
Robiąc symulacje komputerowe monte carlo, trzeba zawsze o tym pamiętać i wiedzieć, że grozi to fałszowaniem wyników.
Z tego powodu C++11 dostarczył więcej rożnych generatorów liczb losowych oraz API, które powinno wykorzystywać hardware do uzyskania liczb naprawdę losowych.

Klasyczny przykładem pokazującą słabość LCG (do której zwykle należy rand), jest narysowanie obrazka z punktów (x, y) utworzonych z kolejnych liczb pseudo losowych takiego generatora.
Jeśli doda się tych punktów bardzo dużo, to powiększenie obrazka wykażę strukturę. Punkty się układają wzdłuż ciasno upakowanych ukośnych linii.

Nieprawda.
W tym przypadku wyniki są poprawne dla dowolnego generatora.

0

Dziwne wyniki losowania - czy tak powinno być? Orzeł/reszka, czarne czerwone. "Dodam jeszcze, że z moich testów wynika, że rand w Visual Studio jest szczególnie kulawy." - MarekR22 32

Nie mam pojęcia co tam tworzycie - ja mam poprawne wyniki dla dowolnego generatora.

Pojedyncze bity są zawsze bardzo poprawnie losowe: p = 1/2, dla dowolnego bita w random!

random(2) = 0 -> bit 0
random(2) = 1 -> bit 1
wyjdzie po 50% - zawsze !!!

random(100) < 50 -> 50% - zawsze!

randf() < 0.5 -> 50% - zawsze!
itd.

0

Najprawdopodobniej generator ma za krótki okres, dlatego dla dłuższych ciągów powtórzeń dostałeś zero, spróbuj z innym generatorem np. takim, który zapewnia bardzo długi cykl, choć niestety jest powolny.

0
cs napisał(a):

Najprawdopodobniej generator ma za krótki okres, dlatego dla dłuższych ciągów powtórzeń dostałeś zero, spróbuj z innym generatorem np. takim, który zapewnia bardzo długi cykl, choć niestety jest powolny.

Wątpię aby w VS był aż tak popsuty random.

Nawet prostacki random: xor128 produkuje poprawne losowe.
https://en.wikipedia.org/wiki/Xorshift

uint xor128(void) {
  uint t;
  t = x ^ (x << 11);
  x = y; y = z; z = w;
  return w = w ^ (w >> 19) ^ (t ^ (t >> 8));
}

gdzie: x, y, z w, są wcześniej definiowane, np. tak:
uint x = 123456789, y = 362436069, z = 521288629, w= 88675123;

co można sobie inaczej ustawić, oczywista, np.: x,y = time(), w nanosekundach...

0
hehej napisał(a):
cs napisał(a):

Najprawdopodobniej generator ma za krótki okres, dlatego dla dłuższych ciągów powtórzeń dostałeś zero, spróbuj z innym generatorem np. takim, który zapewnia bardzo długi cykl, choć niestety jest powolny.

Wątpię aby w VS był aż tak popsuty random.

Z wyników OP i moich (które podlinkowałem) wynika, że twoje zaufanie do VS jest bezzasadne.
Wystarczy zmienić kompilator, albo generator i ten sam kod generuje wyniki, które wyglądają na poprawne.

0
MarekR22 napisał(a):
hehej napisał(a):
cs napisał(a):

Najprawdopodobniej generator ma za krótki okres, dlatego dla dłuższych ciągów powtórzeń dostałeś zero, spróbuj z innym generatorem np. takim, który zapewnia bardzo długi cykl, choć niestety jest powolny.

Wątpię aby w VS był aż tak popsuty random.

Z wyników OP i moich (które podlinkowałem) wynika, że twoje zaufanie do VS jest bezzasadne.
Wystarczy zmienić kompilator, albo generator i ten sam kod generuje wyniki, które wyglądają na poprawne.

Chyba źle to wyliczasz i stąd błędne wnioski.

Takie należy wyliczać wielokrotnie dla zdanego n = liczba prób, ponieważ tu średnia ma być zgodna z tymi wzorami ze statystyki.

Zatem tak należy to robić:
N - liczba testów, np. N = 1000 (w teorii powinno to być nieskończone, aby wyniki były idealnie zgodne z teorią!)

i teraz zliczamy te serie np. dla n = milion prób, ale N razy, nie tylko raz.

Potem drukujemy wyniki w taki sposób:
runs[k] * 1.0/N, bo taka jest średnia z N testów.

Zrób tak, a wtedy się okaże że jest OK.

0

a tak jeszcze w ramach tego improwizowania o losowaniu serii:

zamiast losować miliony razy i sprawdzać rnd() & 2, wystarczy przecież sprawdzać poszczególne bity z losowanej liczby, którą zwraca funkcja rnd.

Np. gdy mamy random, który produkuje 32 bity, wówczas mamy od razu - za jednym strzałem, aż 32 losowania z p = 0.5!

x = rand32(); // mamy 32 losowe bity, każdy z prawdop. p=0.5

for(i = 0; i < 32; i++, x >>= 1)
if( x & 1 ) hit++;
else koniec serii...

32 razy szybciej, a dla rand64 byłoby jeszcze 2 razy lepiej.

0
MarekR22 napisał(a):
hehej napisał(a):
cs napisał(a):

Najprawdopodobniej generator ma za krótki okres, dlatego dla dłuższych ciągów powtórzeń dostałeś zero, spróbuj z innym generatorem np. takim, który zapewnia bardzo długi cykl, choć niestety jest powolny.

Wątpię aby w VS był aż tak popsuty random.

Z wyników OP i moich (które podlinkowałem) wynika, że twoje zaufanie do VS jest bezzasadne.
Wystarczy zmienić kompilator, albo generator i ten sam kod generuje wyniki, które wyglądają na poprawne.

Pomyślałem, że to ciekawe. Sprawdziłem na starym dobrym Devie na którym się uczyłem 100 lat temu. :) Na drugim komputerze, w pracy - żeby mieć upewnić się czy winą za błędne wyniki można obarczyć kompilator lub może sam komputer czy też kod. Wyniki działania programu zbliżone, mimo mocniejszej jednostki na DEVie jakoś o dziwo dużo dłużej młóciło. ;) Załączam:

Liczba prob: 107429k
1       53719534
2       26852447
3       13394276
4       6753643
5       3325998
6       1686785
7       855697
8       440958
9       209812
10      100001
11      44264
12      24588
13      8196
14      8195
15      1639
16      3278
17      0
18      0
19      0
20      0
Press any key to continue . . .

I przypominam dla porównania wyniki otrzymane na mojej maszynie:

Piotr Uchman napisał(a):

Dziwią mnie mocno wyniki. Oto one:

Liczba prob: 107437k
1       53723587
2       26854335
3       13395144
4       6754130
5       3326253
6       1686872
7       855750
8       440987
9       209834
10      100000
11      44264
12      24590
13      8197
14      8196
15      1639
16      3278
17      0
18      0
19      0
20      0
Press any key to continue . . .

Muszę skrobnąć to po zmianie generatora, zmiana kompilatora nie dała żadnych efektów.

hehej napisał(a):

a tak jeszcze w ramach tego improwizowania o losowaniu serii:

zamiast losować miliony razy i sprawdzać rnd() & 2, wystarczy przecież sprawdzać poszczególne bity z losowanej liczby, którą zwraca funkcja rnd.

Np. gdy mamy random, który produkuje 32 bity, wówczas mamy od razu - za jednym strzałem, aż 32 losowania z p = 0.5!

x = rand32(); // mamy 32 losowe bity, każdy z prawdop. p=0.5

for(i = 0; i < 32; i++, x >>= 1)
if( x & 1 ) hit++;
else koniec serii...

32 razy szybciej, a dla rand64 byłoby jeszcze 2 razy lepiej.

Zgodziłbym się, że 32 razy szybciej jeśli zawsze odbywałoby się losowanie 32 liczb. Zauważ, że specyfikacja problemu (jeśli trafimy zero koniec serii) jest taka, że statystycznie w połowie przypadków wystarczy wylosować jeden bit. Nawet przy moim mało wymagającym warunku końca (końcowy wynik otrzymujemy po wylosowaniu 10001 serii po 10 czerwonych/jedynek z rzędu) liczba losowań wynosi ponad 107 mln. W 53 mln prób wystarczyło wylosować jeden bit, w 93 mln prób wystarczyło wylosować 3 bity. Czy losowanie za każdym razem 32 bitów byłoby szybsze jeśli prawdopodobieństwo wystąpienia 1 na końcu jest tak ekstremalnie małe (1/(2^32)?

Jak będę miał chwilę albo znów pocierpię na bezsenność to przepiszę przy użyciu innego generatora i pochwalę się Panowie.

1
Piotr Uchman napisał(a):

32 razy szybciej, a dla rand64 byłoby jeszcze 2 razy lepiej.

Zgodziłbym się, że 32 razy szybciej jeśli zawsze odbywałoby się losowanie 32 liczb. Zauważ, że specyfikacja problemu (jeśli trafimy zero koniec serii) jest taka, że statystycznie w połowie przypadków wystarczy wylosować jeden bit. Nawet przy moim mało wymagającym warunku końca (końcowy wynik otrzymujemy po wylosowaniu 10001 serii po 10 czerwonych/jedynek z rzędu) liczba losowań wynosi ponad 107 mln. W 53 mln prób wystarczyło wylosować jeden bit, w 93 mln prób wystarczyło wylosować 3 bity. Czy losowanie za każdym razem 32 bitów byłoby szybsze jeśli prawdopodobieństwo wystąpienia 1 na końcu jest tak ekstremalnie małe (1/(2^32)?

p = 1/2^32 -> to jest prawdopodobieństwo wylosowania zera w ramach random32.

x = rand32(); // full 32 bity!
czego nie spełnia standardowy random z c, bo tam RAND_MAX = 2^15-1, czyli short int zaledwie - 15 bitów tylko.

Np. ten xor128 produkuje 32 bity losowe w jednym strzale.

0

RAND_MAX=32767 od Visual studio :).
RAND_MAX=2147483647 u konkurencji.
Przy czym wartość ta, nie jest zdefiniowana przez standard i może być różna dla każdego kompilatora (implementacji biblioteki standardowej), a nawet dla danej platformy (kompilator może obsługiwać kilka platform).

0
hehej napisał(a):

mamy od razu - za jednym strzałem, aż 32 losowania z p = 0.5!

odważne stwierdzenie biorąc pod uwagę, że wyżej masz dowód na to, że w rzeczywistych generatorach bywa inaczej.

2

random(2) = 0 -> bit 0
random(2) = 1 -> bit 1
wyjdzie po 50% - zawsze !!!

@hehej A zdajesz sobie sprawę, że prawdopodobieństwo, że przy 100 rzutach monetą, 50 to będzie reszka, a 50 to będzie orzeł - wynosi 8% ?

0
tr napisał(a):

random(2) = 0 -> bit 0
random(2) = 1 -> bit 1
wyjdzie po 50% - zawsze !!!

@hehej A zdajesz sobie sprawę, że prawdopodobieństwo, że przy 100 rzutach monetą, 50 to będzie reszka, a 50 to będzie orzeł - wynosi 8% ?

Nie wiem, czy aż tak mało - to byłby już rozkład Gaussa (prawie).

Ale średnia będzie blisko 0.5; z rozrzutem chyba około 1/sqrt(N), co daje aż 0.1 dla 100, czyli faktycznie sporo.
Dla N = milion rozrzut byłby 0.001, czyli dużo mniejszy.

0

konkretnie:

losowanie n razy z prawdopodobieństwem 50% sukcesu daje: q = p = 0.5 z prawdopodobieństwem:

2^n = liczba możliwych kombinacji, czyli to jest zwyczajna liczba binarna o długości n bitów.

a nas interesuje przypadek:
p = q, co znaczy że liczby bitów 1 i 0 w tej liczbie mają być równe, np. 8 i 8 dla 16 bitów, albo 16 zer i 16 jedynek dla 32 bitowych.

zatem należy wyliczyć ile jest takich liczb:

  • dla n = 2 są dwie takie liczby: 10 i 01, czyli 2 sztuki spośród 2^2 = 4, co daje prawdopodobieństwo: 2/4 = 1/2
  • dla n = 4 mamy trochę więcej takich kombinacji: 0011, 0101, 1001, 0110, 1010, 1100, razem 6, zatem teraz mamy: 6/2^4 = 6/16 = 3/8
  • dla n = 6: ...
    ...

n = 100 -> ? :)

0
hehej napisał(a):
tr napisał(a):

random(2) = 0 -> bit 0
random(2) = 1 -> bit 1
wyjdzie po 50% - zawsze !!!

@hehej A zdajesz sobie sprawę, że prawdopodobieństwo, że przy 100 rzutach monetą, 50 to będzie reszka, a 50 to będzie orzeł - wynosi 8% ?

Nie wiem, czy aż tak mało - to byłby już rozkład Gaussa (prawie).

Ale średnia będzie blisko 0.5; z rozrzutem chyba około 1/sqrt(N), co daje aż 0.1 dla 100, czyli faktycznie sporo.
Dla N = milion rozrzut byłby 0.001, czyli dużo mniejszy.

Aż tak mało, dokładnie 7.96%.

0

Nie wiem co jest nie tak z generatorami liczb pseudolosowych w C++, to już któryś watek ostatnio, sprawdziłem, w Pythonie z biblioteką rand wyniki wyglądają na w pełni losowe.
Może pora zaportować pythonowe rand do C++ :)). Kod:

# rulette symulation, black and white series only, no zero field
# 4programmers: https://4programmers.net/Forum/C_i_C++/315890-dziwne_wyniki_losowania_czy_
# tak_powinno_byc_orzelreszka_czarne_czerwone?p=1528153#id1528153

import random
from collections import Counter

def series():
    ctr = 1
    rand = [1]
    while rand == [1]:
        rand = random.sample(range(2), 1)
        ctr += 1
    return ctr

def symulation(n):
    r = []
    for _ in range(n):
        r.append(series())
    return r

series to Twoje symulation, a symulation, to oddtworzenie Twojego spaghetti z main:) Pora na wyniki:

s = symulation(1000000)
r = Counter(s)
r.most_common()  '''-> [(2, 500245),
 (3, 249715),
 (4, 124887),
 (5, 62667),
 (6, 31090),
 (7, 15692),
 (8, 7945),
 (9, 3856),
 (10, 1935),
 (11, 962),
 (12, 496),
 (13, 256),
 (14, 128),
 (15, 56),
 (16, 33),
 (17, 19),
 (18, 9),
 (20, 3),
 (19, 3),
 (22, 2),
 (25, 1)]'''

Dla Twojego 13 i 14 wyszły akurat wyniki 256 i 128, jak w teorii:)

0
lion137 napisał(a):

Nie wiem co jest nie tak z generatorami liczb pseudolosowych w C++, to już któryś watek ostatnio, sprawdziłem, w Pythonie z biblioteką rand wyniki wyglądają na w pełni losowe.
Może pora zaportować pythonowe rand do C++ :)). Kod:

Ja też nie mam pojęcia co oni tworzą. :)

Moje wyniki są perfekcyjne - na dowolnym generatorze.
W tym i te z fantastyki kwantowej pt. EPR-Bell, co tu kiedyś serwowałem.

Pewnie są to objawy jakiegoś generalnego zboczenia uniwersyteckiego, w które wpadła cywilizacja kilkadziesiąt lat temu. :)

lion137 napisał(a):

Aż tak mało, dokładnie 7.96%.

może nie zupełnie dokładnie:

p(50 i 50) = 0.07958923738717876149812705024217 wedle kalkulatora z windows. :)

0
lion137 napisał(a):

Oto przykład idiomatycznego kodu.

import itertools
import random
from collections import Counter
 
def series():
    for i in itertools.count():
        if random.randrange(2) == 0:
            return i
 
def simulation(n):  # simulation, not symulation
    return Counter(series() for _ in range(n))     # w ten sposób rozwiązanie jest także oszczędne pamięciowo, nigdy nie przechowujemy całej listy

1 użytkowników online, w tym zalogowanych: 0, gości: 1