Categories: Programmazione

Numeri Casuali nei Programmi di Simulazione

I modelli di rappresentazione di eventi reali vengono definiti in base ad alcune loro caratteristiche come: statici o dinamici, continui o discreti, deterministici o stocastici. La differenza tra un evento deterministico ed uno stocastico è che nel primo caso ogni evento è determinato da un causa o serie di cause che si verificano contemporaneamente o in sequenza temporale, mentre nel secondo un evento è determinato da una causa o insieme di cause come effetto casuale che si realizza con una certa probabilità ed in alternativa ad effetti diversi aventi proprie probabilità di realizzazione. Spesso si ricorre al metodo stocastico per descrivere un sistema complesso che nella realtà è deterministico, basti pensare alla meccanica statistica che determina le proprietà degli oggetti macroscopici come conseguenza delle proprietà di quelli microsocopici che li compongono.
Per realizzare un programma di simulazione molti linguaggi e librerie mettono a disposizione un generatore di numeri casuali.

dk = ((double)rand())/RAND_MAX;

Questa istruzione assegna alla variabile dk di tipo double un valore casuale uniformemente distruibuito nell’intervallo tra 0 ed 1. Nel caso si voglia simulare il lancio di una moneta dovremmo porre tra 0.00 e 0.50 per “testa” e 0.51 e 1.00 per “croce”, in questo modo possiamo simulare la probabilità scaturita dai lanci.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char** args)
{
   srand((unsigned int)time(NULL));

   int nTesta = 0;
   int nCroce = 0;
   int nLanci = 2564;
   double dk;

   for (int i = 0; i < nLanci; ++i)
   {
      dk = ((double)rand()) / RAND_MAX;
      if (dk <= .5)
         ++nTesta;
      else
         ++nCroce;
   }

   dk = ((double)(nTesta * 100)) / nLanci;
   printf("Testa: %.2f\n", dk);
   dk = ((double)(nCroce * 100)) / nLanci;
   printf("Croce: %.2f\n", dk);

   scanf_s("0");

   return 0;
}

Questa tecnica è nota come “Metodo di Monte-Carlo”, infatti veniva utilizzata negli anni ’40 che in assenza di calcolatori, si ricorreva alle registrazioni delle uscite alla roulette del casinò di Monte-Carlo. Questa tecnica di simulazione stocastica coinvolge due possibili esiti, quindi p1 è sicuramente pt – p2. Non sempre un evento ha solo due possibili esiti, pensiamo per esempio al caso del lancio di un dado con sei facce e quindi sei esiti distinti. Come sapete dalla statistica i sei valori del dado hanno tutti la stessa probabilità d’uscita ( equiprobabili ), ma anche questa situazione non è sempre vera in un evento stocastico nel quale si possono presentare esiti diversi, anche se il totale deve essere sempre 1, questa è la dichiarazione di una variabile aleatoria discreta finita.
Se vogliamo applicare il metodo di “Monte-Carlo” al lancio di un dado dobbiamo suddividere le probabilità tra 0 ed 1, quindi (0,1/6) (1/6,1/3) (1/3, 1/2) (1/2, 2/3) (2/3,5/6) (5/6, 1), gli estremi superiori di questi intervalli rappresentano le cosiddette probabilità cumulate di ciascun evento, definite come la somma delle probabilità associate a tutti gli eventi di valore inferiore più la probabilità relativa all’evento considerato. Se mettessimo due dadi invece di uno dovremmo considerare 12 probabili valori ( 36 se non consideriamo la somma ) e quindi iniziare da (0, 1/12) (1/12, 1/6) (1/6, 1/4) … con questo ragionamento potremmo simulare anche il caso di n dadi, ma vi evito questo caso dal punto di vista del codice sorgente. Prendiamo invece l’esempio di un simulatore di estrazioni, 6 su 90 numeri per fare un esempio classico.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char** args)
{
   srand((unsigned int)time(NULL));

   int k, j;
   bool bFound;
   int pu[] = { 0, 0, 0, 0, 0, 0 };

   int u = 0;
   while (u < 6)
   {
       k = rand() % 90 + 1;
       bFound = false;
       for (j = 0; j < 6; ++j)
      {
           if (pu[j] == k)
          {
              bFound = true;
 break;
           }
      }
      if (!bFound)
      {
           pu[u] = k;
            ++u;
       }
   }

   printf("Estrazione: %d %d %d %d %d %d\n",
      pu[0], pu[1], pu[2], pu[3], pu[4], pu[5]);

   scanf_s("0");

   return 0;
}

Partendo da questo punto potremmo fare tutte le estrazioni che vogliamo e calcolare quindi la probabilità d’uscita di un numero.

Share
Giampaolo Rossi

Sviluppatore di software gestionale da oltre 28 anni.

Recent Posts

Un Abbonamento per Tutti i Software

Sono arrivato alla convinzione che un abbonamento per tutti i miei software gestionali sia il…

1 anno ago

Software di Magazzino Gratuito

MerciGest è un software per la gestione del magazzino completamente gratuito. Continua a leggere→

1 anno ago

Mettere il PC in Lock Screen

In ufficio può capitare di doversi allontanare dal proprio posto di lavoro, ecco che allora…

3 anni ago

Fare il reset togliendo la corrente

In questo articolo vedremo quando è più o meno utile togliere la corrente ad un…

3 anni ago

Prossimi Aggiornamenti Software

Dopo la pausa invernale dovuta al lavoro che devo fare per sostentarmi, eccomi di nuovo…

3 anni ago

Come Eliminare i Files in Windows

Vediamo come eliminare i files direttamente da Windows senza utilizzare il cestino. Continua a leggere→

4 anni ago