PDA

View Full Version : [JAVA] Algoritmo che setta la probabilità di uscita


EnZiMa
06-06-2008, 10:43
Ciao a tutti!

Devo simulare il giro di una ruota composta da valori numerici letti da file con relative probabilità di uscita. Con l'oggetto random scelgo a caso che valore deve uscire, ma come faccio ad assegnare ad un valore specifico la probabilità di uscita? :confused:

faccio un esempio:

avendo 3 valori nelle ruota

1) 50
2) 100
3) 150

ovviamente hanno tutti la stessa probabilità di uscita 0.33

ma come faccio ad assegnare le seguenti probabilità?

1) 0.1
2) 0.2
3) 0.7

Grazie 1000! :)

banryu79
06-06-2008, 11:02
Non basta che ti fai generare da random un valore nel range 0.0 - 1.0 e in base al risultato (0.0-0.1 per il 3, 0.11-03 per il 100, 0.031-1.0 per il 150) decidi te quale dei tre numeri esce?

EnZiMa
06-06-2008, 11:49
Non basta che ti fai generare da random un valore nel range 0.0 - 1.0 e in base al risultato (0.0-0.1 per il 3, 0.11-03 per il 100, 0.031-1.0 per il 150) decidi te quale dei tre numeri esce?

no, non li decido io...

cmq il problema è che non so a priori quanti valori(compresa la probabilità) ho, perchè sono letti da file, quindi magari potrei metterli in un array...

banryu79
06-06-2008, 12:00
Mi sono espresso male, ma il ragionamento resta valido (ammesso che io abbia capito cosa devi fare):

Non basta che ti fai generare da random un valore nel range 0.0 - 1.0 e in base al risultato (0.0-0.1 per il 3, 0.11-03 per il 100, 0.031-1.0 per il 150) vedi quale dei tre numeri esce?


In sostanza tu parserizzi da un file i numeri della ruota e le relative probabilità di estrazione.

Bene, la somma di tutte le probabilità la rapporti a 1.0 (100%), quindi tramite il rapporto puoi calcolarti gli intervalli di valore percentuali di ogni numero, al quel punto "tiri il dado" (ti fai generare un valore random nell'intervallo da 0.0 a 1.0) e hai il numero uscito.

I numeri li potresti ordinare in senso crescente e metterli in un HashMap associando ogni numero con il valore della sua probabilità di uscita.

feboss
06-06-2008, 12:02
Ciao a tutti!
avendo 3 valori nelle ruota

1) 50
2) 100
3) 150

ovviamente hanno tutti la stessa probabilità di uscita 0.33

ma come faccio ad assegnare le seguenti probabilità?

1) 0.1
2) 0.2
3) 0.7

Grazie 1000! :)
se nel file inserisci
1 volta il valore 50
2 volte il valore 100
7 volte il valore 150
in questo modo le probabilità sono rispettivamente 0.1 0.2 0.7

banryu79
06-06-2008, 13:14
Credo che il file non sia lui a generarlo, ma gli venga dato come input, infatti ha detto che non sa a priori quanti valori ha proprio perchè li legge da un file.

gugoXX
06-06-2008, 13:41
Si chiama distribuzione di probabilita'.
Ad ogni elemento del vettore e' associato un valore. La probabilita' di uscita dell'elemento e' esattamente quel valore diviso la somma di tutti i valori.

Dovrai quindi tirare un numero a caso tra 0 e la somma di tutte le distribuzioni, e andare a cercare il valore corrispondente.
Per comodita' puoi costruirti la funzione integrale della distribuzione, dove a ciascun elemento sara' associato il proprio valore di probabilita' sommato a tutti i precedenti.

Con questa nuova distribuzione trovare l'elemento casuale e' semplice. E' sufficiente andare a cercare il piu' piccolo valore > al numero casuale.

ES:
ho 3 elementi, pippo, pluto e paperino, associati ciascuno ai pesi 3 5 9

pippo = 3
pluto = 5
paperino = 9

E' sufficiente quindi tirare un numero a caso tra 0 e (3+5+9) = 17 (escluso)
Per sapere quale e' l'elemento uscito, puoi costruirti la distribuzione integrale

