Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,505

    Prendere un elemento di un array casualmente, ma non troppo

    Ho un array con un numero non definito di elementi e devo prenderne uno a caso, ma il primo deve avere una probabilità maggiore di essere selezionato.

    Ho trovato una soluzione sulla documentazione della funzione array_rand, ma prevede che si sappia a priori il numero di elementi e che si assegni ad ognuno un intero che ne definisce la probabilità di essere selezionato, io non lo so quanti elementi conterrà l'array.

    Idee su come procedere?

  2. #2
    Bè secondo quale criterio questo elemento deve avere una probabilità maggiore di essere selzionato ?

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2012
    Messaggi
    1,453
    Un piccolo calcolo insieme a rand che avvantaggia anche la prima serie potrebbe andare bene? Sennò cerca un altro criterio per selezionarlo

  4. #4
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,505
    E' esattamente quello che voglio fare, ma la funzione rand non prevede un peso per i valori tra cui scegliere.

    Io prendo dei dati li ordino in modo che in posizione 0 ci sia quello che secondo i criteri di ordinamento è l'elemento più importante, ma non deve essere preso sistematicamente, deve solo avere una maggiore probabilità rispetto agli altri.

    Diciamo che la probabilità con cui deve essere selezionato è

    floor($num_elementi/10)*10 + 10
    gli altri devono dividersi equamente la probabilità restante

    Quindi ad esempio:
    se ci sono 3 elementi
    probabilità elemento 0 = floor(3/10)*10 + 10 = 40
    probabilità elemento 1 = (100 - 40) / 2 = 30
    probabilità elemento 2 = (100 - 40) / 2 = 30

    se ci sono 4 elementi
    probabilità elemento 0 = floor(4/10)*10 + 10 = 30
    probabilità elemento 1 = (100 - 30) / 3 = 23
    probabilità elemento 2 = (100 - 30) / 3 = 23
    probabilità elemento 3 = (100 - 30) / 3 = 23
    (non si arriva a 100, ma non fa niente, basta che uno venga selezionato)

    e via dicendo.

    EDIT: la formula non mi pare che funzioni, l'ho scritta al volo e dovrò cambiarla, ma l'idea è quella lì

  5. #5
    Utente di HTML.it L'avatar di garakkio
    Registrato dal
    Dec 2011
    residenza
    Roma
    Messaggi
    480
    Parto dal presupposto che tu abbia già calcolati i pesi che ti interessa applicare (cosa che mi sembra esuli da questo topic).
    Dunque, una volta che hai i pesi, puoi applicarli semplicemente creando un nuovo array, che ripeta ogni elemento per il numero di peso che gli hai attribuito. A quel punto, il semplice array_rand() applicato a tale array ti darà il risultato atteso.

  6. #6
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,505
    Ok, ho la formula per le probabilità.

    Diciamo che il primo elemento deve avere probabilità tripla rispetto agli altri, quindi:

    Codice PHP:
    //numero di elementi presenti nell'array
    $num_elementi count($array);

    //probabilità per gli elementi diversi dal primo
    $prob_generale 100/($num_elementi 2);

    //probabilità del primo elemento
    $prob_primo $prob_generale
    Ecco, ora devo tirare fuori il primo elemento con una probabilità pari a $prob_primo, e gli altri con una probabilità $prob_generale per ognuno di essi.

    Come posso usare questi dati per pesare la selezione casuale di un elemento?

  7. #7
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,505
    Originariamente inviato da garakkio
    Parto dal presupposto che tu abbia già calcolati i pesi che ti interessa applicare (cosa che mi sembra esuli da questo topic).
    Dunque, una volta che hai i pesi, puoi applicarli semplicemente creando un nuovo array, che ripeta ogni elemento per il numero di peso che gli hai attribuito. A quel punto, il semplice array_rand() applicato a tale array ti darà il risultato atteso.
    Si, ma a regime è previsto che gli elementi siano migliaia e a loro volta sono degli array, viene una cosa mostruosa facendo così.

  8. #8
    una cosa così potrebbe funzionare...anche se con tanti elementi diventa un lavoro pesante
    a seconda dei numeri degli if finali si decide la probabilità
    Vedi te se può essere utile,a me scriverla non fa fatica
    Codice PHP:
    function estrai() {
    //array di partenza da cui estrarre
    $colori = array('bianco''nero''giallo''verde''rosso');
    //array che tiene le estrazioni inizializzato con tutte le voci a 0
    $conta[$colori.length];
    for(
    $i 0$colori.length$i++) {
    $conta[$i] = 0;
    }
    while(!
    in_array(3$conta)){
    //estrazione: $pescato contiene l'indice estratto
    $pescato array_rand($colori);
    //l'elemento con lo stesso indice nell'array di conteggio viene incrementato
    $conta[$pescato]++;
    //al primo elemento basta una estrazione per essere ritornato
    if($conta[0] == 1) return $colori[0];
    //agli altri 3 --> ritorna l'ultimo pescato(che è per forza l'unico con 3)
    elseif(in_array(3$conta)) return $colori[$pescato];
    }


  9. #9
    Utente di HTML.it
    Registrato dal
    May 2012
    Messaggi
    1,453
    Originariamente inviato da scimmiaparlante
    una cosa così potrebbe funzionare...anche se con tanti elementi diventa un lavoro pesante
    a seconda dei numeri degli if finali si decide la probabilità
    Vedi te se può essere utile,a me scriverla non fa fatica
    Codice PHP:
    function estrai() {
    //array di partenza da cui estrarre
    $colori = array('bianco''nero''giallo''verde''rosso');
    //array che tiene le estrazioni inizializzato con tutte le voci a 0
    $conta[$colori.length];
    for(
    $i 0$colori.length$i++) {
    $conta[$i] = 0;
    }
    while(!
    in_array(3$conta)){
    //estrazione: $pescato contiene l'indice estratto
    $pescato array_rand($colori);
    //l'elemento con lo stesso indice nell'array di conteggio viene incrementato
    $conta[$pescato]++;
    //al primo elemento basta una estrazione per essere ritornato
    if($conta[0] == 1) return $colori[0];
    //agli altri 3 --> ritorna l'ultimo pescato(che è per forza l'unico con 3)
    elseif(in_array(3$conta)) return $colori[$pescato];
    }

    Da quand'è che esiste length in php?




    Comunque a mio parere una cosa del genere potrebbe andare
    Codice PHP:
    $lol = array('uno','due','tre','quattro','cinque','sei','sette','otto','nove','dieci');
    $r floor(rand(0,count($lol)-1)-rand(0,count($lol)/2));
    $s $r $r;

    echo 
    $lol[$s]; 
    uno esce almeno ogni 4-5 volte

  10. #10
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,505
    Alla fine penso che farò semplicemente così:
    Codice PHP:
    $elementi = array(.......); //l'array con tutti i miei elementi tra cui scegliere

    $array_della_sorte = array(0,0,0,1);

    $pescato array_rand($array_della_sorte); //la prob di pescare 0 è 3 volte quella di pescare 1

    if ( $array_della_sorte[$pescato] == )
    {
        
    //prendo il primo elemento
    }
    else
    {
        
    //ne prendo uno a caso degli altri.


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.