ในฐานะวิศวกรระบบฝังตัว (Embedded Systems Engineer) หลายครั้งที่เรามักจะหมกมุ่นอยู่กับการควบคุมฮาร์ดแวร์ การจัดการ Interrupt หรือการปรับแต่ง Register แต่ในบางครั้ง การย้อนกลับไปหาพื้นฐานทางคณิตศาสตร์ที่บริสุทธิ์ก็สามารถสร้างแรงบันดาลใจใหม่ๆ ได้อย่างไม่น่าเชื่อ บทความนี้ผมจะพาไปสำรวจ "สมมติฐานของคอลลาตซ์" (Collatz Conjecture) ผ่านมุมมองของนักพัฒนาระบบฝังตัว โดยใช้เพียงบอร์ด Arduino และคอมพิวเตอร์หนึ่งเครื่องเป็นเครื่องมือในการพิสูจน์ความซับซ้อนภายใต้กฎเกณฑ์ที่แสนเรียบง่ายนี้
โปรเจกต์นี้เป็นการพิสูจน์ว่าพลังของ C++ บน Arduino IDE นั้นไม่ได้จำกัดอยู่เพียงแค่การเปิด-ปิดไฟ LED หรือการอ่านค่าเซนเซอร์ แต่ยังสามารถนำมาใช้ประมวลผลอัลกอริทึมทางคณิตศาสตร์เชิงทฤษฎีได้อย่างมีประสิทธิภาพ โดยที่คุณไม่จำเป็นต้องต่อวงจรให้ยุ่งยาก ไม่ต้องมีตัวต้านทาน หรือสายจัมเปอร์ใดๆ เพียงแค่เสียบสาย USB และเตรียมสมองให้พร้อมสำหรับการวิเคราะห์ตัวเลข
สมมติฐานของคอลลาตซ์ (Collatz Conjecture) คืออะไร?
สมมติฐานของคอลลาตซ์ เป็นหนึ่งในปัญหาทางคณิตศาสตร์ที่ดูเรียบง่ายที่สุดแต่ยังไม่มีใครสามารถพิสูจน์ให้เป็นจริงได้ในทุกกรณีมานานกว่า 80 ปี กฎของมันมีเพียงไม่กี่ข้อที่ใช้กับจำนวนเต็มบวก (Positive Integers) ใดๆ ดังนี้:
- หากจำนวนนั้นเป็น เลขคู่ (Even): ให้หารด้วย 2
- หากจำนวนนั้นเป็น เลขคี่ (Odd): ให้คูณด้วย 3 แล้วบวกเพิ่มอีก 1
- นำผลลัพธ์ที่ได้กลับไปทำตามข้อ 1 หรือ 2 ซ้ำไปเรื่อยๆ จนกว่าผลลัพธ์จะกลายเป็น 1
ทฤษฎีนี้ระบุว่า ไม่ว่าคุณจะเริ่มต้นด้วยจำนวนเต็มบวกที่มากแค่ไหนก็ตาม ท้ายที่สุดแล้วลำดับของตัวเลขจะ "ยุบตัว" (Collapse) ลงมาที่เลข 1 เสมอ ตัวเลขเหล่านี้บางครั้งถูกเรียกว่า "เลขลูกเห็บ" (Hailstone Numbers) เพราะค่าของมันจะพุ่งสูงขึ้นและตกลงมาสลับกันไปมา เหมือนลูกเห็บที่วนเวียนอยู่ในเมฆก่อนจะตกลงสู่พื้นดิน
ลองพิจารณาตัวเลข 11 เป็นค่าเริ่มต้น:
11 (คี่) → 34 → 17 (คี่) → 52 → 26 → 13 (คี่) → 40 → 20 → 10 → 5 (คี่) → 16 → 8 → 4 → 2 → 1
หรือลองเลขที่ใหญ่ขึ้นอย่าง 3412:
3412, 1706, 853, 2560, 1280, 640, 320, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1
แม้แต่ Lothar Collatz ผู้เสนอทฤษฎีนี้ในปี 1937 ก็คงคาดไม่ถึงว่าความเรียบง่ายนี้จะกลายเป็นความท้าทายระดับโลกในสาขาทฤษฎีตัวเลข (Number Theory) ที่นักคณิตศาสตร์ผู้ยิ่งใหญ่หลายท่านยังไม่สามารถหาข้อพิสูจน์ที่ครอบคลุมได้ทั้งหมด
การเตรียมอุปกรณ์และระบบ (The Technical Setup)
ในเชิงวิศวกรรม การรันอัลกอริทึมนี้บนไมโครคอนโทรลเลอร์มีความน่าสนใจในเรื่องของ Data Precision และ Computational Limits ของ CPU ขนาดเล็ก อย่าง ATmega328P ที่อยู่ใน Arduino Uno ซึ่งเป็นสถาปัตยกรรมแบบ 8-bit
ส่วนประกอบที่ใช้:
- Microcontroller: บอร์ด Arduino รุ่นใดก็ได้ (Uno, Nano, Mega หรือ ESP32 สำหรับการประมวลผล 32-bit ที่รวดเร็วกว่า)
- Interface: สาย USB สำหรับโปรแกรมและสื่อสารข้อมูลผ่านโปรโตคอล UART (Serial Monitor)
- Software: Arduino IDE
ขั้นตอนการติดตั้งนั้นง่ายแสนง่าย:
- เชื่อมต่อบอร์ด Arduino เข้ากับคอมพิวเตอร์
- เปิด Arduino IDE แล้วทำการ Compile/Upload โค้ด Collatz Sketch ลงไป
- เปิด Serial Monitor และตั้งค่า Baud Rate ไปที่ 9600 baud ซึ่งเป็นความเร็วมาตรฐานในการสื่อสารข้อมูลอนุกรมสำหรับโปรเจกต์ทั่วไป
วิเคราะห์ตรรกะเบื้องหลังโค้ด (Logic & Code Breakdown)
หัวใจสำคัญของโปรแกรมนี้อยู่ที่การจัดการ Loop และการตรวจสอบเงื่อนไข ซึ่งในภาษา C++ เราจะใช้โอเปอเรเตอร์ทางคณิตศาสตร์พื้นฐาน:
// ตัวอย่างตรรกะหลักภายใน Loop
while (n != 1) {
if (n % 2 == 0) { // ตรวจสอบว่าเป็นเลขคู่หรือไม่ด้วย Modulo Operator
n = n / 2;
} else {
n = (3 * n) + 1; // กฎของเลขคี่
}
Serial.println(n); // ส่งค่ากลับไปยังคอมพิวเตอร์
}
ในการเขียนโปรแกรมระดับ Embedded สิ่งที่เราต้องระวังคือ Integer Overflow หากผู้ใช้ใส่ตัวเลขขนาดใหญ่มาก (เช่น เลขที่มีค่าเข้าใกล้ขีดจำกัดของ unsigned long) ค่าที่คำนวณได้อาจจะเกินความจุของ Register ทำให้เกิดข้อผิดพลาดในการคำนวณ ดังนั้นการเลือกใช้ชนิดข้อมูล (Data Types) เช่น unsigned long หรือแม้แต่ uint64_t ในบอร์ดรุ่นใหม่ๆ จึงเป็นเรื่องสำคัญอย่างยิ่งเพื่อให้แน่ใจว่าการ "พุ่งขึ้น" ของเลขลูกเห็บจะไม่ทะลุเพดานหน่วยความจำเสียก่อน
โปรแกรมจะทำงานในลักษณะ Interactive โดยรอรับค่า Input จากผู้ใช้ผ่านฟังก์ชัน Serial.parseInt() จากนั้นจะคำนวณลำดับทั้งหมดและแสดงผลออกมาเป็นชุดข้อมูลทางหน้าจอ Serial Monitor
การวิเคราะห์พฤติกรรมผ่าน Serial Plotter
นอกจากการดูตัวเลขที่วิ่งผ่านหน้าจอ Serial Monitor แล้ว ผมแนะนำให้คุณลองใช้เครื่องมือที่ชื่อว่า Serial Plotter (เลือกได้จากเมนู Tools ใน Arduino IDE)
เมื่อเปลี่ยนจากตัวอักษรมาเป็นกราฟ คุณจะเห็น "รูปร่าง" (Shape) ของลำดับคอลลาตซ์ได้อย่างชัดเจน กราฟจะแสดงการไต่ระดับของตัวเลขที่พุ่งขึ้นสูงอย่างรวดเร็วเมื่อเจอเลขคี่หลายตัวติดต่อกัน และการดิ่งลงอย่างรวดเร็วเมื่อเจอกำลังของเลขสอง (Powers of 2) ความสวยงามของมันคือไม่ว่ากราฟจะผันผวนเพียงใด สุดท้ายมันจะตกลงสู่ฐานที่เลข 1 เสมอ
ข้อแนะนำทางเทคนิค: เนื่องจาก Serial Plotter ของ Arduino IDE ไม่มีปุ่ม Clear ข้อมูลในตัว หากคุณต้องการเริ่มดูรูปทรงของตัวเลขใหม่ ให้ปิดหน้าต่าง Plotter แล้วเปิดใหม่อีกครั้งเพื่อล้าง Buffer ข้อมูลเก่า
(ตัวอย่างภาพกราฟที่แสดงบน Serial Plotter ซึ่งแสดงให้เห็นถึงความผันผวนของลำดับก่อนจะยุบตัวลง)
บทสรุปและข้อสังเกต
จากการทดลองรันตัวเลขหลายๆ ชุด คุณจะพบข้อสังเกตที่น่าทึ่ง:
- ไม่มีความสัมพันธ์เชิงเส้น: ตัวเลขที่น้อย (เช่น 27) อาจสร้างลำดับที่ยาวและซับซ้อนกว่าตัวเลขที่มาก (เช่น 1024 ซึ่งจะดิ่งตรงสู่ 1 ทันที)
- Convergence Pattern: ทุกลำดับจะจบลงด้วยวงจร 4 → 2 → 1 เสมอ ซึ่งเป็นจุดสิ้นสุดของสมมติฐานนี้
การทำโปรเจกต์นี้แสดงให้เห็นว่า Arduino ไม่ได้เป็นเพียงบอร์ดสำหรับควบคุมฮาร์ดแวร์เท่านั้น แต่ยังเป็นห้องทดลองคณิตศาสตร์ขนาดย่อมที่ช่วยให้เราเข้าใจความซับซ้อนของอัลกอริทึมได้ดียิ่งขึ้น หากคุณเป็นนักพัฒนาระบบฝังตัว ลองใช้เวลาว่างจากการ Optimize โค้ดควบคุมมอเตอร์ มาลองไล่ตามเลขลูกเห็บเหล่านี้ดู แล้วคุณจะพบเสน่ห์ที่ซ่อนอยู่ในกฎเกณฑ์ง่ายๆ ของ Lothar Collatz ครับ