Repository 32bit  Forum
Repository 64bit  Wiki

[RISOLTO][JAVA] Numeri casuali non ripetuti

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

[RISOLTO][JAVA] Numeri casuali non ripetuti

Messaggioda Delcaran Lëdeloth » mar dic 08, 2009 17:59

Come si evince dal titolo ho la necessità di generare dei numeri casuali non ripetuti. Non essendo un novellino alle prime armi con sti problemi ho approntato la seguente soluzione:
Codice: Seleziona tutto
public class Nodo {

   private static int tot = 0; // numero dei nodi (solo per debug)
   private int num; // numero del nodo (debug)
   private int cx; // coordinata orizzontale
   private int cy; // coordinata verticale
   private static Vector<Integer> ascisse = new Vector<Integer>(); // ascisse gia' usate
   private static Vector<Integer> ordinate = new Vector<Integer>(); // ordinate gia' usate
   private Random random = new Random();

   /**
    * Costruttore.
    */
   public Nodo() {
      // imposto le coordinate impedendo nodi sovrapposti
      boolean condx, condy;
      do {
         condx = condy = false;
         this.cx = random.nextInt(101);
         condx = ascisse.contains(this.cx);
         if (!condx) {
            ascisse.addElement(this.cx); // non e' mai stata usata questa ascissa: la aggiungo
         }

         this.cy = random.nextInt(101);
         condy = ordinate.contains(this.cy);
         if (!condy) {
            ordinate.addElement(this.cy); // non e' mai stata usata questa ordinata: la aggiungo
         }
         System.out.println("condx && condy: " + (condx && condy));
      } while (condx && condy); // entrambe le coordinate gia' usate, ripeto la procedura
//      this.cx = (int) (Math.random() * 100);
//      this.cy = (int) (Math.random() * 100);
      this.num = tot;
      tot++;
      System.out.println("Creato nodo " + this.num + " (" + this.cx + "," + this.cy + ")");
   }
}

Questo codice funziona senza nessuna difficoltà, se non quando arriva sui 140-150 nodi generati, dove la guardia del while (condx && condy) restituisce sempre TRUE e quindi il ciclo non si ferma... La condizione si verifica in quanto sia l'ascissa che l'ordinata del punto che devo creare sono già state utilizzate... Ora, questi nodi si inseriscono in un grafico di 100x100 interi, il che vuol dire 10000 nodi possibili senza sovrapposizioni (matematica di base). Il fatto che il programma entri in loop dopo soli 150 nodi mi porta a pensare a pensare che la funzione Random.next(101) faccia un po' schifo come generatrice di numeri... Ipotesi affermata anche dal fatto che se commento il ciclo e decommento le due righe subito sotto (ovvero tolgo il vincolo di non avere elementi sovrapposti) il programma funziona come si deve.
La mia domanda è: esiste un modo per potenziare la funzione Random.next(101) in modo che mi restituisca numeri molto più variabili?
E se non c'è, avete soluzioni alternative?

Grazie a tutti!
Ultima modifica di Delcaran Lëdeloth il mar dic 08, 2009 18:43, modificato 1 volta in totale.
Avatar utente
Delcaran Lëdeloth
Linux 2.0
Linux 2.0
 
Messaggi: 107
Iscritto il: mar mag 27, 2008 7:24
Località: Orsaria
Nome Cognome: Matteo Paoluzzi
Slackware: slackware-current
Kernel: 2.6.29.6-smp
Desktop: KDE 4.3.3

Re: [JAVA] Numeri casuali non ripetuti

Messaggioda kreen » mar dic 08, 2009 18:13

I linguaggi di programmazione normalmente, mettono a disposizione generatori di numeri pseudocasuali, che funzionano bene per la granparte degli utilizzi.
Se vuoi dei numeri realmente casuali, ti devi costruire una funzione su misura.

Ciao
Avatar utente
kreen
Linux 2.4
Linux 2.4
 
Messaggi: 228
Iscritto il: mer feb 01, 2006 18:32
Località: Verona
Slackware: 12.0
Kernel: 2.6.21.5-smp
Desktop: KDE

Re: [JAVA] Numeri casuali non ripetuti

Messaggioda Delcaran Lëdeloth » mar dic 08, 2009 18:18

Giustissimo, infatti è la prima volta in 10 anni di onesta programmazione con svariati linguaggi che mi trovo dinanzi ad un inconveniente simile... Sono dell'opinione che la colpa sia mia che non inizializzo come si deve il generatore dei numeri...
Avatar utente
Delcaran Lëdeloth
Linux 2.0
Linux 2.0
 
Messaggi: 107
Iscritto il: mar mag 27, 2008 7:24
Località: Orsaria
Nome Cognome: Matteo Paoluzzi
Slackware: slackware-current
Kernel: 2.6.29.6-smp
Desktop: KDE 4.3.3

Re: [JAVA] Numeri casuali non ripetuti

Messaggioda Delcaran Lëdeloth » mar dic 08, 2009 18:41

Come sempre la colpa è nell'utente :) la mia implementazione faceva davvero schifo! Ho risolto come segue:
Codice: Seleziona tutto
public class Nodo {

   private static int tot = 0; // numero dei nodi (solo per debug)
   private int num; // numero del nodo (debug)
   private int cx; // coordinata orizzontale
   private int cy; // coordinata verticale
   private static boolean[][] coordinate = new boolean[101][101]; // coordinate già usate
   private Random random = new Random();

   /**
    * Costruttore. Assegna le coordinate al nodo e lo imposta al gruppo iniziale come non rappresentante
    */
   public Nodo() {
      // imposto le coordinate impedendo nodi sovrapposti
      for (int x=0; x <101;x++)
         for (int y =0;y<101;y++)
            coordinate[x][y]=false;
      do {
         this.cx = random.nextInt(101);
         this.cy = random.nextInt(101);
      } while (coordinate[this.cx][this.cy]); // entrambe le coordinate gia' usate, ripeto la procedura
      coordinate[this.cx][this.cy]=true;
      this.cluster = 0;
      this.rappresentante = false;
      this.num = tot;
      tot++;
      System.out.println("Creato nodo " + this.num + " (" + this.cx + "," + this.cy + ")");
   }
}

Come avevo fatto prima vuol dire andarsele a cercare! Mi cospargo il capo di cenere :banghead:
Avatar utente
Delcaran Lëdeloth
Linux 2.0
Linux 2.0
 
Messaggi: 107
Iscritto il: mar mag 27, 2008 7:24
Località: Orsaria
Nome Cognome: Matteo Paoluzzi
Slackware: slackware-current
Kernel: 2.6.29.6-smp
Desktop: KDE 4.3.3


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite