GORAGOD.com

เทคนิคการสุ่มข้อมูลจำนวนมากแบบไม่ซ้ำกัน

การสุ่มข้อมูลด้วย PHP สามารถทำได้ไม่ยากด้วยคำสั่ง rand()
int rand(int $min, int $max)

ฟังก์ชั่น rand() จะสุ่มตัวเลขระหว่าง $min และ $max ออกมา เป็น ผลลัพท์ของฟังก์ชั่น
$min ตัวเลขต่ำสุดที่ต้องการ ถ้าไม่ได้กรอกค่านี้จะใช้ค่า 0
$max ตัวเลขสูงสุดที่ต้องการ ถ้าไม่กรอกจะสามารถสุ่มค่าได้สูงสุดเท่ากับค่าที่ได้จากฟังก์ชั่น getrandmax() (บน Windows จะสามารถสุ่มได้สูงสุดเท่ากับ 32767)
หมายเหตุ หากต้องการบังคับให้ rand() สุ่มค่าได้เกิน 32767 จะต้องกำหนด $min และ $max ที่ต้องการให้กับฟังก์ชั่น

มีคำถามจาก Facebook ถามถึงการสุ่มข้อมูลแบบไม่ซ้ำกันจำนวนมากๆ ผมเห็นว่าน่าสนใจดีเลยมาตอบไว้ที่นี่
<?php
    // แอเรย์เก็บผลลัพท์ไว้ที่ key
    $datas = array();
    // จำนวนข้อมูลที่ต้องการ
    $count = 100;
    // วนลูป
    while (true) {
        // สุ่มตัวเลข
        $r = rand(0, $count * 1000);
        // ตรวจสอบตัวเลขซ้ำ
        if (!isset($datas[$r])) {
            // ถ้ายังไม่เคยมีตัวเลขนี้ให้ใส่ลง array เป็น key
            $datas[$r] = 0;
        }
        if (sizeof($datas) == $count) {
            // ครบจำนวนที่ต้องการให้ออกจากลูป
            break;
        }
    }
    // จำนวนข้อมูลที่สุ่มได้
    echo sizeof($datas);
    // แสดงรายการข้อมูลที่สุ่มได้
    print_r(array_keys($datas));

เทคนิคนี้เป็นการสุ่มข้อมูล แล้วนำข้อมูลที่สุ่มมาใส่แอเรย์ เพื่อใช้ในการตรวจสอบข้อมูลที่อาจซ้ำกัน เหตุที่นำมาใส่ลงใน key ก็เพราะว่าเราสามารถตรวจสอบข้อมูลซ้ำได้ง่ายๆและรวดเร็วด้วยคำสั่ง isset() เท่านั้น
ข้อจำกัดของวิธีนี้ คือ จำนวนสูงสุดที่สามารถสุ่มได้จะขึ้นกับหน่วยความจำของเครื่อง
ในกรณีที่ต้องการผลลัพท์เป็นตัวอักษรอาจใช้วิธีการแปลง 0-9 เป็น A-J ได้

มีคำถามเพิ่มเติมจาก Facebook ว่า หากต้องการข้อมูลจำนวนมากๆ แต่มี Ram น้อยจะทำอย่างไร
 $r = rand(0, $count * 1000);

แนวคิด โค้ดด้านบนคือคำตอบครับ 

ให้เราสุ่มข้อมูลเป็นช่วงๆครับ เช่น ช่วงแรกสุ่ม 1-10000 ช่วงที่สอง สุ่ม 10001 - 20000 (แต่ละช่วงห่างกัน 10000 ลำดับ) ไปเรื่อยๆจนกว่าจะครบจำนวนที่ต้องการ โดยการกำหนดช่วงให้กับฟังก์ชั่น rand()
// รอบที่ 1
$r = rand(0, 10000); // ผลลัพทธ์ที่ได้จะอยู่ระหว่าง 0-10000
......
// รอบที่ 2
$r = rand(10001, 20000);// ผลลัพทธ์ที่ได้จะอยู่ระหว่าง 10001-20000
// รอบถัดไปจนกว่าจะครบ
......

การที่เรากำหนดตัวเลขในการสุ่มข้อมูลเป็นช่วงๆ ด้วยตัวเอง จะทำให้เราได้เลขที่ไม่ซ้ำกันกับช่วงก่อนๆ ซึ่งมีผลให้เราสามารถทดสอบตัวแปรที่ซ้ำกันในแต่ละช่วงได้ โดยไม่จำเป็นต้องทดสอบกับข้อมูลทั้งหมด โดยที่ในแต่ละช่วงหลังการสุ่มข้อมูลในแต่ละช่วงจบแล้ว จะต้องทำลายตัวแปรทิ้งเสมอ เพื่อเริ่มต้นในการสุ่มค่าชุดใหม่ (ไม่งั้นหน่วยความจำก็ไม่พออยู่ดี) รวมถึง ต้องทำการบันทึกข้อมูลที่สุ่มแล้วก่อนด้วย