pippo = 3
pluto = 8 (5 + 3)
paperino = 17 (9+8)

Se tiro 15, allora il risultato sara' paperino, che e' il piu' piccolo elemento il cui valore della funzione integrale e' > 15

PS: Il venerdi' andiamo in centro a bere birra a pranzo, quindi non sono lucido come dovrei.

feboss
06-06-2008, 13:43
allora man mano che li legge e le inserisce in una struttura dati, fa il controllo sulla probabilità e aggiunge probabilità*10 volte il numero corrispondente alla struttura dati

oppure ho pensato:
Carica le probabilità in una struttura dati e i numeri in un altra.
ordina le probabilità e nell'agoritmo di ordinamento, ogni qual volta sposta gli elementi della probabilità, sposta anche i valori(senza controllo, il controllo va fatto sulle prob)
in pratica ordina i due array in base alla probabilità.

Somma ad ogni elemento delle probabilità, i valori precedenti.
ad esempio in un array
static int[] sommarizza(int[] ar)
{
int[] ar2= new int[ar.length];
for(int i=0;i<ar.length;i++)
ar2[i]=ar[i];

for(int i=1;i<ar.length;i++)
for(int j=0;j<i;j++)
ar2[i]+=ar[j];

return ar2;
}

dopo fa un controllo simile, dove ar1 sono le probabilità, mentre ar2 i numeri

for(int i=0;i<ar1.length-1;i++)
{
if(random > ar1[i] && random <= ar1[i+1])
printa ar2[i+1]
else if(random <= Array[i])
printa ar2[i]
dovrebbe andare

banryu79
06-06-2008, 14:10
Io voto per la soluzione di gugoXX!

P.S.: anche io sono sotto birra (pizzata con i colleghi) :D

EnZiMa
07-06-2008, 13:16
la soluzione di gugoXX non so come implementarla :(

ho provato questa strada:

import java.util.*;
public class es{

private static List<Integer> probabilita = new ArrayList<Integer>();
private static Map <Integer,Integer> mappa = new HashMap <Integer,Integer>();
private static int estratto=0;
private static final int LIMITE=100;

public static void main(String[]args){

//metto le probabilita e i valori nell'hashMap(probabilita, valore)
mappa.put(70,150);
mappa.put(10,50);
mappa.put(20,100);

//inserisco le probabilita nell'arraylist
probabilita.add(70);
probabilita.add(10);
probabilita.add(20);

//creo il numero random
Random random = new Random();
estratto = random.nextInt(LIMITE);

System.out.println("Numero random: "+estratto);

//ordino la lista delle probabilita
Collections.sort(probabilita);

for(int i = 0; i < probabilita.size();i++){
int corrente = probabilita.get(i);

if(estratto<=corrente){
System.out.println("Numero estratto:"+mappa.get(corrente)+" con probabilita del "+corrente+"%");
break;
}
}
}
}

sicuramente non è la soluzione migliore e non funziona neanche bene, ho dovuto mettere quel bruttissimo break dentro l'if altrimentri mi beccava anche l'intervallo successivo. Cosi come è, se esce un numero nell'ultimo intervallo tra il 71 e 100 non lo considera :muro: :mc:

EnZiMa
09-06-2008, 11:38
Devo implementare lo stesso algoritmo che fa funzionare questa ruota http://illuminations.nctm.org/ActivityDetail.aspx?ID=79 :mc:

help me!

EnZiMa
14-06-2008, 09:31
up!

wingman87
14-06-2008, 10:37
Secondo me potresti fare coś (che forse era quello che diceva gugoXX):
//Fai inserire il numero di valori desiderati all'utente o scegli il numero a priori, mettiamo sia n
...
int probabilities[]=new int[n];
int values[]=new int[n];

int totalprob=0;

for(int i=0;i<n;i++){
//Fai inserire probabilità e valore ma alla probabilità aggiungi totalprob
...
totalprob+=probabilities[i];
}

//crei il numero random
...

for(int i=0,lastprob=0;i<n;lastprob=probabilities[i],i++){

if(random<=probabilities[i])
System.out.println("Numero estratto: "+values[i]+". Con probabilita': "+probabilities[i]-lastprob);
}