# Random() : Bereich festelgen



## hdi (28. Jan 2008)

Hi, ich möchte mir Zufallszahlen im Bereich von 0 bis 3 erzeugen lassen.

Ich werd aber aus der manpage von der Klasse Rando nicht schlau.

Da gibt es nur einen Konstruktor mit irgendeinem long-wert, genannt "seed". Weiss gar nicht was das bedeutet.

Finde auch keine Methode für sowas irgendwie.

Wie kann ich denn den Zahlenbereich des Generators einstellen?

Danke.


----------



## Pappenheimer++ (28. Jan 2008)

```
import java.util.Random;
class Test 
{
//...........
Random rnd=new Random();
int z=rnd.nextInt(4); //liefert zahlen zwischen 0 (inklusive) und 4 (exklusive)
}
```


----------



## Guest (28. Jan 2008)

oder so:


```
1 + (int)(Math.random() * 3);
```


----------



## SlaterB (28. Jan 2008)

seed ist eine Einstellung von Random, wenn du mit seed 1452 anfängst,
dann kommen vielleicht als erstes die Zufallszahlen 45, 34, 9 und 1003

nun kannst du dir sicher sein, dass diese Zahlen immer kommen werden, wenn du einen neuen Random mit seed 1452 erstellst


-----------

> Wie kann ich denn den Zahlenbereich des Generators einstellen? 

nextInt(int n) 


die seed-Zahlen weiter oben sind natürlich abstrakt zu sehen,
oder vielleicht als double-Werte zwischen 0 und 1,
wenn du nextInt(4) aufrufst, bekommst du vielleicht nur 3,3, 2,3,0
aber auf jeden Fall bei jeder Ausführung die gleichen, wenn du immer alles gleich machst


----------



## tincup (29. Jan 2008)

Anonymous hat gesagt.:
			
		

> oder so:
> 
> 
> ```
> ...



Das erzeugt aber nur die Zahlen 1,2 und 3.


----------



## Ariol (29. Jan 2008)

```
1 + (Math.random() * 3);
```


----------



## Backwardsman (29. Jan 2008)

"seed" = "saat" ist der start-wert für einen (pseudo)zufallszahlengenerator. wie schon erwähnt ist eine reihe von zufallszahlen reproduzierbar, sofern man den gleichen seed-wert nimmt. typischerweise will man ja, dass die zahlen möglichst "zufällig" sind, deshalb verwenden viele als startwert einfach die aktuelle systemzeit, so dass von einem anderen der start-wert nicht geraten werden kann, schließlich hätte der andere dann ja alle zufallszahlen und könnte auch zukünftige zahlen bestimmen. bei extrem sicherheitskritischen anwendungen verlässt man sich dann übrigens nicht mal mehr auf die systemzeit...

mit der nextRandom() funktion bekommst du zahlen zwischen 0.0 und 1.0... ich würde diese zahlen jetzt einfach mit 10 multiplizieren, dann erhälst du zahlen zwischen 0.0 und und 10.0 und alle wegschmeißen die kleiner 0 oder größer 3 sind...


```
Random rand = new Random(System.currentTimeMillis());
	double x = -1;
	while (x < 0 || x > 3) {
		x = 10 * rand.nextDouble();
	}
	System.out.println(x);
```


----------



## SlaterB (29. Jan 2008)

<0 geht eh nicht

was hat es für einen Sinn, mit 10 zu multiplizieren und 70% wegzuschmeißen?
wenn überhaupt, dann mal 4 und 25% wegschmeißen, oder mal 3.000000001 und sehr wenig wegschmeißen

aber das nur, damit der Wert 3 kommen kann?
wollen wir mal die Wahrscheinlichkeit ausrechnen, dasss jemals genau 3.000000000 kommt? 
falls das überhaupt möglich ist, denn dann müsste die Original-Zufallszahl
0.300000000000 oder 0.75000000000 sein, was auch nicht gerade leicht ist

wenn die 3.00000 nicht dazugehören muss, dann ganz simpel * 3 ohne while-Schleife,

wenn es eh um ints geht, dann nextInt(4)


----------



## tincup (29. Jan 2008)

Also das mit dem mit 10 multiplizieren erschliesst sich mir auch nicht ganz. Und mit der 3 auch nicht, denn wenn ich die 3 nur mit einer verschwindend kleinen Wahrscheinlichkeit, oder generell mit einer anderen Wahrscheinlichkeit als 0, 1 oder 2 erwische, ist das ganze Ding ja völlig unbrauchbar.

Wüsste auch nicht, wo das Problem an (int)(Math.random() * 4) liegen soll, 4 kommt da nicht raus weil laut API explizit Math.random() einen Wert >= 0 aber < 1 rausgibt. Ob sich Random#nextDouble auch so verhält ist nicht ganz klar ersichtlich aus der Doku.


----------



## Ariol (29. Jan 2008)

Ob das hier das Problem löst weiss ich leider nicht, aber versuchen kannst du's ja mal:


```
double ausgleicher = Math.random()+Math.random();
		while(ausgleicher > 1)
		{
			ausgleicher -= Math.random();
		}
		
		double zufallsZahl = ausgleicher*Math.random()*3;
