natofp Temat założony przez niniejszego użytkownika |
Wyznaczanie przyblizenia liczby pi » 2017-10-13 08:31:47 Witam, probowalem wlasnie wyznaczyc liczbe pi w przyblizeniu metoda Monte Carlo. Program losuje punkty z pierwszej cwiartki ukladu wspolrzednych i sprawdza, czy naleza do kola o promieniu a. Pozniej dzieki temu wyznaczamy przyblizenie liczby pi.Kod wyglada nastepujaco: [ # include < iostream > #include <ctime>
using namespace std;
bool sprawdz() { int a = 100000; int y =( rand() %( a + 1 ) ); int x =( rand() %( a + 1 ) ); if((( x * x ) +( y * y ) ) > a * a ) return false; else return true; }
int main() { srand( time( NULL ) ); long long tab[ 1 ]; tab[ 0 ] = 0; for( int i = 0; i < 10000000; i++ ) { bool xd = sprawdz(); if( xd ) tab[ 0 ] ++; } cout << tab[ 0 ] * 4 << endl; return 0; }
I tu moje pytanie - dla 'a' z przedzialu okolo (0,1000) program przybliza liczbe pi do plus minus 3,1. Ma to sens, poniewaz dla malych danych program moze byc nieco niedokladny. Jesli jednak za 'a' przyjmiemy na przyklad 10000 to przyblizenie pi wynosi 3.27,a dla a=40000 pi wynosi 3.84, co kompletnie nie ma sensu. Blad powinien malec, im wiekszy przedzial losowania, a tutaj blad rosnie. Dlaczego tak sie dzieje? Bede wdzieczny za odpowiedz. |
|
mateczek |
» 2017-10-13 09:40:03 weź może poszukaj (bo ja nie robiłem) losowania liczb (long double) z przedziału od 0 do 1 i sprawdzaj przynależność do koła. Zostanie Ci wówczas tylko jeden parametr do analizy (ilość losowań) |
|
Monika90 |
» 2017-10-13 10:18:00 Największa wartość zwracana przez rand to RAND_MAX, a RAND_MAX zależy od implementacji i może być małe, np równe 32767, w takiej sytuacji rand() % 40001 nie ma sensu. Ale to nie wszystko, bo dla int a = 100000; a * a wychodzi poza maksymalny zakres int (w typowej implementacji gdzie int ma 32 bity). To oznacza że zachowanie twojego programu jest niezdefiniowane. Spróbuj raczej czegoś nieco nowszego: #include <iostream> #include <random> #include <limits>
int main() { std::mt19937 rnd; std::uniform_real_distribution < double > dist( - 1, 1 ); int trials = 0, inside = 0; while( trials < std::numeric_limits < int >::max() ) { ++trials; const auto x = dist( rnd ); const auto y = dist( rnd ); if( x * x + y * y <= 1 ) { ++inside; std::cout << trials << ' ' << 4.0 * inside / trials << std::endl; } } std::cout << "The end..." << std::endl; }
|
|
darko202 |
» 2017-10-13 14:18:59 |
|
mateczek |
» 2017-10-13 15:00:45 miast pola koła można policzyć na ćwiartce wycinka. Efekt ten sam |
|
natofp Temat założony przez niniejszego użytkownika |
» 2017-10-13 23:37:17 Mozna oczywiscie to obejsc w inny sposob, losujach liczby z przedzialu 0,1 lub losujac pelne kolo. Jednak mnie zastanawia, dlaczego ten program ma wiekszy blad dla wiekszych danych, (nie przekraczajacyh zakresu), kiedy blad powinien malec. Poza tym, rand max jest zdefiniowane jako maxymalny int. Pytanie dlaczego blad rosnie nadal pozostaje bez odpowiedzi... |
|
mateczek |
» 2017-10-14 08:00:42 nie obejść tylko rozwiązać w sposób prawidłowy !!! |
|
darko202 |
» 2017-10-16 08:57:28 1. pisał już o tym &[Monika90] zakres int -2'147'483'648 do 2'147'483'647
czyli jeśli losujemy jakiegoś int x, y który może mieć wartość do 10'000 to * x*x może mieć wartość 10 000 000 000 * y*y j.w. * suma x*x + y*y : j.w. * a*a = 10 000 000 000
czyli w warunku (( x * x ) +( y * y ) ) > a * a )
możesz mieć 4 przypadki przekroczenia zakresu
to jest pierwszy błąd, który ma Ten algorytm
2. to o czym pisałem jeśli badasz 1 ćwiartkę to zapominasz o mnożeniu przez 4
|
|
« 1 » |