Advertisement
pin65

Probabilità di somme di dadi anche 'arbitrari'

Feb 26th, 2015
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.70 KB | None | 0 0
  1. <?php
  2. // Il codice può essere eseguito qui:
  3. // http://www.tutorialspoint.com/execute_php_online.php
  4. //
  5. // Dato i valori presenti sulle facce di un dado e il numero di lanci
  6. // (o di dadi lanciati contemporaneamente) il codice determina tutte
  7. // le possibili somme ottenibili e le loro probabilità.
  8. //
  9. // Costanti
  10. define ("CRLF", "\n");   //  "\n" o "<br>" (accapo)
  11. define ("DEBUG", 0);     //  0, 2, 5, 10 (0 = no Debug mode)
  12. //
  13. // * Variabili (dati del problema) *
  14. // Vettore con i valori delle facce del dado
  15. // Le facce possono avere un numero di facce variabile con valori anche
  16. // ripetuti o non sequenziali (es [0,4,5,5])
  17. $dado = array(0,0,1,2,3,4);
  18. // Numero di dadi (o di lanci)
  19. $numeroDadi = 5;
  20. //
  21. // * Funzioni *
  22. //
  23. // Funzione ricorsiva che calcola le probabilità delle somme di (0..n) dadi
  24. // - gli indici di vecValoriEProb sono i numeri presenti sulle facce (se si ripetono vengono presi una volta sola)
  25. // - i valori di vecValoriEProb indicano la probabilità relativa al valore indice.
  26. // Per calcolare tutte le somme di un dado di 5 valori (0,1,2,3,4) eseguirà 155 cicli
  27. // (1*5 + 5*5 + 9*5 + 16*5 cicli, vale a dire 5 + 25 + 45 + 80)
  28. function calcProbSomme($vecValoriEProb, $numeroDadi) {
  29.   if ($numeroDadi > 0) {
  30.     $vecProbSommePrec = calcProbSomme($vecValoriEProb, $numeroDadi-1);         // La funzione si richiama ricorsivamente
  31.     if (DEBUG >= 5)  { print_array("Prec: ", $vecProbSommePrec); }
  32.     $vecProbSomme = array();
  33.     // Scandisco tutte le somme già ottenute sommando alle stesse tutti i possibili valori di un dado
  34.     // Esempio: al primo dado ho solo la somma "0", con probabilità 1; se sommo un 1 con probabilità 1/6 ne
  35.     // consegue una nuova somma "1" con probabilità 1*1/3
  36.     // Ciclo che scandisce le 'somme precedenti'
  37.     foreach($vecProbSommePrec as $s0 => $p0) {
  38.       if (DEBUG >= 5) { echo "Somma ". $s0 . " prob. " . $p0 . CRLF; }
  39.       // Ciclo che somma, uno per uno, i vari valori del dado e determina le probabilità di ciascuna somma
  40.       // NOTA: le probabilità di 0+3 o 1+2 o 2+1 o 3+0 andranno tutte a sommarsi nell'elemento '3' del vettore delle probabilità
  41.       foreach($vecValoriEProb as $vf => $pv) {
  42.         if (empty($vecProbSomme[$s0 + $vf])) { $vecProbSomme[$s0 + $vf] = 0; }      // creo il nuovo elemento se non c'è ancora
  43.         // $s0 (somma precedente); $vf (valore faccia); $p0 (probabilità di somma prec); $pv (probabilità del valore faccia)
  44.         $vecProbSomme[$s0 + $vf] = $vecProbSomme[$s0 + $vf] + $p0 * $pv;
  45.       }
  46.     }  
  47.     if (DEBUG >= 5) { print_array("Post: ", $vecProbSomme); }
  48.   } else {
  49.     // nunero dadi = 0 - inizializzo il vettore delle somme (l'unica somma possibile è 0, con probabilità 1) e lo ritorno
  50.     $vecProbSomme = array();
  51.     $vecProbSomme[0] = 1;   // solo il valore 0 ha probailità 1 all'inizio
  52.   }
  53.   if (DEBUG >= 5) { echo("calcProbSomme - Dado " . $numeroDadi . CRLF); }
  54.   return $vecProbSomme;
  55. }
  56. //
  57. // Funzione che elenca gli elementi di un vettore di tipo indice => valore
  58. function print_array($titolo, $a) {
  59.   echo(CRLF . $titolo . CRLF);
  60.   foreach($a as $i => $v) {
  61.     echo($i . " [" . number_format($v, 3) . "]" . CRLF);
  62.   }
  63.   echo CRLF;
  64. }
  65. //
  66. // * Main *
  67. //
  68. $probSomme = array();       // raccoglie le probabilità delle somme possibili
  69. $probValoreFacce = array();
  70. //
  71. echo("**** Calcolo probabilità di somme di dadi 'arbitrari' ****" . CRLF . CRLF);
  72. if (DEBUG > 0) {echo("Modo DEBUG = " . DEBUG . CRLF); }
  73.  
  74. // le dacce sono equiprobabili (i valori no, se appaiono su più facce)
  75. $facceDado = count($dado);
  76. $probFacciaDado = 1 / $facceDado;
  77.  
  78. // Calcolo probabilità di ciascun valore
  79. for($x = 0; $x < $facceDado; $x++) {
  80.     $prob0=0;
  81.     if (!empty($probValoreFacce[$dado[$x]])) {
  82.       $prob0 = $probValoreFacce[$dado[$x]];
  83.     }
  84.     $probValoreFacce[$dado[$x]] = $prob0 + $probFacciaDado;
  85. }
  86.  
  87. // Mostra facce del dado (se true)
  88. if (DEBUG >= 2) {
  89.   echo("Facce del dado" . CRLF);
  90.   foreach($dado as $x => $x_value) {
  91.     echo( "Faccia: " . $x . ", Valore: " . $x_value . CRLF);
  92.   }
  93. }
  94.  
  95. // Mostra probabilità dei valori (unici) delle facce (se true)
  96. if (DEBUG >= 2) {
  97.   echo(CRLF);
  98.   echo("Probabilità dei valori delle facce del dado" . CRLF);
  99.   foreach($probValoreFacce as $x => $x_value) {
  100.     echo("Valore: " . $x . ", Probabilità: " . $x_value . CRLF);
  101.   }
  102.   echo(CRLF);
  103. }
  104.  
  105. // Calcola le probabilità di ciascuna somma ottenibile riportando un
  106. $probSomme = calcProbSomme($probValoreFacce, $numeroDadi);
  107.  
  108.  
  109. // Mostra le possibili somme e le rispettiva probabilità
  110. if (true) {
  111.   echo("Probabilità delle possibili somme" . CRLF);
  112.   foreach($probSomme as $s => $ps) {
  113.     echo("Somma: " . $s . ", Probabilità: " . $ps . CRLF);
  114.   }
  115.   echo CRLF;
  116. }
  117. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement