Dips estube leyendo el post. Y me quedo gustando la idea :P, de todas formas voy a ver si mi funcion se puede aplicar a tu problema :)
Volviendo a lo mio, estube realizando algunas pruebas a la funcion, y los resultados me dejaron sorprendidos :P
_________________________
Primero los Sucesos Posibles junto a su Probabilidad son :
Código:
x=1 p(x=1)=5
x=2 p(x=2)=90
x=3 p(x=3)=2
x=4 p(x=3)=2
x=5 p(x=3)=2
En palabras, el Uno tiene una Probalidad de 5% , el Dos de 90%, etc se entiende :P
Vamos a realizar 100 Sucesos Aleatorios (respetando el % de exito de los numero) y esto 300 Veces (En total 3000), Vamos a tener unos contadores para cada numero , luego vamos a sacar el promedio de aparicion de los nuermos.
Código PHP:
<?
// Numeros con Probabilidad de Exito
// by DeeR http://deerme.org
function sum_array($m)
{
$t=0;
foreach($m as $v)
{
$t=($t+$v);
}
return $t;
}
function num_con_prob($n,$p)
{
// Las Matrices deben ser de Igual Dimension
if ( count($n) == count($p) )
{
// La Suma de la Matriz $p debe dar 100 (Suma de Probabilidades)
if ( sum_array($p) == 100 )
{
// Recorremos los Numeros
$m=0;
for ( $i=0 ; $i<count($n) ; $i++ )
{
// Recorremos sus Probabilidades
for ( $j=0 ; $j<($p[$i]) ; $j++)
{
$prob[$m]=$n[$i];
$m++;
}
}
/*
Finalmente Tenemos en la Matris $prob Los Numeros repetidos segun
su Probabilidad
Entonces ahora elegimos un Numero al Azar de la Matriz $prob
- Cada Numero tiene su Probabilidad de Salir (La cantidad de Veces que se repite, es ovbio, si se repite mas veces en la matriz, es mas probable que salga elegido).
*/
return ( $prob[ rand(0,99) ] );
}
}
return FALSE;
}
$numeros=array(1,2,3,4,5);
$probabilidades=array(5,90,2,2,1);
// Vamos a Realizar 10 Pruebas
for ($i=0;$i<300;$i++)
{
// Inicializamos Variables
$res[$i]['uno']=0;
$res[$i]['dos']=0;
$res[$i]['tres']=0;
$res[$i]['cuatro']=0;
$res[$i]['cinco']=0;
for($j=0;$j<100;$j++)
{
// Vamos a realizar 100 Intentos
switch ( num_con_prob($numeros,$probabilidades) ):
case 1:
$res[$i]['uno']++;
break;
case 2:
$res[$i]['dos']++;
break;
case 3:
$res[$i]['tres']++;
break;
case 4:
$res[$i]['cuatro']++;
break;
case 5:
$res[$i]['cinco']++;
break;
endswitch;
}
}
// Finalmente Realizamos el Promedio
for($i=0;$i<count($res);$i++)
{
$resf['uno']=$resf['uno']+$res[$i]['uno'];
$resf['dos']=$resf['dos']+$res[$i]['dos'];
$resf['tres']=$resf['tres']+$res[$i]['tres'];
$resf['cuatro']=$resf['cuatro']+$res[$i]['cuatro'];
$resf['cinco']=$resf['cinco']+$res[$i]['cinco'];
}
$resf['uno']=($resf['uno']/$i);
$resf['dos']=($resf['dos']/$i);
$resf['tres']=($resf['tres']/$i);
$resf['cuatro']=($resf['cuatro']/$i);
$resf['cinco']=($resf['cinco']/$i);
print_r($resf);
?>
Y el Resultado fue :O
Código:
Array
(
[uno] => 5.0533333333333
[dos] => 89.956666666667
[tres] => 1.9733333333333
[cuatro] => 2.0266666666667
[cinco] => 0.99
)
Es decir, el resultado que nos dio la prueba, coinciden practicamente igual con el porcentaje de exito de los sucesos :P, es decir la funcion se comporta muy bien.
( Lo que hace el ocio y tiempo libre xD, total en unas semanas mes comienza el semestre )
PD : Respecto al contra (Porcentajes con Decimales), Estube pensando como realizar la funcion, para que admita porcentajes con decimales, pero creo que la solucion a la que llege consume mucha memoria :P