1. เลขสุ่มเทียม
บางครั้งโปรแกรมเมอร์ต้องเผชิญกับงานที่ดูเหมือนง่าย: "เลือกภาพยนตร์แบบสุ่มจากรายการที่ต้องการ", "เลือกผู้ชนะลอตเตอรี", "สุ่มเพลย์ลิสต์เมื่อผู้ใช้เขย่าสมาร์ทโฟน", "เลือกหมายเลขสุ่มเพื่อเข้ารหัสข้อความ" ฯลฯ ในแต่ละกรณี ผู้พัฒนาจะถามคำถามเชิงตรรกะ: จะรับตัวเลขสุ่มได้อย่างไร
จริงๆ แล้ว การหาตัวเลขสุ่มจริงๆ นั้นค่อนข้างยาก ในความเป็นจริง เป็นเรื่องยากมากที่ตัวประมวลผลร่วมทางคณิตศาสตร์แบบพิเศษจะถูกสร้างขึ้นในคอมพิวเตอร์บางเครื่องเพื่อสร้างตัวเลขที่ตรงตามข้อกำหนดทั้งหมดสำหรับการสุ่มที่แท้จริง
โปรแกรมเมอร์คิดวิธีแก้ปัญหาของตนเอง: pseudorandom numbers Pseudorandom numbers เป็นลำดับประเภทหนึ่งซึ่งตัวเลขดูเหมือนจะเป็นแบบสุ่ม อย่างไรก็ตาม ด้วยการวิเคราะห์อย่างรอบคอบ ผู้เชี่ยวชาญสามารถค้นหารูปแบบบางอย่างในลำดับได้ ตัวเลขดังกล่าวไม่เหมาะสำหรับการเข้ารหัสเอกสารลับ แต่เพียงพอสำหรับการจำลองการตายในเกม
มีอัลกอริธึมมากมายสำหรับสร้างลำดับของตัวเลขสุ่มเทียม เกือบทั้งหมดสร้างหมายเลขสุ่มถัดไปตามหมายเลขก่อนหน้าและหมายเลขตัวช่วยเพิ่มเติม
ตัวอย่างเช่น โปรแกรมนี้จะแสดง1000
ตัวเลขที่ไม่ซ้ำ:
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());
}
}
}
อย่างไรก็ตาม เราไม่ได้พูดถึงตัวเลขสุ่มเทียมที่นี่ เรากำลังพูดถึงลำดับของเลขสุ่มเทียม เมื่อดูที่ตัวเลขตัวเดียวไม่สามารถบอกได้ว่าเป็นแบบสุ่มหรือไม่
มีหลายวิธีในการรับหมายเลขสุ่ม:
public static int getRandomNumber()
{
return 4; // Here's a random number (we got it by rolling a die)
}
2.Math.random()
ใน Java Math
คลาสมีเมธอดพิเศษที่ส่งคืนตัวเลขสุ่ม และอย่างที่คุณเดาได้ วิธีการนี้เรียกrandom
ว่า โดยทั่วไปแล้ว นี่คือลักษณะของการเรียกวิธีนี้:
Math.random()
วิธีนี้ไม่ใช้พารามิเตอร์และส่งกลับจำนวนจริงเทียมในช่วงจาก0
ถึง 1
หมายเลข 1 นั้นไม่รวมอยู่ในช่วง
ตัวอย่าง:
รหัส | เอาต์พุตคอนโซล |
---|---|
|
|
แต่ถ้าวิธีนี้ไม่ใช่สิ่งที่คุณต้องการล่ะ สมมติว่าคุณต้องการเขียนโปรแกรมจำลองการกลิ้งแม่พิมพ์หกด้าน คุณจะได้จำนวนเต็มสุ่มในช่วง 1..6 แทนที่จะเป็นจำนวนจริงในช่วง 0..1 ได้อย่างไร
มันค่อนข้างง่ายจริงๆ
ขั้น แรกคุณต้องแมปช่วง[0, 1)
กับ ในการทำเช่น นี้[0, 6)
เพียงคูณผลลัพธ์ที่ส่งกลับrandom()
ด้วย 6
แน่นอน ในการรับจำนวนเต็ม คุณต้องปัดขึ้น:
รหัส | เอาต์พุตคอนโซล |
---|---|
|
|
ส่งgetRandomDieNumber()
กลับจำนวนเต็มสุ่มในช่วง0..5
รวม 1, 2, 3, 4, 5, 6
แต่จะ ไม่เป็นตัวเลขในชุด 0, 1, 2, 3, 4, 5
มันจะเป็นตัวเลขในชุด
หากสิ่งที่คุณต้องการคือตัวเลขในชุด1, 2, 3, 4, 5, 6
ให้เพิ่มหนึ่งตัวในตัวเลขสุ่ม:
รหัส | เอาต์พุตคอนโซล |
---|---|
|
|
ตอนนี้สมบูรณ์แบบแล้ว!
3. Random
ชั้นเรียน
Java มีRandom
คลาสพิเศษที่ห่อหุ้มลำดับของตัวเลขสุ่มเทียม คุณสามารถสร้างหลายวัตถุของRandom
ชั้นเรียน แต่ละวัตถุเหล่านี้จะสร้างลำดับของตัวเลขสุ่มเทียมขึ้นมาเอง
นี่เป็นคลาสที่น่าสนใจสุด ๆ ด้วยวิธีการที่น่าสนใจมากมาย เริ่มจากสิ่งที่ง่ายที่สุดกันก่อน
double nextDouble()
วิธี นี้จะส่งกลับจำนวนจริงแบบสุ่มในช่วง0.0
- 1.0
มันคล้ายกันมากกับMath.random()
วิธีการ และไม่น่าแปลกใจเนื่องจากMath.random()
เมธอดเรียกnextDouble()
เมธอดบนRandom
วัตถุ
float nextFloat()
วิธีนี้คล้ายกับnextDouble()
วิธีนี้มาก แต่ตัวเลขสุ่มที่ส่งคืนคือfloat
a นอกจากนี้ ยังอยู่ในช่วง0.0
- 1.0
และเช่นเคยใน Java ช่วงจะไม่รวม1.0
ตัวเลข
Random r = new Random();
float f = r.nextFloat();
int nextInt(int max)
วิธีนี้จะส่งกลับจำนวนเต็มแบบสุ่มในช่วง รวมอยู่ในช่วง แต่ไม่[0, max)
0
max
กล่าวอีกนัยหนึ่ง ถ้าคุณต้องการรับตัวเลขสุ่มในชุด1, 2, 3, 4, 5, 6
คุณต้องเพิ่มหนึ่งตัวในตัวเลขสุ่มที่ส่งคืน:
Random r = new Random();
int x = r.nextInt(6) + 1;
int nextInt()
วิธีนี้คล้ายกับวิธีก่อนหน้า แต่ไม่ใช้พารามิเตอร์ใด ๆ ดังนั้นช่วงของค่าส่งคืนคืออะไร? จาก-2 billion
ถึง+2 billion
.
เอาตรงๆ จาก-2147483648
ถึง+2147483647
.
long nextLong()
วิธีนี้คล้ายกับnextInt()
เมธอด แต่ค่าที่ส่งคืนจะตกอยู่ในช่วงที่เป็นไปได้ทั้งหมดของlong
s
boolean nextBoolean()
เมธอด นี้ส่งคืนค่าสุ่มboolean
: false
หรือ true
วิธีนี้จะสะดวกมากเมื่อคุณต้องการรับค่าบูลีนแบบสุ่มที่มีลำดับยาว
void nextBytes(byte[] data)
วิธีนี้ไม่คืนค่าใดๆ (เนื่องจากประเภทการส่งคืนคือvoid
) แต่จะเติมอาร์เรย์ที่ส่งผ่านด้วยค่าสุ่มแทน สิ่งนี้มีประโยชน์มากเมื่อคุณต้องการบัฟเฟอร์ขนาดใหญ่ที่เต็มไปด้วยข้อมูลแบบสุ่ม
double nextGaussian()
วิธี นี้จะส่งกลับจำนวนจริงแบบสุ่มในช่วง0.0
- 1.0
อย่างไรก็ตาม ตัวเลขจะไม่กระจายอย่างสม่ำเสมอในช่วงนี้ แต่จะเป็นไปตาม การแจกแจง แบบปกติ
ค่าใกล้กึ่งกลางของช่วง ( 0.5
) จะเกิดขึ้นบ่อยกว่าค่าที่ปลายช่วง
ในกรณีของเรา จุดสูงสุดของการกระจายมูลค่าจะอยู่ที่0.5