Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung
-
Hallo, ich möchte einen zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung in der Mitte angegeben durch a... deshalb schaue ich in einer Schleife, ob der Wert <0 oder >1 ist und verwerfe in diesen Fällen:
/** * @param from lower bound * @param to upper bound * @param a factor between 0.0 and 1.0 * @return a random double value */ public static double getRandomDouble(double from, double to, double a) { double g; do { g = (new Random().nextGaussian() + 1.0) / 2.0; } while (g < 0 || g > 1); if (g < 0.5) { g += (0.5 - g) * a * a; } else if (g > 0.5) { g -= (g - 0.5) * a * a; } return g * (to - from) + from; }
Nun zu meiner Frage, kann der Code vereinfacht werden oder kann ich die do-while-Schleife vermeiden? Oder gibts vielleicht etwas Besseres als
new Random().nextGaussian()
? Vielen Dank.Edit: In C/C++ wird das wahrscheinlich ähnlich möglich sein...
-
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Oder gibts vielleicht etwas Besseres als new Random().nextGaussian()?
Alles ist besser als new Random() in einer Schleife.
-
@manni66 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Alles ist besser als new Random() in einer Schleife.
Um Performance geht es nicht.
-
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
In C/C++ wird das wahrscheinlich ähnlich möglich sein...
Dafür gibts std::normal_distribution
-
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
@manni66 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Alles ist besser als new Random() in einer Schleife.
Um Performance geht es nicht.
Um Intelligenz auch nicht.
-
@manni66 Ich glaub' es reicht dann auch wieder.
@EinNutzer0 Tut's org.apache.commons.math3.distribution.NormalDistribution nicht?
-
@Swordfish sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
@EinNutzer0 Tut's org.apache.commons.math3.distribution.NormalDistribution nicht?
Das ist eine zusätzliche Lib.
Warum ist @manni66 so unfreundlich? Ich werde hier nichts mehr schreiben, dann kann er sich von mir aus in seinem eigenen Saft suhlen. Irgendwann sollte man doch mal normale Umgangsformen gelernt haben.
-
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Das ist eine zusätzliche Lib.
deren Code Du Dir ansehen kannst.
-
@Swordfish sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Das ist eine zusätzliche Lib.
deren Code Du Dir ansehen kannst.
Ja werde ich machen. Danke.
-
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Um Performance geht es nicht.
Zack, downvote. Nur warum? Meiner Meinung nach eine völlig legitime Handlungsweise, Probleme erst zu verstehen, bevor man sich über die Performance Gedanken macht.
Ist doch (glücklicherweise?) nicht stackoverflow hier.
-
new Random()
in einer Loop hat nicht nur Performanceprobleme. Man hat dann nicht mehr das normalerweise garantierte Verhalten von Random, sondern man erzeugt "irgendwie" immer neue prngs. Der seed soll laut Java-Doku bei jedem Aufruf möglichst anders sein, aber wie genau er erzeugt wird, ist nicht klar definiert. Welches Verhalten haben also die hier generierten Zufallszahlen?Es ist nun eben einfach nicht sinnvoll, einen prng hier in der Loop immer neu zu erzeugen.
-
@wob sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
new Random()
in einer Loop hat nicht nur Performanceprobleme. Man hat dann nicht mehr das normalerweise garantierte Verhalten von Random, sondern man erzeugt "irgendwie" immer neue prngs. Der seed soll laut Java-Doku bei jedem Aufruf möglichst anders sein, aber wie genau er erzeugt wird, ist nicht klar definiert. Welches Verhalten haben also die hier generierten Zufallszahlen?Es ist nun eben einfach nicht sinnvoll, einen prng hier in der Loop immer neu zu erzeugen.
Die Entropie und Güte der Zufallswerte wird dadurch nicht beeinflusst (sprich: Die Semantik bleibt dieselbe). Aber hier noch mal neu:
/** * @param from lower bound * @param to upper bound * @param a factor between 0.0 and 1.0 * @return a random double value in bounds */ @SuppressWarnings("unused") public static double getRandomDouble(double from, double to, double a) { Random random = new Random(); double g; do { g = (random.nextGaussian() + 1.0) / 2.0; } while (g < 0 || g > 1); if (g < 0.5) { g += (0.5 - g) * a * a; } else if (g > 0.5) { g -= (g - 0.5) * a * a; } return g * (to - from) + from; }
Und ich hab mich auch etwas informiert, die
new BetaDistribution(2.0, 2.0).sample();
gibt das gewünschte Ergebnis zurück.
-
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Die Entropie und Güte der Zufallswerte wird dadurch nicht beeinflusst (sprich: Die Semantik bleibt dieselbe).
Beweis durch Behauptung?
-
@wob sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Die Entropie und Güte der Zufallswerte wird dadurch nicht beeinflusst (sprich: Die Semantik bleibt dieselbe).
Beweis durch Behauptung?
Random
wählt den seed unter anderem anhand der Nanosystemzeit. Dadurch ist eine ausreichende seed-Entropie sichergestellt. Der Zustand des Systems kann praktisch auch nicht so genau beobachtet werden, dass der seed reproduzierbar wäre (Werner Heisenbergs Unschärferelation).Es könnte lediglich (theoretisch) passieren, dass zwei
getRandomDouble
-Aufrufe zeitlich so nah beieinander liegen, dass sie denselben Wert berechnen und zurückgeben... Aber dann hilft eine lokale Variable (Zeile 9) auch nicht... dann braucht man eine Objekt- oder Klassenvariable.
-
manni66 hat Recht.
-
Der Beweis geht quasi direkt aus dem Kommentar/Source hervor:
/** * Creates a new random number generator. This constructor sets * the seed of the random number generator to a value very likely * to be distinct from any other invocation of this constructor. */ public Random() { this(seedUniquifier() ^ System.nanoTime()); } private static long seedUniquifier() { // L'Ecuyer, "Tables of Linear Congruential Generators of // Different Sizes and Good Lattice Structure", 1999 for (;;) { long current = seedUniquifier.get(); long next = current * 1181783497276652981L; if (seedUniquifier.compareAndSet(current, next)) return next; } }
http://www.java2s.com/example/java-src/pkg/java/util/random-fd044.html
@SeppJ sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
manni66 hat Recht.
Womit hat er recht? Wie man sich danebenbenimmt?
-
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Random wählt den seed unter anderem anhand der Nanosystemzeit. Dadurch ist eine ausreichende seed-Entropie sichergestellt.
Ähm. Vielleicht einmalig. Aber sicher nicht beim Wiederholen.
Der Zustand des Systems kann praktisch auch nicht so genau beobachtet werden, dass der seed reproduzierbar wäre (Werner Heisenbergs Unschärferelation).
Ich sehe einen im Grab rotierenden Heisenberg.
-
@wob sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Ich sehe einen im Grab rotierenden Heisenberg.
Es könnte lediglich (theoretisch) passieren, dass zwei getRandomDouble-Aufrufe zeitlich so nah beieinander liegen, dass sie denselben Wert berechnen und zurückgeben...
Das war irgendwie falsch formuliert... Das kann eigentlich gar nicht passieren.
Dennoch hat, wo das
new Random()
nun genau vorkommt, gar nichts mit meiner Frage zu tun!
-
@EinNutzer0 Du willst normalverteilte Zufallsvariablen haben, richtig? Warum sollten die ersten Werte der Zufallsreihen verschieden initialisierter Zufallsgeneratoren normalverteilt sein? Garantiert ist das für die Werte eines Zufallsgenerators.
-
@EinNutzer0 sagte in Zufälligen nextGaussian-Wert zwischen zwei Grenzen mit einer Häufung:
Dennoch hat, wo das
new Random()
nun genau vorkommt, gar nichts mit meiner Frage zu tun!Eine deiner Fragen war (Zitat) "Oder gibts vielleicht etwas Besseres als new Random().nextGaussian()?" (Zitat Ende). Ja, gibt es. Trennen von "new Random()" und dem "nextGaussian()". Aber für mich ist jetzt Ende.
-
@Schlangenmensch :
#nextGaussian()
ist eine Methode vonRandom
basierend auf dessen seed.