E la probabilità?, Simulazioni in C

« Older   Newer »
  Share  
Elemento 38
view post Posted on 8/5/2010, 14:43




Buon giorno a tutti :)
Apro questa discussione per parlare di probabilità. Ovviamente, dato anche che questa è la sezione Informatica, il tutto si svilupperà attraverso simulazioni con programmi in C.
Il primo esperimento di cui parlo è il seguente e "serve" per tirare fuori da qualche calcolo il Pi Greco. Immaginiamo di avere un quarto di cerchio di raggio 1. Immaginiamo poi che questo quarto di cerchio sia "chiuso" su un quadrato anch'esso di lato 1. Figura:
image
Immaginiamo ora di "sparare" a caso dei proiettili su questa figura. La probabilità di sparare un proiettile dentro l'area del quarto di cerchio è data dalla formula casi favorevoli/casi totali , quindi area del quarto di cerchio/area del quadrato.
Facendo i calcoli, la probabilità di questo avvenimento tende a piGreco/4. Noi ora possiamo provare a simulare questi proiettili con un programma in C e vedere se davvero riusciamo a trovare un numero che tende a piGreco.

Il programma è abbastanza semplice (se avete domande sarò ben lieto di rispondervi :) ), chiede di inserire il numero di lanci che si vuole effettuare e dopo estrae per ogni lancio due numeri, x e y, compresi tra 0 e 1. Attraverso l'equazione del cerchio(dato che siamo in una circonferenza goniometrica x2+y2=1) e le coordinate x e y estratte riusciamo a capire se il punto appartiene o no al cerchio. Se si viene incrementato un contatore. Notare che è stato implementato anche un file di uscita del programma che contiene per ogni lancio il valore di piGreco calcolato. Attraverso questo file ho fatto questo grafico per dare un'idea di cosa succede (ascisse->lancio n° ordinate->valore di piGreco).
image
In allegato il file .cpp con il programma.
NOTA: il programma è abbastanza veloce, ma per numeri di laci superiori alle 800000, ci vuole qualche secondo per permettere al PC di lavorare. E' probabile che il programma non accetti numeri troppo grandi (superiori al miliardo) per problemi di lunghezza delle variabili. Il file di uscita è abbastanza semplice e dato che non è compresso pesa abbastanza(circa 1 MB per 40000 lanci). Se volete graficare i valori non fate estrarre al PC più di 32000 lanci, Excel non supporta righe in più ;)

Edited by Elemento 38 - 14/5/2010, 17:26

Download attachment
Pi_main.cpp ( Number of downloads: 109 )

 
Top
view post Posted on 8/5/2010, 14:50
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


interessante...voglio leggere bene con calma!
 
Top
Elemento 38
view post Posted on 8/5/2010, 17:16




Ho provato ad andare un po' su con i numeri e vedere quanto si avvicina al numero piGreco. Ecco una schermata con qualche esempio
image

Ho anche provato ad aggiungere un altro zero, ma il computer poi si è impallato :lol: Con 100000000 di lanci estratti il file di uscita è di 2,03GB e ci ha messo tipo 12 minuti (volevo mettere anche un conteggio per il tempo, ma con più di due minuti iniziava a sballare :wacko: )
 
Top
OzzFan
view post Posted on 9/5/2010, 00:36




ele te che sei un genio di matematica mi daresti ripetizioni? io non ci capisco nulla a riguardo e mi sento proprio inutile...

comunque è interessante questa cosa non è che tra qualche anno zio bill ti chiama in casa microsoft!??! :P
 
Top
Elemento 38
view post Posted on 9/5/2010, 07:31




Vé che non sono un genio della matematica :P Queste cose le insegnano in molte scuole :lol:
E poi il programma è una stupidata, si potrebbe fare molto meglio eheh

Edited by Elemento 38 - 9/5/2010, 09:50
 
Top
gyppe
view post Posted on 12/5/2010, 16:53




Mi piacciono parecchio questi esperimenti così ho provato anche io, però ho dovuto installare le conio che su linux non ci sono :) Come mai per la chiamata a funzione hai dichiarato int la variabile? Così non mi compilava.

Non so perchè ha con 8 zeri l'ha risolto molto in fretta, pochi secondi, con 9 mi ha invece dato:

