Visualizzazione risultati 1 fino 18 di 18

Discussione: [PHP] Distribuzione valore su array impostando un range

  1. #1
    nevada2000 non è connesso Neofita
    Data registrazione
    06-04-2010
    Messaggi
    12

    Question [PHP] Distribuzione valore su array impostando un range

    Ciao raga.
    scrivo qui per chiedervi aiuto su come potrei fare a creare una funzione del genere:

    Supponendo di avere un array composto da 100 variabili , e una $variabile con un valore (es 800)
    vorrei che il valore contenuto nella variabile venga smistato in tutto l'array, MA impostando un range per ogni array (0- 100)
    esempio

    array(0) = 0
    array(1) = 100
    array(3) = 73
    array(4) = 11
    ...
    ...
    ..
    TOTALE VALORE ARRAY = 800

    come potrei fare? anche per effettuare una ricerca, non saprei proprio cosa cercare!! ho provato anche a cercare
    "Ordinamento randomizzato per distribuzione" .. ma non mi è stato di aiuto. grazieeee

  2. #2
    Guest

    Predefinito

    Supponendo che più elementi dell' array possano avere valori uguali fra loro, e che la distribuzione dei valori avvenga in modo casuale, puoi provare una cosa del genere:
    Codice PHP:
    $variabile = 800;
    $somma = 0;

    for(
    $i = 0; $i < 100; $i++) {
    $array[$i] = rand(0, $variabile);
    $somma = $somma + $array[$i];
    $variabile = 800 - $somma;
    }
    $variabile rappresenta il valore massimo che può assumere ogni elemento dell' array (che varia ad ogni iterazione del ciclo) ed assume come valore di partenza il numero che vuoi scomporre all' interno dell' array, mentre $somma è la somma di tutti i valori assunti dai vari elementi dell' array (inizialmente è 0, alla seconda iterazione vale $array[0], alla terza $array[0] + $array[1], etc.) Ad ogni iterazione viene generato il numero casuale, viene aggiornata la variabile $somma ed infine il valore massimo assumibile viene ridotto della somma di tutti i valori assunti fino a quel punto.

    Ad esempio:

    Alla prima iterazione lo script assegna
    Codice PHP:
    $array[0] = rand(0, 800) // supponiamo generi 100;
    $somma = 100;
    $variabile = 700;
    Alla seconda
    Codice PHP:
    $array[1] = rand(0, 700) // supponiamo generi 150;
    $somma = 250;
    $variabile = 550;
    Alla terza
    Codice PHP:
    $array[1] = rand(0, 550)
    ...
    ...

    ...
    Ultima modifica di alemoppo : 15-07-2015 alle ore 15.52.48 Motivo: +tag [php]

  3. #3
    L'avatar di alemoppo
    alemoppo non è connesso Staff AV
    Data registrazione
    24-08-2008
    Residenza
    PU / BO
    Messaggi
    22,744

    Predefinito

    Citazione Originalmente inviato da descartesadventures Visualizza messaggio
    Codice PHP:
    $variabile = 800;
    $somma = 0;

    for(
    $i = 0; $i < 100; $i++) {
    $array[$i] = rand(0, $variabile);
    $somma = $somma + $array[$i];
    $variabile = 800 - $somma;
    }
    In questo modo, non rischi di avere $somma a 800 prima di arrivare alla fine dell'array? Mi spiego: l'array è lungo 100. Se mediamente rand(0, $variabile) vale più di 8 (cosa molto probabile visto che ad esempio all'inizio è rand(0,800)), ti ritrovi di aver finito i numeri da assegnare prima di arrivare agli ultimi elementi dell'array. In altre parole, in questo modo mi pare che i primi elementi vengano assegnati a valori alti, per poi decrescere man mano che si sale negli elementi dell'array. Verosimilmente gli ultimi elementi saranno sempre zero.

    L'unica idea però pessima che mi è venuta è una cosa del genere:
    Codice PHP:
    $variabile = 800;

    while(
    $variabile--)
    $array[rand(0, 100)]++;
    Che però a livello di ottimizzazione è una mostrousità. Si potrebbe migliorare incrementando i valori più di 1, magari valori casuali purché piccoli (ovviamente sottraendo della stessa quantità $variabile), ma dipende dal compromesso velocità/distribuzione che si vuol ottenere.

    Ciao!
    Ultima modifica di alemoppo : 15-07-2015 alle ore 15.55.51

  4. #4
    Guest

    Predefinito

    Citazione Originalmente inviato da alemoppo Visualizza messaggio
    In questo modo, non rischi di avere $somma a 800 prima di arrivare alla fine dell'array? Mi spiego: l'array è lungo 100. Se mediamente rand(0, $variabile) vale più di 8 (cosa molto probabile visto che ad esempio all'inizio è rand(0,800)), ti ritrovi di aver finito i numeri da assegnare prima di arrivare agli ultimi elementi dell'array. In altre parole, in questo modo mi pare che i primi elementi vengano assegnati a valori alti, per poi decrescere man mano che si sale negli elementi dell'array. Verosimilmente gli ultimi elementi saranno sempre zero.
    Questo senz' altro, infatti nella premessa avevo scritto che lo script sarebbe stato valido nel caso in cui ci fosse la possibilità di generare valori uguali fra loro (verosimilmente tanti 0 alla fine ) .

    La soluzione che proponi effettivamente è interessante, però non è anche in questo modo possibile che molti elementi dell' array vengano lasciati a 0? Cioè, con rand(0, 100) non si ha la certezza che alla fine delle 800 iterazioni tutti i 100 elementi dell' array siano stati coperti.

  5. #5
    L'avatar di alemoppo
    alemoppo non è connesso Staff AV
    Data registrazione
    24-08-2008
    Residenza
    PU / BO
    Messaggi
    22,744

    Predefinito

    Citazione Originalmente inviato da descartesadventures Visualizza messaggio
    Cioè, con rand(0, 100) non si ha la certezza che alla fine delle 800 iterazioni tutti i 100 elementi dell' array siano stati coperti.
    No: rand(0,100) indica la chiave dell'array e non il contenuto. Visto che i valori da immettere solo molto maggiori di 100 (otto volte superiori), mediamente ogni elemento dell'array viene chiamato 8 volte.

    In altre parole: su 800 tentativi, sono abbastanza sicuro di prendere tutti e 100 i numeri almeno una volta (ripeto, mediamente mi aspetterei 8 successi per ogni numero ma questo dipende dalla funzione di distribuzione di rand()).

    Nel caso invece che il valore non sia 800 ma minore di 100, è normale che molti elementi siano nulli. In ogni caso il numero viene comunque distribuito casualmente tra gli elementi indipendentemente che siano i primi o ultimi elementi.

    Ciao!
    Ultima modifica di alemoppo : 15-07-2015 alle ore 16.15.36

  6. #6
    Guest

    Predefinito

    Citazione Originalmente inviato da alemoppo Visualizza messaggio
    In altre parole: su 800 tentativi, sono abbastanza sicuro di prendere tutti e 100 i numeri almeno una volta (ripeto, mediamente mi aspetterei 8 successi per ogni numero ma questo dipende dalla funzione di distribuzione di rand()).
    Ah beh certo, non avevo considerato che la probabilità di generare ogni chiave almeno una vota è davvero alta.

  7. #7
    Guest

    Predefinito

    Mahh così leggendo di fretta i commenti e il problema mi viene da dire a sboccio che devi impostare un calcolo, perchè se tu vuoi che tutti e 100 gli elementi vengano usati e il totale del loro valore sia 800 vuol dire che devi impostare un ciclo che controlli ad ogni iterazione quant'è il valore raggiunto e la somma degli elementi dovrà essere il totale meno il valore raggiunto...

    Esempio ho 10 elementi la somma deve fare 100 con valori presi a random se il primo a random è 99 innanzi tutto sei fregato perchè se usi interi con due elementi sei a 100 quindi ci vuole un limite, sono 10 variabili il primo valore non può essere superiore a 90, poi la somma del totale degli elementi dovrà essere 100-90 = 10...quindi la somma dei valori degli altri 9 elementi deve essere 10 se il primo vale 90, se il primo vale 50 0 40 o pinco pallo la somma del totale degli altri elementi sarà sempre 100 - 50 o 100 - 40 o 100 - pinco pallo....Non so a sboccio mi viene da dire così.
    Ciao

    EDIT:

    Ehh Karl però così funziona.... :) alla fine va bene...

    Codice PHP:

    $variabile
    = 800;

    while(
    $variabile--){
    $array[rand(1, 100)]++;
    }

    print (
    '<pre>');print_r ($array);print ('</pre>');
    print
    'numero elementi =' .count($array).'<br>';
    print
    'somma = ' .array_sum($array).'<br>';
    Ultima modifica di alemoppo : 15-07-2015 alle ore 21.50.19 Motivo: Non fare post consecutivi: modifica i messaggi con il tasto "Modifica messaggio".

  8. #8
    L'avatar di alemoppo
    alemoppo non è connesso Staff AV
    Data registrazione
    24-08-2008
    Residenza
    PU / BO
    Messaggi
    22,744

    Predefinito

    Citazione Originalmente inviato da fractalcosmo Visualizza messaggio
    Mahh così leggendo di fretta i commenti e il problema mi viene da dire a sboccio che devi impostare un calcolo, perchè se tu vuoi che tutti e 100 gli elementi vengano usati e il totale del loro valore sia 800 vuol dire che devi impostare un ciclo che controlli ad ogni iterazione quant'è il valore raggiunto e la somma degli elementi dovrà essere il totale meno il valore raggiunto...

    Esempio ho 10 elementi la somma deve fare 100 con valori presi a random se il primo a random è 99 innanzi tutto sei fregato perchè se usi interi con due elementi sei a 100 quindi ci vuole un limite, sono 10 variabili il primo valore non può essere superiore a 90, poi la somma del totale degli elementi dovrà essere 100-90 = 10...quindi la somma dei valori degli altri 9 elementi deve essere 10 se il primo vale 90, se il primo vale 50 0 40 o pinco pallo la somma del totale degli altri elementi sarà sempre 100 - 50 o 100 - 40 o 100 - pinco pallo....Non so a sboccio mi viene da dire così.
    Ciao
    Questa è la soluzione proposta da descartesadventures. Leggi la mia prima risposta sopra per capire perché non è un granché.

    Citazione Originalmente inviato da fractalcosmo Visualizza messaggio
    Ehh Karl
    Karl?

    Citazione Originalmente inviato da fractalcosmo Visualizza messaggio
    però così funziona.... :) alla fine va bene...

    Codice PHP:

    $variabile
    = 800;

    while(
    $variabile--){
    $array[rand(1, 100)]++;
    }

    print (
    '<pre>');print_r ($array);print ('</pre>');
    print
    'numero elementi =' .count($array).'<br>';
    print
    'somma = ' .array_sum($array).'<br>';
    Non è necessario provare uno script di 2 righe per vedere che "funziona". Ho detto che non mi sembra molto ottimizzato.
    Comunque ora che rivedo la documentazione della rand(), deve andare da (0,99) e non da (0,100) come ho scritto.

    p.s: Non fare messaggi consecutivi: modifica i messaggi con l'apposito pulsante.

    Ciao!
    Ultima modifica di alemoppo : 15-07-2015 alle ore 21.45.06

  9. #9
    Guest

    Predefinito

    Può andare anche da 51 a 150...Non c'entra credo sia meglio partire da 1 ma comunque non fa differenza per il calcolo.Ho messo il codice perchè con i print <pre> e la somma e in numero degli elementi è più visibile...tutto lì, salta più a l'occhio come lavora, rimane il fatto che per me la soluzione che hai dato è buona.
    Leggevo di fretta e dall'indice dei messaggi pensavo fosse stato scritto da Karl invece era un altro post...

    No un momento allora non hai capito, mi sembra strano dovresti aver fatto ingegneria delle telecomunicazione se non vado errato, certo non è matematica, ma quello che hai scritto nel codice è esattamente quello che ti ho detto io, il parse fa quello abbassa il valore e nello stesso momento aumenta l'elemento dell'array fino a quando non arriva ad 800 e per farlo deve per forza fare il ragionamento che ti ho detto.Cioè parte da 800 gli toglie 10 poi gli togli 5 e aumenta gli elementi fino a quando la somma non fa 800...infatti il codice dell'altro post andava bene ma manca qualcosa scritto in quel modo.

    Ps:La matematica non è un'opinione se vuoi arrivare a 10 con 10 elementi e sei in N ogni elemento vale 1...c'è poco da fare, in matematica non si scherza...Se metti lo zero sei in N_0 quindi hai un tot di possibilità...non si scappa...fidati, no perchè se vogliamo mettere in discussione la regina delle scienze allora ci do a mucchio.... :)
    Ultima modifica di fractalcosmo : 15-07-2015 alle ore 23.15.41

  10. #10
    L'avatar di alemoppo
    alemoppo non è connesso Staff AV
    Data registrazione
    24-08-2008
    Residenza
    PU / BO
    Messaggi
    22,744

    Predefinito

    Citazione Originalmente inviato da fractalcosmo Visualizza messaggio
    Ps:La matematica non è un'opinione se vuoi arrivare a 10 con 10 elementi e sei in N ogni elemento vale 1...c'è poco da fare, in matematica non si scherza...Se metti lo zero sei in N_0 quindi hai un tot di possibilità...non si scappa...fidati, no perchè se vogliamo mettere in discussione la regina delle scienze allora ci do a mucchio.... :)
    Non ho capito nulla. A cosa ti riferisci? Forse al mio
    deve andare da (0,99) e non da (0,100) come ho scritto.
    Stavo soltanto correggendo il mio script. Questa volta sinceramente non capisco perché ti sei sentito tirato in causa.

    E comunque per convenzione, gli array in PHP partono da 0.

    Ciao!
    Ultima modifica di alemoppo : 15-07-2015 alle ore 23.56.25

  11. #11
    Guest

    Predefinito

    Da questo tuo commento:

    Questa è la soluzione proposta da descartesadventures. Leggi la mia prima risposta sopra per capire perché non è un granché.


    Mentre l'idea di descartes è giusta ma è scritta male nel codice, perchè in quel modo il parse entra nel ciclo ed ogni volta crea un numero random con un array che una volta ha un elemento poi la seconda iterazione ha due elementi etc...etc....arriva a fissarsi a 800 al quattordicesimo array cioè quando ha 14 elementi la somma è sempre 800 solo che molti elementi sono a zero.Se metti i print dentro al ciclo lo vedi..
    La logica è quella che ha detto descartes ma scritta come hai scritto tu, cioè tu hai scritto esattamente quello che intendeva descartes, perchè la matematica non è un'opinione....Se tu vuoi usare 100 elementi ed escludi lo zero come valore e la somma dei valori di questi 100 elementi deve fare 800 per forza il parse dovrà togliere un valore da 800 e poi la somma dei restanti indici dovrà fare 800 - valoreAssegnato....Per forza non si scappa, purtroppo matematica è così non è filosofia, non si poteva andare all'esame dicendo al Prof Mahhh io l'ho interpretata così...come interpreti un poeta o un filosofo, la matematica è bianca o nera non si scappa, non a caso è una scienza esatta.
    Ultima modifica di fractalcosmo : 16-07-2015 alle ore 00.09.03

  12. #12
    L'avatar di alemoppo
    alemoppo non è connesso Staff AV
    Data registrazione
    24-08-2008
    Residenza
    PU / BO
    Messaggi
    22,744

    Predefinito

    Da come la vedo io, le due soluzioni sono totalmente differenti. La mia si può migliorare ulteriormente come descritto sempre nella mia prima risposta. È un approccio differente al problema.

    Io non ho fatto alcun
    800 - valoreAssegnato
    Se per te le soluzioni sono uguali allora ok, direi che stiamo parlando di filosofia.

    Ciao!

  13. #13
    Guest

    Predefinito

    Alemoppo $variabile-- vuol dire prendi 800 e decrementalo di una unità fino a 1 e mentre fai questo inserisci degli indici random fino a 100.Se scrivi questo:

    Codice PHP:
    $variabile = 800;

    while(
    $variabile--){
    $array[]++;
    }

    print (
    '<pre>');print_r ($array);print ('</pre>');
    print
    'numero elementi =' .count($array).'<br>';
    print
    'somma = ' .array_sum($array).'<br>';
    Il tuo array sarà di 800 elementi e i valori tutti 1....Ribadisco non c'è niente da discutere è così e non si scappa.Il fatto è che nel tuo esempio ci sono ovviamente molti valori doppioni perchè il parse non si preoccupa, al caricamento della pagina cambia il random degli elementi ma lui può tranquillamente fare chiave - > valore con valore == 5 5 5 5 5 5 basta che usa 100 indici presi a random e arriva da 800 a 1.E secondo te come fa, come ragiona?
    Semplice prova l'esempio che ti ho fatto io sopra e vedrai come ragiona prende 800 e gli toglie una volta 1 la seconda volta toglie 1 da 799 cioè 800-1 poi 800-2 poi 800-3 e così via....Cioè hai scritto 800 - valoreAssegnato in quel momento.Il problema è che random l'indice non i valori perchè ovviamente è impostato a metà....Se vuoi fare random sia la chiave che il valore il tuo esempio è mancante...Ma il ragionamento è questo...Per questo ti dico che se vuoi fare random anche i valori devi per forza creare un ciclo che calcoli

    800 - Valore alla seconda iterazione la somma dei valori dei restanti indici deve essere = 800 - Valore come dice descartes se il primo valore è 50 la somma dei restanti 99 indici deve essere 750 non si scappa....Adesso su non possiamo stare a discutere di cose ovvie..Ciao
    Ultima modifica di fractalcosmo : 16-07-2015 alle ore 00.56.52

  14. #14
    L'avatar di alemoppo
    alemoppo non è connesso Staff AV
    Data registrazione
    24-08-2008
    Residenza
    PU / BO
    Messaggi
    22,744

    Predefinito

    Se usiamo una distribuzione discreta uniforme, direi che dobbiamo aspettarci valori doppioni. Per il resto ok, anche se ancora penso che siano approcci differenti :P

    Ciao!

    EDIT:

    Quindi secondo te, io non so come "ragiona" il codice che ho scritto io stesso?

    p.s: la chiudo qui, come al solito non stiamo portando nulla di costruttivo.
    Ultima modifica di alemoppo : 16-07-2015 alle ore 00.55.30

  15. #15
    Guest

    Predefinito

    Citazione Originalmente inviato da fractalcosmo Visualizza messaggio
    Esempio ho 10 elementi la somma deve fare 100 con valori presi a random se il primo a random è 99 innanzi tutto sei fregato perchè se usi interi con due elementi sei a 100 quindi ci vuole un limite, sono 10 variabili il primo valore non può essere superiore a 90, poi la somma del totale degli elementi dovrà essere 100-90 = 10...quindi la somma dei valori degli altri 9 elementi deve essere 10 se il primo vale 90, se il primo vale 50 0 40 o pinco pallo la somma del totale degli altri elementi sarà sempre 100 - 50 o 100 - 40 o 100 - pinco pallo....Non so a sboccio mi viene da dire così.
    Ciao
    Questo è corretto, ma si deve tenere presente che su un array di 10 elementi in cui la somma dei valori deve essere 100 - come nel tuo esempio, se alla prima chiave imponi di non assumere un valore maggiore al 90, nel caso in cui dovesse uscire proprio 90, poi hai comunque una media di 1 su tutti gli altri elementi. Si dovrebbe considerare un valore limite tale che la quantità rimanente è raggiungibile da valori diversi, ma ovviamente si tratta di capire bene quanto sono raffinate le esigenze, e, come diceva alemoppo, trovare il corretto compromesso fra distribuzione dei valori e leggerezza del programma.
    Ultima modifica di descartesadventures : 16-07-2015 alle ore 01.19.13

  16. #16
    Guest

    Predefinito

    Ma secondo me invece in tre abbiamo detto come deve essere la logica poi starà anche a Nevada a costruirsi il ciclo cercando di ottenere quello che vuole, è giusto anche che ci provi lui, tu gli hai dato la soluzione però con i valori che possono essere doppioni descartes gli ha dato la soluzione giusta logica per valori random ma codice da sistemare, io ho detto che avete ragione tutti e due, unendo i codici e le logiche Nevada adesso ha un buon punto per poter provarci...Io adesso vado e non mi metto a scrivere codice perchè sono a pezzi, vedrò nei prossimi giorni tempo permettendo...Ciao notte.

  17. #17
    L'avatar di alemoppo
    alemoppo non è connesso Staff AV
    Data registrazione
    24-08-2008
    Residenza
    PU / BO
    Messaggi
    22,744

    Predefinito

    Citazione Originalmente inviato da fractalcosmo Visualizza messaggio
    Io adesso vado e non mi metto a scrivere codice perchè sono a pezzi
    Codice PHP:
    $array = array_fill(0,100,0);

    $contenuto = 800;
    $len = 100;

    $x = $contenuto/$len;
    do {
    $delta = ($contenuto - ($delta = rand(1,$x)) < 0)?$contenuto:$delta;
    $array[rand(0, $len-1)]+= $delta;
    }while(
    $contenuto-=$delta);
    Però a sto punto direi che era più bello il mio precedente

    Se riuscite a implementarlo meglio, fate sapere. È una certa ora anche per me.

    Ciao!

    EDIT:

    Urca! Addirittura va il doppio più veloce!
    Ultima modifica di alemoppo : 16-07-2015 alle ore 02.20.13

  18. #18
    Guest

    Predefinito

    Altre soluzioni non ci sono, non si può usare valori che non siano doppioni se l'array è di 100 elementi i valori non possono essere diversi e arrivare a 800 usando tutti e 100 gli elementi. la sommatoria da 1 a 100 fa 5000 e qualcosa, quindi altre soluzioni non ce ne sono....O prendi lo zero e comunque valori bassi o come hai fatto l'esempio precedente con i doppioni...Altrimenti Nevada deve spiegare meglio quanto è lungo l'array e come dovrebbero essere i valori.

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •