[C] Programma metodo montecarlo/variabile senza ripetizione

di il
15 risposte

[C] Programma metodo montecarlo/variabile senza ripetizione

Salve a tutti,
volevo chiedere se qualche buon'anima potesse aiutarmi a scrivere un programma valido per la presentazione di un progetto sul " metodo Montecarlo ".
Sto scrivendo un programma basato sul gioco del BlackJack in cui l'utente inserisce il numero di carte da estrarre e le mani totali. Fatto ciò il programma calcola quante volte faresti 21.
Il problema è che non riesco a generare il vettore delle carte pescate senza che ci sia la ripetizione delle carte. Mi spiego meglio : il programma in sostanza non tiene conto del fatto che nel mazzo ci sono, ad esempio, massimo 4 carte che valgono 1 ( nel caso peschi un asso ). Nel programma c'è praticamente il " rischio " che peschi 6 volte l'asso ( ad esempio ) cosa che è evidentemente sbagliata.

Qualcuno potrebbe darmi una mano a risolvere questo problema?

Grazie in anticipo.

15 Risposte

  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    "Il programma non tiene conto" ... c'è già un programma, un codice? Vediamo dove sbagli ...


    P.S. Mi sembra che dovresti usare un titolo più adatto per il tuo thread.
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Ciao, grazie per la celere risposta, copio di seguito il programma.
    Premetto che è in corso di sviluppo quindi ci sono modifiche.
    ( consigli per il titolo?
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    int main ()
    {
    	int c[13], q[13], f[13], p[13], v[13], k[n]
    	int i,m,x,n,a,b,d,y,k,sum; 
    	for (i=1;i<11;i++)
    		{
    			c[i]=i;
    			q[i]=i;
    			f[i]=i;
    			p[i]=i;
    		}
    	for (i=11;i<14;i++)
    		{
    			c[i]=10;
    			q[i]=10;
    			f[i]=10;
    			p[i]=10;
    		}
    	a=0;
    	b=0;
    	d=0;
    	srand(time(NULL));
    	printf ("Inserisci il numero di carte da ricevere per ogni mano: ");
    	scanf ("%d", &n);
    	printf ("Inserisci il numero di mani che vuoi gicoare: ");
    	scanf ("%d", &m);
    	while (b<m)
    		{
    			sum=0;
    			k=0;
    			y=rand()%9+1;
    					if (y==10)
    						{
    							k++;
    							if (k>3)
    								{
    									summ=30;
    								}
    						}
    					else
    						{
    							u[n]=y; 
    								{
    									if(u[i]=y)
    										{
    											j++;
    										}
    									if(j=4)
    										{
    											y=rand()%12+1;
    											j--;
    										}
    									for(i=0;i<n;i++)
    										{
    											y=rand()%12+1;
    										}
    								}
    					
    					
    					sum=sum+y;
    					a++;
    					
    				}
    			if (sum==21)
    				{
    					d++;	
    				}
    			b++;
    		
    		}
    	printf ("Hai ottenuto BlackJack per %d volte \n\n", d);
    	system ("PAUSE");
    	return 0;
    }
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Il titolo deve dire qualcosa del problema, in maniera breve. Fai tu.

    Usa i tag CODE per racchiudere il codice nel forum altrimenti si fa fatica a leggerlo.

    Intanto vedo un po' di errori evidenti ... if(x=2) e simili ... da correggere
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Si scusa quella parte in commento penso sia essenzialmente inutile. Era il programma all'inizio dove tenevo conto anche dei semi ma è inutile.
    Adesso modifico e elimino
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Hai modificato? I tag CODE non ci sono ancora e ci sono ancora errori ... if(j=4)
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Non so cosa siano i tag code,
    ho modificato il programma copio di seguito :

    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    int main ()
    {
    	int v[12];
    	int a,b,d,i,j,m,n,y,k,sum; 
    	a=0;
    	b=0;
    	d=0;
    	for(i=0;i<12;i++)
    		{
    			v[i]=i+11;
    		}
    	srand(time(NULL));
    	printf ("Inserisci il numero di carte da ricevere per ogni mano: ");
    	scanf ("%d", &n);
    	printf ("Inserisci il numero di mani che vuoi gicoare: ");
    	scanf ("%d", &m);
    	if(n>12)
    		{
    			d=0;
    		}
    	else
    		{
    			if(n==1)
    				{
    					d=0;
    				}
    			else
    				{
    					while (b<m)
    						{
    							sum=0;
    							k=0;
    							j=0;
    							while (a<n)
    								{
    									y=rand()%9+1;
    									if (y==10)
    										{
    											k++;
    											if (k>3)
    												{
    													y=30;
    												}
    										}		
    									else
    										{
    											v[a]=y; 
    											for(i=0; i<12; i++)
    												{
    													if(v[i]==y) 
    														{
    															j++;
    														}
    													if(j==5)
    														{
    															y=rand()%9+1;
    															j--;	
    														}
    												}		
    										}
    									sum=sum+y;
    									if (sum==21)
    										{
    											d++;	
    										}
    									a++;
    								}
    							b++;
    						}	
    				}
    			
    		}	
    	printf ("Hai ottenuto 21 per %d volte \n\n", d);
    	system ("PAUSE");
    	return 0;
    }


    ( da risultato 0 qualsiasi dati metti )

    Grazie mille per l'aiuto
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Devi scrivere

    [/code]

    alla fine del codice e
    
    
    all'inizio
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Non penso il problema sia quello perché a scuola abbiamo sempre usato quell'intestazione e con gli altri programmi funziona. Usiamo DevCpp portable
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Per assicurarti di non avere carte duplicate, il trucco e' estremamente semplice:

    1) genere un vettore con le carte, creando una qualche mappa 1:1 tra i valori del vettore (as esempio degli interi) e le carte del mazzo
    2) mescoli il vettore: scambi tra di loro due indici generate ai caso, oppure per ogni indice, generi a caso un'altro indice con cui scambiare i valori.

    Banale.

    PS: CORREGGI i post precedenti: metti il codice DENTRO i tag Code!!!!!!!!
    Se no, non si capisce un'accidenti!
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Più facile dirlo che farlo



    Non so cosa sono i tag code
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Roberto Bellotti ha scritto:


    Non penso il problema sia quello perché a scuola abbiamo sempre usato quell'intestazione e con gli altri programmi funziona. Usiamo DevCpp portable
    Ma di che parli?
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Roberto Bellotti ha scritto:


    Non so cosa siano i tag code,
    ho modificato il programma copio di seguito :
    
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    int main ()
    {
    	int v[12];
    	int a,b,d,i,j,m,n,y,k,sum; 
    	a=0;
    	b=0;
    	d=0;
    	for(i=0;i<12;i++)
    		{
    			v[i]=i+11;
    		}
    	srand(time(NULL));
    	printf ("Inserisci il numero di carte da ricevere per ogni mano: ");
    	scanf ("%d", &n);
    	printf ("Inserisci il numero di mani che vuoi gicoare: ");
    	scanf ("%d", &m);
    	if(n>12)
    		{
    			d=0;
    		}
    	else
    		{
    			if(n==1)
    				{
    					d=0;
    				}
    			else
    				{
    					while (b<m)
    						{
    							sum=0;
    							k=0;
    							j=0;
    							while (a<n)
    								{
    									y=rand()%9+1;
    									if (y==10)
    										{
    											k++;
    											if (k>3)
    												{
    													y=30;
    												}
    										}		
    									else
    										{
    											v[a]=y; 
    											for(i=0; i<12; i++)
    												{
    													if(v[i]==y) 
    														{
    															j++;
    														}
    													if(j==5)
    														{
    															y=rand()%9+1;
    															j--;	
    														}
    												}		
    										}
    									sum=sum+y;
    									if (sum==21)
    										{
    											d++;	
    										}
    									a++;
    								}
    							b++;
    						}	
    				}
    			
    		}	
    	printf ("Hai ottenuto 21 per %d volte \n\n", d);
    	system ("PAUSE");
    	return 0;
    }
    


    ( da risultato 0 qualsiasi dati metti )

    Grazie mille per l'aiuto
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Le paroline magiche per questo genere di applicazioni sono "shuffle" e "Knuth". Si veda qui, ma soprattutto il lungo thread referenziato all'inizio del post.

    Vale anche la pena di riportare per l'ennesima volta una nota che troppo spesso viene trascurata.
    L'algoritmo di shuffle “di Knuth” è stato pubblicato per la prima volta nella sua forma attuale, com'è ben noto, da R. Durstenfeld (R. Durstenfeld, "Algorithm 235: Random permutation", Communications of the ACM 7 (1964), no. 7, 420). L'attribuzione “shuffle di Fisher e Yates” invece non è universalmente accettata senza discussioni, come molte fonti online paiono erroneamente ritenere (o, peggio, vorrebbero far credere).
    L'originale algoritmo pubblicato nel 1938 da Ronald Fisher e Frank Yates, semplicemente, non era computabile e non si basava in modo specifico sull'aumento di efficienza dell'operazione di cancellazione da un array (realizzata in O(1) tramite un semplice scambio con l'ultimo elemento e la riduzione di una unità della dimensione dell'array, per le mosse successive). Poiché esattamente in questa idea consiste l'asse portante dell'algoritmo e la chiave del suo successo applicativo, molti rifiutano la prassi di “cointestare” l'algoritmo stesso e considerano unicamente la pubblicazione di Durstenfeld come l'atto di nascita di tale procedura di shuffle in senso strettamente informatico: senza per questo voler togliere a Fisher e Yates una doverosa menzione (magari in una nota o commento) e senza sminuire in alcun modo i loro meriti. Meriti che peraltro sono e rimangono numerosi, anche in campo discretistico: a partire dai loro contributi allo studio dei block designs, dei quali rimane traccia ancor oggi nel fatto che la cardinalità dell'insieme degli elementi in un BD è curiosamente indicata con la lettera v, a memoria dell'originale “varieties of wheat” di cui si occupavano i due ricercatori; per non dire della notissima disuguaglianza di Fisher per i block designs BIBD, intuitiva quanto fondamentale: in ogni (v,b,r,k,lambda)-BIBD, il numero dei blocchi b è sempre non minore del numero v di elementi dell'insieme di scelta.


    Nota di moderazione: Per questa volta sono intervenuto personalmente a modificare i vari messaggi per inserire i tag CODE. Naturalmente ci si aspetta che l'OP impari ad usarli per il futuro.
  • Re: [C] Programma metodo montecarlo/variabile senza ripetizione

    Continuo a non riuscire a farlo funzionare anche perche non ho capito una mazza della sua risposta ( perche non capisco io non perché non sia chiaro).
    Mi scuso per gli errori di pubblicazione, non capivo bene come funzionasse essendo nuovo.

    Volevo dire che sono un ragazzo di 5° superiore di un liceo scientifico scienze applicate ( faccio due ore di informatica alla settimana ma mi piace molto come materia ), quindi non ho moltissime conoscenze.
    Grazie dell'aiuto
Devi accedere o registrarti per scrivere nel forum
15 risposte