Inserisci il numero di lanci da effettuare(0 per uscire):
1000
Valore probabilistico di Pi Greco: 3.132000
Inserisci il numero di lanci da effettuare(0 per uscire):
100000
Valore probabilistico di Pi Greco: 3.142480
Inserisci il numero di lanci da effettuare(0 per uscire):
1000000
Valore probabilistico di Pi Greco: 3.141564
Inserisci il numero di lanci da effettuare(0 per uscire):
10000000
Valore probabilistico di Pi Greco: 3.140952
Inserisci il numero di lanci da effettuare(0 per uscire):
1000000000
Valore probabilistico di Pi Greco: 3.141605
Inserisci il numero di lanci da effettuare(0 per uscire):

Ci si comincia ad avvicinare, ora sto provando con 10, sicuramente dovrebbe riuscire visto che anche con 9 non ha occupato per niente memoria ma solo cicli macchina.
 
Top
Elemento 38
view post Posted on 12/5/2010, 17:11




CITAZIONE
Come mai per la chiamata a funzione hai dichiarato int la variabile? Così non mi compilava.

Ho notato adesso che l'avevo lasciato, comunque non dovrebbe dare problemi, massimo un warning che dice che non riesce a fre il cast tra un int e un int :) Però è strano, a me lo compila senza problemi ...
Comunque è stato un errore, mi sa che c'è rimasto perchè prima avevo provato ad usare gets invece che scanf, mah... :unsure:
Sono contento ti interessi, ne ho ancora qualcuno di questi esperimenti, ora che ho un seguace li posto tutti :lol:
 
Top
Elemento 38
view post Posted on 12/5/2010, 18:06




Spero che però hai commentato le righe che creano il file di output, se no c'è un po' si spazzatura da qualche GB nella cartella del programma :lol:
Comunque una cosa in più: all'inizio del programma, sotto le dichiarazione delle variabili ci starebbe uno srand(time(NULL)); per inizializzare il generatore di numeri casuali con numeri sempre diversi ;)
 
Top
gyppe
view post Posted on 12/5/2010, 18:27




Qui sta ancora a calcolare :O Mi sa tanto che non mi basterà l'hd per salvare quel popò di file che salterà fuori, avrei dovuto davvero levarlo caspita :D

Piuttosto perchè non torniamo sulla crittografia? Ora ho il compilatore pronto, su linux è una goduria smanettare in programmazione visto che hai tutto pronto, addirittura la controparte di notepad ti evidenzia automaticamente la sintassi di qualsiasi tipo di linguaggio :) Compilatore migliore al mondo preinstallato, per installare un ide poi.... 5 minuti e non serve neppure aprire firefox per cercarlo.

 
Top
Elemento 38
view post Posted on 12/5/2010, 19:32




CITAZIONE (gyppe @ 12/5/2010, 19:27)
Qui sta ancora a calcolare :O Mi sa tanto che non mi basterà l'hd per salvare quel popò di file che salterà fuori, avrei dovuto davvero levarlo caspita :D

Piuttosto perchè non torniamo sulla crittografia? Ora ho il compilatore pronto, su linux è una goduria smanettare in programmazione visto che hai tutto pronto, addirittura la controparte di notepad ti evidenzia automaticamente la sintassi di qualsiasi tipo di linguaggio :) Compilatore migliore al mondo preinstallato, per installare un ide poi.... 5 minuti e non serve neppure aprire firefox per cercarlo.

Si si io ci sono :)

Bisognerebbe ritornare alla vecchia discussione e decidere su cosa lavorare :) (si programmaerà in C/C++, giusto :unsure: ? )

Edited by Elemento 38 - 13/5/2010, 21:00
 
Top
gyppe
view post Posted on 13/5/2010, 16:26




Azz vero la vecchia discussione, tu eri andato anche abbastanza avanti, se non sbaglio vigenere lo avevi già risolto, ora vado a vedere.
Si come linguaggio direi C.
 
Top
Elemento 38
view post Posted on 13/5/2010, 19:44




