Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Ecovacs Goat O1200 LiDAR Pro: la prova del robot tagliaerba con tagliabordi integrato
Ecovacs Goat O1200 LiDAR Pro: la prova del robot tagliaerba con tagliabordi integrato
Nuova frontiera per i robot tagliaerba, con Ecovacs GOAT O1200 LiDAR Pro che riconosce l'ambiente in maniera perfetta, grazie a due sensori LiDAR, e dopo la falciatura può anche rifinire il bordo con il tagliabordi a filo integrato
Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere?
Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere?
Equilibrio e potenza definiscono il Samsung Galaxy S26+, un flagship che sfida la variante Ultra e la fascia alta del mercato con il primo processore mobile a 2nm. Pur mantenendo l'hardware fotografico precedente, lo smartphone brilla per un display QHD+ da 6,7 pollici d'eccellenza, privo però del trattamento antiriflesso dell'Ultra, e per prestazioni molto elevate. Completano il quadro la ricarica wireless a 20W e, soprattutto, un supporto software settennale
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti
Zeekr sbarca ufficialmente in Italia con tre modelli elettrici premium, X, 7X e 001, distribuiti da Jameel Motors su una rete di 52 punti vendita già attivi. La Zeekr X parte da 39.900 euro, la 7X da 54.100: piattaforma a 800V, chip Snapdragon di ultima generazione, ricarica ultraveloce e un'autonomia dichiarata fino a 615 km WLTP. Le prime consegne sono previste a metà aprile
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 14-12-2015, 15:04   #1
Lim
Senior Member
 
L'Avatar di Lim
 
Iscritto dal: Dec 2000
Messaggi: 501
[JAVA] Problema nella generazione dei numeri casuali

Salve a tutti, ho un problema con la generazione dei numeri casuali in Java.
Ho sviluppato una piattaforma di simulazione per il moto di migliaia di particelle in uno spazio 3D.
Ho la necessità di aggiornare le loro coordinate spaziali (x, y, z) ad ogni istante temporale della simulazione in modo del tutto casuale (data da un moto di tipo Browniano) secondo una distribuzione Gaussiana con media nulla e deviazione standard predefinita.

Ipotizzando una dislocazione iniziale delle particelle in un punto ben preciso dello spazio, ci si aspetterebbe che dopo un certo tempo, le particelle si siano sparpagliate nello spazio in modo uniforme, mantenendo il baricentro di tutti i punti grosso modo intorno al punto iniziale.