```


----------



## SlaterB (29. Jan 2008)

jetzt drehen hier alle durch


----------



## Ariol (29. Jan 2008)

Ähm...erst jetzt


----------



## Backwardsman (30. Jan 2008)

also ich habe mal 10 genomnen, weil *3 nicht ausreicht! in der doku steht "from the range 0.0d (inclusive) to 1.0d (exclusive)", also ohne 1.0 und dann käme der wert 3.0 niemals vor. mit 4 multiplizieren ist doch auch quatsch, weil dann werte bis 3.999...96 rauskommen, was laut des ersten beitrags ja nicht der fall sein soll, oder? ... wollt einfach nur ne nummer sicher gehen... außerdem handelt es sich um eine anfänger-frage und hab angenommen, dass jetzt effizienz nicht so die super-wichtige rolle spielt (das 70% weggeschmissen werden stimmt ja immerhin)... letztendlich wäre es wie bereits schon erwähnt totaler quatsch die systemzeit als seed zu nehmen, was die zufallszahlen eh alle im voraus berechenbar macht!


----------



## SlaterB (30. Jan 2008)

> mit 4 multiplizieren ist doch auch quatsch, weil dann werte bis 3.999...96 rauskommen

wenn man deine Abfrage mit größer 3 drinlässt, dann ist es das gleiche wie bei 10,
nur mit 25% Verlust statt 70%,
klar ist das nur ne Spielerei, aber es gibt doch nicht den Hauch eines Grundes, 5, 10, 59996 oder irgendeine andere Zahl größer 4 zu nehmen
(3.0000001 reicht auch, aber da wirds langsam unschön, wobei das ganze System natürlich wenig Sinn macht)


----------



## tincup (30. Jan 2008)

Irgendwie ist das hier alles komisch :wink: so schwer ist das ganze doch nun nicht.

Wenn ich mit 4 malnehme ist das nicht quatsch sondern exakt der Weg zum Ziel. Ich erhalte approximativ gleichverteilt die Zahlen 0, 1, 2 und 3, das war das vom Original-Poster geforderte. Eben genau dass es nur bis 3,999xxx geht ist ja der Grund, warum das funktioniert! 

Die zweite Frage war nach dem Seed, die wurde aber beantwortet, ist halt für die Initialisierung des Pseudo!-Random-Number Generators.


----------



## SlaterB (30. Jan 2008)

tincup, du verfolgst da was anderes, du willst danach ja noch auf int abrunden, da kann man dann auch gleich nextInt(4) nehmen,

Backwardsman hatt ja schon die Idee, den double ganz zu behalten, aber nur genau bis maximal 3.00000 (nicht 2.99999),
das ist ein anderes Thema


----------



## tincup (30. Jan 2008)

Hier nochmal der Beweis, dass es funktioniert (wenn auch eher empirisch als mathematisch):

1 Milliarde Zufallszahlen, dann die relative Häufigkeit ausgegeben, wie oft welche kam. Paar Millionen hättens wohl auch getan.


```
int c[] = new int[4];
final int total = 1000000000;
for (int i=0; i<total; i++) {
	c[(int)(Math.random()*4)]++;
}
System.out.println((float)c[0]/(float)total);
System.out.println((float)c[1]/(float)total);
System.out.println((float)c[2]/(float)total);
System.out.println((float)c[3]/(float)total);
```

Ergibt


```
0.2500188
0.24999553
0.24999027
0.2499954
```

Keine Index Out Of Bounds exception, also auch keine falschen Zahlen. Was will man mehr.

Grüsse, 
 Tin


----------



## tincup (30. Jan 2008)

Das mit den nextInt ist schon richtig aber hier wurden ja die dubiosesten Sachen behauptet die nicht funktionieren können, da wollte ich mal zeigen, dass er klassische Weg halt richtig ist.


----------

