ฟังก์ชัน rand() ใน C สุ่มตัวเลขได้แค่ช่วง 0 ถึง RAND_MAX เพื่อสุ่มในช่วงที่ต้องการ [lower, upper] ต้องใช้สูตรคณิตศาสตร์ปรับช่วง
สูตรการสุ่มในช่วง [L, R]
random_number = (rand() % (upper - lower + 1)) + lower;
อธิบายสูตร
rand() % (upper - lower + 1)→ ได้ค่า 0 ถึง (upper - lower)+ lower→ เลื่อนช่วงให้เริ่มจาก lower- ผลลัพธ์: ค่าสุ่มในช่วง [lower, upper] รวมทั้งสองข้าง
การ Seed ด้วย srand()
ต้อง Seed ด้วย srand(time(0)) เพื่อให้ได้ลำดับสุ่มต่างกันทุกครั้งที่รัน
time(0)คืนค่า Unix Timestamp (วินาที)- วาง
srand()ครั้งเดียว ที่เริ่มโปรแกรม (ไม่ใช่ใน Loop)
ตัวอย่างโค้ดสมบูรณ์
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// ฟังก์ชันสุ่มในช่วง [l, r] จำนวน count ครั้ง
void generate_random(int l, int r, int count) {
for (int i = 0; i < count; i++) {
int rand_num = (rand() % (r - l + 1)) + l;
printf("%d ", rand_num);
}
}
int main() {
int lower = 10, upper = 15, count = 15;
// Seed ด้วยเวลาปัจจุบัน (ครั้งเดียว!)
srand(time(0));
generate_random(lower, upper, count);
printf("\n");
return 0;
}
ผลลัพธ์ตัวอย่าง
15 11 13 10 13 10 15 11 14 12 12 13 12 13 14
หมายเหตุ: ผลลัพธ์จะต่างกันทุกครั้งที่รัน
ข้อควรระวัง (Bias Problem)
rand() % N มี Modulo Bias เมื่อ RAND_MAX + 1 ไม่หาร N ลงตัว ทำให้บางตัวเลขมีโอกาสออกมากกว่า
วิธีแก้ Bias (Better Random)
int rand_range(int min, int max) {
int range = max - min + 1;
int limit = RAND_MAX - (RAND_MAX % range);
int r;
do {
r = rand();
} while (r >= limit); // Rejection Sampling
return min + (r % range);
}
C++11 Library (แนะนำสำหรับโปรเจคจริง)
#include <random>
#include <iostream>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(10, 15);
for (int i = 0; i < 15; ++i) {
std::cout << dist(gen) << ' ';
}
return 0;
}
ใช้ Mersenne Twister (mt19937) คุณภาพสุ่มดีกว่า rand() มาก และไม่มี Bias