1. Pseudorandom na mga numero
Minsan ang isang programmer ay nahaharap sa tila simpleng mga gawain: "pumili ng random na pelikula mula sa isang partikular na listahan", "pumili ng nanalo sa lottery", "shuffle ang playlist kapag inalog ng user ang kanyang smartphone", "pumili ng random na numero para i-encrypt ang isang mensahe" , atbp. Sa bawat kaso, nagtatanong ang developer ng lohikal na tanong: paano makakuha ng random na numero?
Sa totoo lang, ang pagkuha ng tunay na random na numero ay medyo mahirap gawin. Sa katunayan, napakahirap na ang mga espesyal na mathematical coprocessor ay binuo sa ilang mga computer upang makabuo ng mga numero na nakakatugon sa lahat ng mga kinakailangan para sa tunay na randomness.
Ang mga programmer ay gumawa ng sarili nilang solusyon: mga pseudorandom na numero . Ang mga pseudorandom na numero ay isang uri ng pagkakasunud-sunod, na ang mga numero ay tila random. Gayunpaman, sa pamamagitan ng pagsasagawa ng maingat na pagsusuri, makakahanap ang isang eksperto ng ilang partikular na pattern sa pagkakasunud-sunod. Ang mga naturang numero ay hindi angkop para sa pag-encrypt ng mga lihim na dokumento, ngunit sapat na ang mga ito para gayahin ang roll ng isang die sa isang laro.
Mayroong maraming mga algorithm para sa pagbuo ng isang pagkakasunud-sunod ng mga pseudorandom na numero. Halos lahat sa kanila ay bumubuo ng susunod na random na numero batay sa nakaraang numero at ilang karagdagang numero ng katulong.
Halimbawa, ang program na ito ay magpapakita ng 1000
mga hindi umuulit na numero:
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());
}
}
}
Sa pamamagitan ng paraan, hindi namin pinag-uusapan ang mga pseudorandom na numero dito. Pinag-uusapan natin ang tungkol sa pagkakasunod-sunod ng mga pseudorandom na numero. Sa pagtingin sa isang solong numero, imposibleng sabihin kung ito ay random o hindi.
Sa katunayan, may iba't ibang paraan para makakuha ng random na numero:
public static int getRandomNumber()
{
return 4; // Here's a random number (we got it by rolling a die)
}
2.Math.random()
Sa Java, ang Math
klase ay may espesyal na paraan na nagbabalik ng random na numero. At tulad ng maaari mong hulaan, ang pamamaraan ay tinatawag na random
. Sa pangkalahatan, narito ang hitsura ng pagtawag sa paraang ito:
Math.random()
Ang pamamaraang ito ay walang mga parameter at nagbabalik ng pseudorandom na tunay na numero sa hanay mula 0
hanggang 1
. Ang numero 1 mismo ay hindi kasama sa hanay.
Halimbawa:
Code | Output ng console |
---|---|
|
|
Ngunit paano kung ang pamamaraang ito ay hindi kung ano ang kailangan mo? Ipagpalagay, gusto mong magsulat ng isang programa na gayahin ang pag-roll ng isang anim na panig na mamatay. Paano ka makakakuha ng mga random na integer sa hanay na 1..6, sa halip na mga tunay na numero sa hanay na 0..1?
Ito ay talagang medyo simple.
Una, kailangan mong imapa ang hanay [0, 1)
sa [0, 6)
. Upang gawin ito, i-multiply lang ang resulta na ibinalik random()
ng 6
. Siyempre, upang makakuha ng mga integer, kailangan mong i-round up:
Code | Output ng console |
---|---|
|
|
Nagbabalik ang getRandomDieNumber()
isang random na integer sa saklaw 0..5
na kasama. Ngunit hindi ito magiging isang numero sa set 1, 2, 3, 4, 5, 6
. Ito ay magiging isang numero sa set 0, 1, 2, 3, 4, 5
.
Kung ang kailangan mo ay mga numero sa set 1, 2, 3, 4, 5, 6
, magdagdag lang ng isa sa mga random na numero:
Code | Output ng console |
---|---|
|
|
Ngayon ay perpekto na!
3. Random
klase
Ang Java ay may espesyal Random
na klase na sumasaklaw sa isang sequence ng mga pseudorandom na numero. Maaari kang lumikha ng ilang mga bagay ng Random
klase. Ang bawat isa sa mga bagay na ito ay bubuo ng sarili nitong sequence ng mga pseudorandom na numero.
Ito ay isang sobrang kawili-wiling klase na may maraming kawili-wiling pamamaraan. Magsimula tayo sa pinakasimpleng.
double nextDouble()
Ang pamamaraang ito ay nagbabalik ng random na tunay na numero sa hanay 0.0
- 1.0
. Ito ay halos kapareho sa Math.random()
pamamaraan. At hindi nakakagulat, dahil ang Math.random()
pamamaraan ay tinatawag lamang ang nextDouble()
pamamaraan sa isang Random
bagay.
float nextFloat()
Ang pamamaraang ito ay halos kapareho sa nextDouble()
pamamaraan, ngunit ang ibinalik na random na numero ay isang float
. Ito rin ay namamalagi sa hanay 0.0
- 1.0
. At, gaya ng nakasanayan sa Java, hindi kasama sa range ang numero 1.0
mismo.
Random r = new Random();
float f = r.nextFloat();
int nextInt(int max)
Ang pamamaraang ito ay nagbabalik ng random na integer sa hanay [0, max)
. 0
ay kasama sa hanay, ngunit max
hindi.
Sa madaling salita, kung gusto mong makakuha ng random na numero sa set 1, 2, 3, 4, 5, 6
, kailangan mong magdagdag ng isa sa ibinalik na random na numero:
Random r = new Random();
int x = r.nextInt(6) + 1;
int nextInt()
Ang pamamaraang ito ay katulad ng nauna, ngunit hindi ito kumukuha ng anumang mga parameter. Kaya ano ang saklaw para sa mga halaga ng pagbabalik nito? Mula -2 billion
sa +2 billion
.
Well, upang maging tumpak, mula -2147483648
sa +2147483647
.
long nextLong()
Ang pamamaraang ito ay katulad ng nextInt()
pamamaraan, ngunit ang halaga ng pagbabalik ay mahuhulog sa isang lugar sa buong posibleng hanay ng long
s.
boolean nextBoolean()
Ang pamamaraang ito ay nagbabalik ng random boolean
na halaga: false
o true
. Ito ay napaka-maginhawa kapag kailangan mong makakuha ng mahabang pagkakasunud-sunod ng mga random na halaga ng boolean.
void nextBytes(byte[] data)
Ang pamamaraang ito ay walang ibinabalik (dahil ang uri ng pagbabalik ay void
). Sa halip, pinupuno nito ang naipasa na array ng mga random na halaga. Ito ay napakadaling gamitin kapag kailangan mo ng malaking buffer na puno ng random na data.
double nextGaussian()
Ang pamamaraang ito ay nagbabalik ng random na tunay na numero sa hanay 0.0
- 1.0
. Gayunpaman, ang mga numero ay hindi pantay na ipinamamahagi sa hanay na ito. Sa halip, sinusunod nila ang isang normal na pamamahagi .
Ang mga value na malapit sa gitna ng range ( 0.5
) ay magaganap nang mas madalas kaysa sa mga value sa dulo ng range.
Sa aming kaso, ang rurok ng pamamahagi ng halaga ay nasa0.5
GO TO FULL VERSION