Ho eseguito diversi run su macchine diverse ed ho ottenuto risultati diversi. La maggior parte delle macchine utilizzate resituisce i risultati attesi, mentre alcune configurazioni specifiche restituiscono risultati polarizzati.
Infatti dai risultati emerge che la "nuvola" di punti si sposti lungo una direzione preferenziale (lungo l'asse x).

Mi chiedo se la generazione dei numeri casuali possa dipendere in qualche modo dall'architettura del processore utilizzato.

Le architetture utilizzate per i test sono le seguenti:

Tipo 1:
Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
RAM: 32GB

Tipo 2:
Intel(R) Core(TM) i5-2300 CPU @ 2.80GHz
RAM: da 8GB a 24GB

Tipo 3:
Intel(R) Xeon(R) CPU E5410 @ 2.33GHz
RAM: 24GB

Tipo 4:
Six-Core AMD Opteron(tm) Processor 8425 HE @ 2.1GHz
RAM: 64GB

Tipo 5:
AMD Opteron(tm) Processor 6128 @ 2GHz
RAM: 128GB

Tipo 6:
Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz
RAM: 64GB


Le tipologie 1 e 2 forniscono i risultati attesi, tutte le altre danno risultati polarizzati.

Il sistema operativo utilizzato è Ubuntu 12.04 LTS e Ubuntu 14.04 LTS.
La versione della JVM è: OpenJDK 1.7 (64-Bit)


Riporto anche il codice dell'algoritmo per l'aggiornamento delle coordinate dei punti:

Il metodo move() è invocato ad ogni passo temporale della simulazione per ogni singolo punto da aggiornare mediante un approccio multithread (non mostrato qui):

Codice:
public void move(MyObj p) {
        float[] center=p.getCenter();                   
        float sigma2=getDiffusionCoefficient(p);        

        float dx=getGauss(sigma2);
        float dy=getGauss(sigma2);
        float dz=getGauss(sigma2);

        center[0]=center[0]+dx;
        center[1]=center[1]+dy;
        center[2]=center[2]+dz;
        p.setCenter(center[0],center[1],center[2]); 
    }


// A better implementation of Gaussian Random Number
    public float getGauss(float sigma){
        float rai=(float) Math.sqrt(-2*sigma*sigma*Math.log(1-(random.next(val)/div)));
        float teta=(float) (2*Math.PI*(random.next(val)/div));
        return (float) (rai*Math.cos(teta));
    }

Dove random è un'istanza di XORShiftRandom:

Codice:
// XORShiftRandom
    int val=31;
    double div=Math.pow(2, val);
    XORShiftRandom random=new XORShiftRandom(); 
    // End XORShiftRandom


public class XORShiftRandom {

    private long seed = System.nanoTime();        

    public XORShiftRandom() {

    }    

    protected int next(int nbits) {         
        long x = this.seed;
        x ^= (x << 21);
        x ^= (x >>> 35);
        x ^= (x << 4);
        this.seed = x;
        x &= ((1L << nbits) -1);
        return  (int)(x);
    }
}

Avendo rilevato una polarizzazione lungo l'asse x, ho voluto provare ad invertire l'ordine di generazione delle nuove coordinate, da x,y,z a y,z,x. La polarizzazione si è spostata dalla componente lungo x a quella lungo y! Quindi a quanto pare è la prima coordinata generata a subire principalmente gli effetti della polarizzazione.
Non ho idea del perché...
Inoltre, sembrerebbe che al crescere del numero di punti, cresca anche l'effetto della polarizzazione (in effetti, al crescere del numero di punti cresce il numero di chiamate al metodo di generazione delle coordinate).


Qualcuno ha qualche idea al riguardo?

Ultima modifica di Lim : 14-12-2015 alle 15:08.
Lim è offline   Rispondi citando il messaggio o parte di esso
Old 14-12-2015, 22:04   #2
GianMi
Senior Member
 
Iscritto dal: Oct 2008
Messaggi: 360
L'unica cosa che è connessa con l'hardware sottostante è la funzione System.nanoTime() e quindi potrebbe essere qualcosa legato alla risoluzione del timer. Tuttavia in un sistema multithread sono moltissime le cose che potrebbero non funzionare a dovere e presentare strani effetti collaterali.
GianMi è offline   Rispondi citando il messaggio o parte di esso
Old 15-12-2015, 10:39   #3
Lim
Senior Member
 
L'Avatar di Lim
 
Iscritto dal: Dec 2000
Messaggi: 501
Quote:
Originariamente inviato da GianMi Guarda i messaggi
L'unica cosa che è connessa con l'hardware sottostante è la funzione System.nanoTime() e quindi potrebbe essere qualcosa legato alla risoluzione del timer. Tuttavia in un sistema multithread sono moltissime le cose che potrebbero non funzionare a dovere e presentare strani effetti collaterali.
Avevo pensato anche io al System.nanoTime(), ma in realtà quella funzione viene invocata una sola volta, in fase di creazione dell'oggetto XORShiftRandom, quindi non dovrebbe influire più di tanto perché alla fine un seed vale l'altro per la generazione della sequenza casuale.
Piuttosto credo che il problema potrebbe essere legato alla concorrenza tra i thread, poiché ognuno effettua 3 chiamate al metodo next() di XORShiftRandom ed all'interno del metodo viene aggiornato il seed, dopo aver effettuato vari shift ed operazioni binarie sul seed precedente.
Sono sempre più convinto che i thread vadano a leggere e scrivere il seed in contemporanea e quindi la sequenza non è più casuale. Quello che continuo a non capire è perché l'effetto di polarizzazione sia evidente soltanto sulla coordinata X...
Lim è offline   Rispondi citando il messaggio o parte di esso
Old 15-12-2015, 11:20   #4
GianMi
Senior Member
 
Iscritto dal: Oct 2008
Messaggi: 360
Ok, allora potresti rendere la tua classe Random locale ai vari thread e quindi ognuno di essi avrà la sua istanza, cosa che se non sbaglio fa anche la la libreria java nella sua classe Random specializzata per il multithread. Dovresti però fare in modo che il seed di partenza non sia lo stesso quindi l'inizializzazione del seed andrebbe fatta con un Singleton.
GianMi è offline   Rispondi citando il messaggio o parte di esso
Old 30-12-2015, 10:57   #5
Daniels118
Senior Member
 
L'Avatar di Daniels118
 
Iscritto dal: Jan 2014
Messaggi: 852
Quote:
Originariamente inviato da GianMi Guarda i messaggi
Ok, allora potresti rendere la tua classe Random locale ai vari thread e quindi ognuno di essi avrà la sua istanza, cosa che se non sbaglio fa anche la la libreria java nella sua classe Random specializzata per il multithread. Dovresti però fare in modo che il seed di partenza non sia lo stesso quindi l'inizializzazione del seed andrebbe fatta con un Singleton.
Conviene passare il seed come parametro nel costruttore di XORShiftRandom, ed istanziarlo così:
Codice:
long seed = System.nanoTime();
XORShiftRandom a = new XORShiftRandom(seed + 0);
XORShiftRandom b = new XORShiftRandom(seed + 1);
...
In questo modo hai la garanzia che i seed siano diversi (se il generatore è buono il fatto che si discostano sempre di 1 dovrebbe essere ininfluente).
Daniels118 è offline   Rispondi citando il messaggio o parte di esso
Old 30-12-2015, 12:16   #6
GianMi
Senior Member
 
Iscritto dal: Oct 2008
Messaggi: 360
Quote:
Originariamente inviato da Daniels118 Guarda i messaggi
Conviene passare il seed come parametro nel costruttore di XORShiftRandom, ed istanziarlo così:
Codice:
long seed = System.nanoTime();
XORShiftRandom a = new XORShiftRandom(seed + 0);
XORShiftRandom b = new XORShiftRandom(seed + 1);
...
In questo modo hai la garanzia che i seed siano diversi (se il generatore è buono il fatto che si discostano sempre di 1 dovrebbe essere ininfluente).
La soluzione che suggerisci mi sembra che ignori del tutto il fatto che l'uso della classe è fatto in più thread paralleli... E' corretto generare il seed in quel modo, ma funzionerebbe solo se l'inizializzazione dei generatori random fosse statica, prima della partenza dei thread a cui si passa poi l'istanza di ogni generatore come parametro. La soluzione corretta potrebbe essere quella di usare un AtomicLong inizializzato con System.nanoTime() e poi usare il metodo incrementAndGet() che è sicuramente atomico.
GianMi è offline   Rispondi citando il messaggio o parte di esso
Old 30-12-2015, 13:42   #7
Daniels118
Senior Member
 
L'Avatar di Daniels118
 
Iscritto dal: Jan 2014
Messaggi: 852
La soluzione che ho proposto va bene se la creazione dei generatori avviene in un unico thread, non ha importanza quando e quanti ne vengono creati; certamente l'utilizzo di AtomicLong rende la classe applicabile ad un maggior numero di scenari.
Daniels118 è offline   Rispondi citando il messaggio o parte di esso
Old 30-12-2015, 13:48   #8
Daniels118
Senior Member
 
L'Avatar di Daniels118
 
Iscritto dal: Jan 2014
Messaggi: 852
Quote:
Originariamente inviato da Lim Guarda i messaggi
[..] Sono sempre più convinto che i thread vadano a leggere e scrivere il seed in contemporanea e quindi la sequenza non è più casuale. Quello che continuo a non capire è perché l'effetto di polarizzazione sia evidente soltanto sulla coordinata X...
Per curiosità fai queste prove e vedi se il problema persiste:
- esegui il programma su un singolo thread;
- aggiungi synchronized al metodo next (girando in multithread).
Daniels118 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Ecovacs Goat O1200 LiDAR Pro: la prova del robot tagliaerba con tagliabordi integrato Ecovacs Goat O1200 LiDAR Pro: la prova del robot...
Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere? Recensione Samsung Galaxy S26+: sfida l'Ultra, m...
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti Zeekr X e 7X provate: prezzi, autonomia fino a 6...
Marathon: arriva il Fortnite hardcore Marathon: arriva il Fortnite hardcore
HP Imagine 2026: abbiamo visto HP IQ all’opera, ecco cosa può (e non può) fare HP Imagine 2026: abbiamo visto HP IQ all’opera, ...
Cometa interstellare 3I/ATLAS: l'ESA dif...
Kodak PIXPRO AZ653: la fotocamera bridge...
Monitor da gaming: Samsung si conferma l...
The Duskbloods potrebbe arrivare a fine ...
Il miglior pesce d'aprile del mondo Linu...
Monopattini elettrici a 62 km/h fermati ...
OpenAI porta la modalità vocale d...
Mercedes-Benz introduce lo steer-by-wire...
Hacker agli Uffizi, il museo smentisce: ...
Nvidia mostra il futuro della grafica co...
Windows 11, scattano gli aggiornamenti f...
TIM lancia l'offerta di Pasqua: Giga ill...
Prime foto reali per OPPO Find X9 Ultra:...
Il leak di Claude Code diventa un'esca: ...
Netflix, batosta in Italia: aumenti ille...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 19:24.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v