Java Zufallszahlen mit Intervall

powerfx

Admiral
Registriert
Apr. 2009
Beiträge
9.351
Kurz mal eine Frage:

Wenn ich beispielsweise Float-Zufallszahlen in einem von beiden Seiten geschlossenen Interval erhalten möchte, hilft ja Random allein nicht weiter, da das obere Ende des Intervalls offen ist.

Wäre es vielleicht möglich, statt das Intervall zu vergrößern und dann mit if-Abfrage bzw. While-Schleife zu hantieren, sich Double-Zahlen aus dem gewünschten Intervall ausgeben zu lassen und sie dann zu Float umzuwandeln, so dass durch das Runden das Maximum doch erreicht wird?
 
meinezufallszahl = randomzahl%maxzahl...
Damit bekommst du den Rest, der immer kleiner als maxzahl ist und so in deinem Interval liegt...

mfg
mitos
 
Zuletzt bearbeitet:
Danke,

ich glaube aber, dass ich vergessen habe zu sagen, dass die Verteilung gleich sein soll, d.h. jede mögliche Zahl aus dem Intervall (inkl. Grenzen, also geschlossenes Intervall) mit der gleichen Wahrscheinlichkeit vorkommen soll.

Nehmen wir z.B. als Intervall [1,2]:

PHP:
Random generator = new Random();
zufallswert = generator.nextFloat();
System.out.println((zufallswert+1);
würde nicht gehen, denn es erzeugt lediglich Zufallszahlen im Intervall [1,2) = [1,2[
(2 ist nie dabei).

PHP:
Random generator = new Random();
while (zufallswert > 2){
	zufallswert = generator.nextFloat();
	zufallswert = (zufallswert*2)+1;
}
System.out.println(zufallswert);
würde das Problem lösen, ist aber nicht besonders effizient.

Wenn man jetzt aber die erste Methode nimmt, nur Float durch Double ersetzt und den zurückgegebenen Wert wieder zu Float umwandelt, entsteht dann nicht das komplette Intervall [1,2]?
 
Hallo,

Mir ist nicht ganz klar, was genau das Problem ist!?

Hier noch folgendes:

Code:
int offset = 0;
int max = 2;
Random generator = new Random();
float zufallswert = generator.nextFloat();
System.out.println(((zufallswert+offset)*100)%max);

Damit gehts von 0 bis 2, du kannst es mit offset und max (max<100) so anpassen, wie du es brauchst...

mfg
mitos
 
Zuletzt bearbeitet:
Ich versteh dein Problem und die Lösung von mitos sieht doch ganz gut aus... Was ich nicht verstehe ist was du damit bezweckst float Zahlen nach double zu konvertieren bzw. andersherum um dabei Rundungen zu erzeugen...?! Ja okay, irgendwo 5 Stellen nach dem Komma...
 
Zuletzt bearbeitet:
Nein, gegen mitos' Lösung habe ich absolut nichts einzuwenden (aber ist das wirklich eine Gleichverteilung?).

Es ging eigentlich nur darum, dass nextFloat() Zufallszahlen zwischen 0 und 0,9999999... erzeugt.
Die "1" kommt nie vor.
Wenn das aber gefordert ist. war meine Idee Doubles erzeugen zu lassen: nextDouble() und dann zu Floats umzuwandeln (das ist ja relativ einfach). Durch das Casting (und Rundung?) würde evtl. 0,99999999... zu "1" werden.

Oder nicht?
 
Kurze praktische Frage:
Wenn du sowieso mit Gleitpunktzahlen arbeitest interessiert es dich überhaupt, ob die Zufallszahl nun genau 0 oder 1 (oder jedes beliebige Intervall) ist?

1.
Das menschliche Gehirn wird da keinen großen Unterschied feststellen (z.B. optische Wahrnehmung).

2.
Wenn du aufgrund dieser Zufallszahl eine Fallunterscheidung machen willst, wirst du um eine Epsilon-Schranke (Diskretisierung) nicht herumkommen. Ob der Wert nun 0.999999999999 oder 1 ist sollte dann ziemlich egal sein.

3.
Wenn diese Zufallszahl (oder viele solche Zufallszahlen) Bestandteil einer großen Gleichung ist kann man durchaus Probleme bekommen, v.a. bei einer multiplikativen Verknüpfung (z.B. Wahrscheinlichkeiten). Aber selbst 0.9999^99 = 0.99 ist noch relativ hoch. Und wie hoch ist die Wahrscheinlichkeit, dass 99x hintereinander eine Zufallszahl >= 0.9999 berechnet wird? Ziemlich gering! Und die Wahrscheinlichkeit, dass eine Zahl z.B. < 0.5 gezogen wird ist bei einer Gleichverteilung sehr hoch. Genau diese Zahl wird das Ergebnis aber signifikant beeinflussen.

Ich kann mir im Moment einfach kein (praktisches) Problem vorstellen, bei dem es einen großen Unterschied macht...
 
Zuletzt bearbeitet:
Ich habe da mal eine kurze Zwischenfrage:

Wieso ist dir die 1 so wichtig? Wenn du float/double benutzt hast du so oder so viele Löcher im Definitionsbereich, denn ein Interval im mathematischen Sinne bekommst du damit nie. Daher testet man solche Werte ja auch nicht auf Gleichheit, sondern auf eine Epsilon-Umgebung und in der ist 1 mit drin. Du kannst ja z.B. auch keine 1/3 oder 1/7 als Ergebnis bekommen.
 
Gluehwurm schrieb:
Kurze praktische Frage:
Wenn du sowieso mit Gleitpunktzahlen arbeitest interessiert es dich überhaupt, ob die Zufallszahl nun genau 0 oder 1 (oder jedes beliebige Intervall) ist?
Ganz einfach: Weil es die Aufgabenstellung ist. :)

@ Gluehwurm:
Ja, Praktisches gibt es hier nichts. Ist eben nur Theorie. Und wenn es eben eine Gleichverteilung z.B. im Intervall [0,1] sein soll, kann man es nicht umgehen, da sonst das gegebene Problem nicht gelöst ist. Da die Laufzeit aber erstmal weniger wichtig ist, passt ja auch meine erste Lösung mit der if-Abfrage. Ich wollte nur die Effizienz etwas erhöhen...
 
Zurück
Oben