Ecco un'altra interessante simulazione :)
Scommettereste che in un gruppo di 50 persone, ad esempio, due persone qualsiasi compino gli anni lo stesso giorno ??
Io si :)
Ho provato a far simulare al computer la probabilità che si ha che in un gruppo di persone(che va da 2 a 365, non ho contato che uno può essere nato il 29 febbraio) ce ne siano almeno due che hanno il compleanno nello stesso giorno :)
Ecco il grafico della probabilità (ascisse->numero di persone; ordinate->probabilità) e il listato del programma, a domani con la spiegazione del calcolo ;)
image
Commento veloce veloce: ad un certo punto, mettiamo verso le 70 persone, la probabilità sale a 1. In realtà non è vero, solo che è un numero talmente vicino a 1 che anche usando un float come variabile non si riesce ad avere abbastanza precisione per distinguere il numero da 1. Ergo, è un numero tipo 0,999999999999999987 :)

Download attachment
Comple_main.cpp ( Number of downloads: 63 )

 
Top
Elemento 38
view post Posted on 14/5/2010, 13:41




Proviamo a dare una spiegazione alla cosa :)
Allora per calcolare la probabilità che due persone NON compiano gli anni lo stesso giorno dell'anno basta usare la solita formula della probabilità

E quindi la probabilità che due pensone compiano gli anni lo stesso giorno è data da

Se abbiamo tre persone basta moltiplicare la probabilità che tre persone non compiano gli anni nello stesso giorno e sottrarre il risultato da 1

E così via ...
:)
 
Top
Elemento 38
view post Posted on 14/5/2010, 16:20




Altra simulazione. Il gioco di Monty Hall :)
Cit, da Wikipedia(che probabilmente spiega meglio di me :P )

Il problema di Monty Hall è un famoso problema di teoria della probabilità, legato al gioco a premi americano Let's Make a Deal. Il nome viene da quello del conduttore dello show, Maurice Halprin, noto con lo pseudonimo di Monty Hall.

Nel gioco vengono mostrate a un giocatore tre porte chiuse; dietro una c'è un'automobile e ciascuna delle altre due nasconde una capra. Al giocatore è permesso aprire una porta, vincendo ciò che c'è dietro. Dopo che il giocatore ha selezionato una porta, ma non l'ha ancora aperta, il conduttore dello show, che conosce ciò che si trova dietro ogni porta, apre una delle altre due, rivelando una delle due capre, e offre al giocatore la possibilità di cambiare la propria scelta iniziale, passando all'unica porta restante.

Passare all'altra porta migliora le chance del giocatore di vincere l'automobile?


La risposta è si, e probabilmente la saprete già perchè questo gioco è stato riproposto in moltissimi film&telefilm, per esempio Numbers e 21-Fate il vostro gioco.
In fondo al 3d il listato con il programma. E' relativamente semplice, con uno scanf([...]) si chiede all'utente il numero di partite che vuole giocare e poi il programma per ogni partita estrae in che porta deve essere la macchina(random+switch iniziale). Viene poi estratto un altro numero che identifica che porta ha scelto il giocatore e a seconda di dove si trova la macchina viene aumentata la variabile cambia se cambiando il giocatore sceglie la macchina, o n_cambia se cambiando il giocatore vince la capra.
Come si può facilmente vedere la probabilità è del 66% (circa) e non del 50% come si sarebbe portati a pensare. Questo diagramma di Venn spiega bene il perchè la probabilità è dei 2/3 invece che dell'1/2:
image

NOTA1: come si estraggono numeri random INTERI. Il modo per estrarre numeri random interi che ho usato nel mio programma è quello di fare estrarre al PC un numero tra 0 e RAND_MAX (di default 32625 mi pare) e poi fare l'operazione %(modulo) con il numero massimo da estrarre nel mio caso:
n = rand()%­3;
dà fuori un numero da 0 a 2, perchè l'operazione modulo calcola il resto della divisione tra rand() e 3 (che può essere solo 0,1,2).
NOTA2: una cosa dove ho sbattuto la testa per una mezz'oretta, come stampare il simbolo di percentuale con la printf([...]). L'unico modo è fare seguire il %d, %f, %b o quale altra cosa sia con 2 simboli di percentuale, ad esempio %f%%.

Download attachment
main_treporte.cpp ( Number of downloads: 66 )

 
Top
gyppe
view post Posted on 15/5/2010, 18:21




Vedo che i numeri ti piacciono proprio :)
 
Top
31 replies since 8/5/2010, 14:43   545 views
  Share