Java willekeurige getallen met een seed

Dit is mijn code om willekeurige getallen te genereren met een seed als argument:

double randomGenerator(long seed) {
    Random generator = new Random(seed);
    double num = generator.nextDouble() * (0.5);
    return num;
}

Elke keer als ik een seed geef en probeer 100 getallen te genereren, zijn ze allemaal hetzelfde.
Hoe kan ik dit oplossen?


Antwoord 1, autoriteit 100%

Als je hetzelfde zaadje geeft, is dat normaal. Dat is een belangrijke functie die tests mogelijk maakt.

Vink dit aan om pseudo-willekeurige generatie en zaden te begrijpen:

Pseudorandom-nummergenerator

Een pseudo-random number generator (PRNG), ook bekend als een determinist
willekeurige bitgenerator DRBG, is een algoritme voor het genereren van een reeks
van getallen die de eigenschappen van willekeurige getallen benadert. De
volgorde is niet echt willekeurig in die zin dat het volledig bepaald wordt door
een relatief kleine set beginwaarden, de staat van de PRNG genoemd,
die een echt willekeurig zaadje bevat.

Als u verschillende sequenties wilt hebben (het gebruikelijke geval wanneer het algoritme niet wordt afgesteld of debuggen), moet u de nul-argumentconstructor aanroepen die de nanoTime gebruikt om elke keer een andere seed te krijgen. Deze Randominstantie moet natuurlijk buiten je methode worden gehouden.

Uw code zou er waarschijnlijk zo uit moeten zien:

private Random generator = new Random();
double randomGenerator() {
    return generator.nextDouble()*0.5;
}

Antwoord 2, autoriteit 36%

De gemakkelijke manier is om te gebruiken:

Random rand = new Random(System.currentTimeMillis());

Dit is de beste manier om Randomgetallen te genereren.


Antwoord 3, autoriteit 14%

Je zou geen nieuwe Random in methode scope moeten maken. Maak er een klaslid van:

public class Foo {
   private Random random 
   public Foo() {
       this(System.currentTimeMillis());
   }
   public Foo(long seed) {
       this.random = new Random(seed);
   }
   public synchronized double getNext() {
        return generator.nextDouble();
   }
}

Dit is slechts een voorbeeld. Ik denk niet dat het op deze manier inpakken van Randomenige waarde toevoegt. Zet het in een klas van jou die het gebruikt.


Antwoord 4, autoriteit 8%

Dat is het principe van een Pseudo-RNG. De cijfers zijn niet echt willekeurig. Ze worden gegenereerd met behulp van een deterministisch algoritme, maar afhankelijk van het zaad varieert de volgorde van gegenereerde getallen. Omdat je altijd dezelfde seed gebruikt, krijg je altijd dezelfde volgorde.


Antwoord 5, autoriteit 2%

Het probleem is dat je de random generator opnieuw seed. Elke keer dat je het zaait, wordt de beginstatus van de generator voor willekeurige getallen gereset en het eerste willekeurige getal dat je genereert, is het eerste willekeurige getal na de beginstatus


Antwoord 6

Als je meerdere getallen wilt genereren met één seed, kun je zoiets als dit doen:

public double[] GenerateNumbers(long seed, int amount) {
    double[] randomList = new double[amount];
    for (int i=0;i<amount;i++) {
        Random generator = new Random(seed);
        randomList[i] = Math.abs((double) (generator.nextLong() % 0.001) * 10000);
        seed--;
    }
    return randomList;
}

Het geeft dezelfde lijst weer als u hetzelfde zaad gebruikt.


Antwoord 7

Verschillende van de voorbeelden hier maken een nieuwe RandomExemplaar, maar dit is niet nodig. Er is ook geen reden om synchronizedte gebruiken als één oplossing. In plaats daarvan profiteer van de methoden op de ThreadLocalRandomKlasse:

double randomGenerator() {
    return ThreadLocalRandom.current().nextDouble(0.5);
}

Other episodes