1. Pseudo-willekeurige getallen

Soms staat een programmeur voor schijnbaar eenvoudige taken: "selecteer een willekeurige film uit een bepaalde lijst", "kies een loterijwinnaar", "shuffle de afspeellijst wanneer de gebruiker zijn of haar smartphone schudt", "kies een willekeurig nummer om een ​​bericht te versleutelen" , enz. In elk geval stelt de ontwikkelaar een logische vraag: hoe kom je aan een willekeurig getal?

Eigenlijk is het nogal moeilijk om een ​​echt willekeurig getal te krijgen. Het is zelfs zo moeilijk dat in sommige computers speciale wiskundige coprocessors zijn ingebouwd om getallen te genereren die voldoen aan alle vereisten voor echte willekeur.

Programmeurs bedachten hun eigen oplossing: pseudowillekeurige getallen . Pseudo-willekeurige getallen zijn een soort reeks waarvan de getallen willekeurig lijken. Door een zorgvuldige analyse uit te voeren, kan een expert echter bepaalde patronen in de reeks vinden. Dergelijke nummers zijn niet geschikt om geheime documenten te versleutelen, maar ze zijn voldoende om het werpen van een dobbelsteen in een spel te simuleren.

Er zijn veel algoritmen voor het genereren van een reeks pseudowillekeurige getallen. Bijna allemaal genereren ze het volgende willekeurige nummer op basis van het vorige nummer en enkele extra helpernummers.

Dit programma zal bijvoorbeeld 1000niet-herhalende nummers weergeven:

public class Main
{
   public static int a = 41;
   public static int c = 11119;
   public static int m = 11113;
   public static int seed = 1;

   public static int getNextRandom()
   {
     seed = (a * seed + c) % m;
     return seed;
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 1000; i++)
     {
       System.out.println(getNextRandom());
     }
   }
}

We hebben het hier trouwens niet over pseudowillekeurige getallen. We hebben het over een reeks pseudowillekeurige getallen. Als je naar een enkel nummer kijkt, is het onmogelijk om te zeggen of het willekeurig is of niet.

Er zijn inderdaad verschillende manieren om een ​​willekeurig getal te krijgen:

public static int getRandomNumber()
{
   return 4; // Here's a random number (we got it by rolling a die)
}

2.Math.random()

In Java Mathheeft de klasse een speciale methode die een willekeurig getal retourneert. En zoals je misschien wel raadt, heet de methode random. Over het algemeen ziet het er als volgt uit om deze methode te noemen:

Math.random()

Deze methode neemt geen parameters en retourneert een pseudo-willekeurig reëel getal in het bereik van 0tot 1. Het nummer 1 zelf is niet in het assortiment opgenomen.

Voorbeeld:

Code Console-uitvoer
public class Main
{
   public static void main(String[] args)
   {
     for (int i = 0; i < 10; i++)
     {
       System.out.println(Math.random());
     }
   }
} 
0.9703753971734451
0.09979423801773157
0.994048474709053
0.2852203204171295
0.13551248551226025
0.3128547131272822
0.5342480554101412
0.6817369932044817
0.1840767788961758
0.06969563435451254

Maar wat als deze methode niet helemaal is wat je nodig hebt? Stel dat u een programma wilt schrijven dat het gooien van een zeszijdige dobbelsteen simuleert. Hoe krijg je willekeurige gehele getallen in het bereik 1..6, in plaats van reële getallen in het bereik 0..1?

Het is eigenlijk vrij eenvoudig.

Eerst moet u het bereik toewijzen [0, 1)aan [0, 6). Om dit te doen, vermenigvuldigt u eenvoudigweg het geretourneerde resultaat random()met 6. Om gehele getallen te krijgen, moet je natuurlijk naar boven afronden:

Code Console-uitvoer
public class Main
{
   public static int getRandomDieNumber()
   {
      return (int) (Math.random() * 6);
   }

   public static void main(String[] args)
   {
      for (int i = 0; i < 10; i++)
      {
         int x = getRandomDieNumber();
         System.out.println(x);
      }
   }
}
5
2
3
3
2
4
1
1
5
0

De getRandomDieNumber()retourneert een willekeurig geheel getal in het bereik 0..5inclusief. Maar het zal geen nummer in de set zijn 1, 2, 3, 4, 5, 6. Het wordt een nummer in de set 0, 1, 2, 3, 4, 5.

Als je nummers in de set nodig hebt 1, 2, 3, 4, 5, 6, voeg er dan gewoon een toe aan de willekeurige nummers:

Code Console-uitvoer
public class Main
{
   public static int getRandomDieNumber()
   {
      return (int) (Math.random() * 6) + 1;
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 10; i++)
     {
       int x = getRandomDieNumber();
       System.out.println(x);
     }
   }
}
3
2
1
3
6
5
6
1
6
6

Dat is perfect!



3. Randomklasse

Java heeft een speciale Randomklasse die een reeks pseudowillekeurige getallen inkapselt. U kunt verschillende objecten van de Randomklasse maken. Elk van deze objecten genereert zijn eigen reeks pseudowillekeurige getallen.

Dit is een super interessante les met veel interessante methodes. Laten we beginnen met de eenvoudigste.

double nextDouble()

Deze methode retourneert een willekeurig reëel getal in het bereik 0.0- 1.0. Het lijkt erg op de Math.random()methode. En geen wonder, aangezien de Math.random()methode gewoon de nextDouble()methode op een Randomobject aanroept.

float nextFloat()

Deze methode lijkt sterk op de nextDouble()methode, maar het geretourneerde willekeurige getal is een float. Het ligt ook in het assortiment 0.0- 1.0. En, zoals altijd in Java, omvat het bereik niet het nummer 1.0zelf.

Random r = new Random();
float f = r.nextFloat();

int nextInt(int max)

Deze methode retourneert een willekeurig geheel getal in het bereik [0, max). 0zit wel in het assortiment, maar maxis het niet.

Met andere woorden, als u een willekeurig getal in de set wilt krijgen 1, 2, 3, 4, 5, 6, moet u er een toevoegen aan het geretourneerde willekeurige getal:

Random r = new Random();
int x = r.nextInt(6) + 1;

int nextInt()

Deze methode is vergelijkbaar met de vorige, maar er zijn geen parameters voor nodig. Dus wat is het bereik voor de retourwaarden? Van -2 billiontot +2 billion.

Om precies te zijn, van -2147483648tot +2147483647.

long nextLong()

Deze methode is vergelijkbaar met de nextInt()methode, maar de geretourneerde waarde valt ergens in het hele mogelijke bereik van longs.

boolean nextBoolean()

Deze methode retourneert een willekeurige booleanwaarde: falseof true. Dit is erg handig wanneer u een lange reeks willekeurige Booleaanse waarden moet krijgen.

void nextBytes(byte[] data)

Deze methode retourneert niets (aangezien het retourtype void). In plaats daarvan vult het de doorgegeven array met willekeurige waarden. Dit is erg handig wanneer u een grote buffer nodig heeft die gevuld is met willekeurige gegevens.

double nextGaussian()

Deze methode retourneert een willekeurig reëel getal in het bereik 0.0- 1.0. De aantallen zijn echter niet gelijkmatig verdeeld in dit bereik. In plaats daarvan volgen ze een normale verdeling .

Waarden in het midden van het bereik ( 0.5) zullen vaker voorkomen dan waarden aan het einde van het bereik.

Willekeurige klasse

In ons geval zal de piek van de waardeverdeling liggen op0.5