ผลต่างระหว่างรุ่นของ "หอคอยฮานอย"
เนื้อหาที่ลบ เนื้อหาที่เพิ่ม
ไม่มีความย่อการแก้ไข |
ล แก้ไขเรื่องการเว้นวรรคและการใช้ภาษาเล็กน้อย |
||
บรรทัด 1:
{{รอการตรวจสอบ}}
[[ไฟล์:Tower_of_Hanoi.jpeg|300px|thumb|ชุดของเล่น
'''หอคอยฮานอย''' (Tower of Hanoi) เป็น[[เกมคณิตศาสตร์]] โดย[[เอดัวร์ ลูว์กา]] นักคณิตศาสตร์ชาวฝรั่งเศส ประกอบด้วยหมุดสามแท่ง และจานกลมแบนต่างขนาดซึ่งมีรูตรงกลางสำหรับให้หมุดลอด เกมเริ่มจากจานทั้งหมดวางอยู่ที่หมุดเดียวกัน โดยเรียงตามขนาดจากใหญ่ที่สุดอยู่ทางด้านล่าง จนถึงจานขนาดเล็กที่สุดอยู่ด้านบนสุด เป็นลักษณะกรวยคว่ำตามรูป
บรรทัด 9:
== ประวัติ ==
เกมปัญหานี้คิดค้นขึ้นโดย
หากตำนานนี้เป็นจริง และ
นอกเหนือจากตำนานข้างต้นแล้ว ยังมีตำนานดัดแปลง
== คำตอบ ==
บรรทัด 23:
* ติดเบอร์ให้กับจานจากเล็กที่สุด 1 ไปจนถึงใหญ่ที่สุด ''n''
ต้องการย้ายจานทั้งหมด n ใบ
# หากย้ายจาน n-1 ใบจาก A ไปไว้ที่ C ก่อน จะทำให้เหลือจาน #n (หมายเลข n ใบใหญ่ที่สุด) เพียงใบเดียวแก้วหน่อง
# ย้ายจาน #n จาก A ไปไว้ที่ B
# ย้ายจาน n-1 ใบจาก C ไปที่ B ซึ่งจานทั้งหมดจะอยู่บนจาน #n
ขั้นตอนวิธีด้านบนนั้นเรียกว่า [[ขั้นตอนวิธีเวียนเกิด]] (recursive algorithm)
ปัญหา
เราสามารถคำนวณหาจำนวนครั้งของการเคลื่อนย้ายจาน ที่จำเป็นในการแก้ปัญหานี้ จาก[[ความสัมพันธ์เวียนเกิด]] (recurrence relation) ได้เท่ากับ <math>2^n - 1</math> โดย <math>n</math> คือ จำนวนจานทั้งหมด ผลลัพธ์นี้ได้จากข้อสังเกตที่ว่า ในขั้นตอนที่ 1 และ 3 ใช้เวลาในการแก้ปัญหา <math>T_{n-1}</math> และ
โปรแกรมในการแก้ปัญหา
hanoi n = hanoi' n 1 2 3
hanoi' 0 _ _ _ = []
hanoi' n f i t = (hanoi' (n-1) f t i) ++ (f, t) : (hanoi' (n-1) i f t)
โดย ''n'' คือ จำนวนจานทั้งหมด
=== คำอธิบาย ===
ขั้นตอนวิธีด้านบน สามารถอธิบายด้วยภาษาชาวบ้าน
# ย้าย
# ย้าย
# ย้าย
ตอนนี้ เรามีจาน 2 ใบวางตามลำดับถูกต้องที่หมุด B และ หมุด C ไม่มีจาน
# ย้าย
# และ
ในแต่ละขั้นจะเห็นได้ว่า เราสร้างหอคอยจาก
จำนวนครั้งในการเคลื่อนย้ายจาน n ใบ
=== ในทางปฏิบัติ ===
บรรทัด 58:
[[ไฟล์:Tower_of_Hanoi_4.gif|right|frame|คำตอบสำหรับจาน 4 ใบ (จานเล็กสุดเคลื่อนไปทางขวา >>>)]]
ทำการเคลื่อนย้ายจาน #1 และจานอื่นที่ใหญ่กว่า
หรือที่ง่ายกว่านั้น
ถึงแม้ว่า ขั้นตอนวิธีในการแก้ปัญหานั้นไม่ซับซ้อน แต่การแก้ปัญหาที่เร็วที่สุด สำหรับจาน ''n'' ใบนั้น ต้องใช้การย้ายถึง 2<sup>''n''</sup>−1 ครั้ง
=== รหัสฐานสอง ===
บรรทัด 68:
เราอาจใช้[[เลขฐานสอง]] ในการระบุการเคลื่อนย้ายตำแหน่งของจาน (โดยสภาวะเริ่มต้นเป็นการเคลื่อนที่ #0 มีเลขฐานสองทุกตำแหน่งเป็น 0 และ สภาวะสุดท้ายเป็นการเคลื่อนที่ #2<sup>''n''</sup>−1 มีเลขฐานสองทุกตำแหน่งเป็น 1) โดยใช้วิธีการดังนี้
* จานแต่ละใบจะแทนด้วย 1 หลัก (บิต) ของเลขฐานสอง
* บิตที่มีค่าความสำคัญมากที่สุด (บิตที่มีค่ามากที่สุด
* บิตที่มีค่าความสำคัญมากที่สุด บิตที่มีค่า 0 หมายถึงจานใบใหญ่ที่สุดอยู่บนหมุดเริ่มต้น และ
* สายบิต (อ่านจากบิตซ้าย
* ในการอ่านสายบิต บิตที่มีค่าเดียวกับบิตก่อนหน้า หมายความว่า
** ซึ่งในกรณีที่ตัวเลขในสายบิต
* บิตที่มีค่าต่างจากบิตก่อนหน้า มีความหมายว่า
** หากเป็นจานหมายเลขคี่
** หากเป็นจานหมายเลขคู่ ค่าบิต
** รูปแบบดังกล่าวสมมติ
** และสมมติการเคลื่อนที่แบบวนรอบ คือ
ตัวอย่าง จาน 8 ใบ:
* การย้าย #0 (00000000)
** จานใบใหญ่ที่สุด
** จานที่เหลือมีค่าบิต 0 ด้วยเช่นกัน (0'''0000000''') จึงวางอยู่บนจานใบใหญ่สุด ดังนั้นจานทุกใบจึงอยู่ที่หมุดเริ่มต้น
* การย้าย #255 (11111111)
** จานใบใหญ่ที่สุด
** จานที่เหลือมีค่าบิต 1 ด้วยเช่นกัน (1'''1111111''') จึงวางอยู่บนจานใบใหญ่สุด ดังนั้นจานทุกใบจึงอยู่ที่หมุดเป้าหมาย และ
* การย้าย #216 (11011000)
** จานใบใหญ่ที่สุด
** จาน #2 มีค่าบิต 1 (1'''1'''011000) ดังนั้นจึงวางอยู่บนจานใบแรกที่หมุดขวาสุด
** จาน #3 มีค่าบิต 0 (11'''0'''11000) จานหมายเลขคี่ มีค่าบิต 0 คือหมุดถัดไปทางด้านขวา (ของหมุดขวาสุด) คือ
** จาน #4 มีค่าบิต 1 (110'''1'''1000) จานหมายเลขคู่ มีค่าบิต 1 คือหมุดถัดไปทางด้านขวา คือ
** จาน #5 มีค่าบิต 1 (1101'''1'''000) เหมือนบิตก่อนหน้า จึงวางอยู่บนจานก่อนหน้าที่หมุดกลาง
** จาน #6 มีค่าบิต 0 (11011'''0'''00) จานหมายเลขคู่ มีค่าบิต 0 คือหมุดถัดไปทางด้านซ้าย คือหมุดซ้ายสุด
** จาน #7 #8 มีค่าบิต 0 (110110'''00''') ซึ่งมีค่าเหมือนบิตก่อนหน้า ดังนั้นจานทั้งสองจึงวางซ้อนอยู่บนจาน #6 ที่หมุดซ้ายสุด
ตามรูปแบบเลขฐานสองนี้ เราสามารถหาตำแหน่งของจาน
=== รหัสเกรย์ ===
[[รหัสเกรย์]] (Gray code) ซึ่งเป็นระบบตัวเลขฐานสองแบบหนึ่ง เป็นรูปแบบจำลองอีกแบบหนึ่งซึ่งสามารถใช้ในการแก้ปัญหา ในระบบรหัสเกรย์นั้น ตัวเลขจะเขียนอยู่ในรูปผสมของตัวเลข 0 และ 1 แต่จะแตกต่างเลขฐานสองมาตรฐาน
หากจำนวนบิตของรหัสเกรย์
วิธีนี้บอกว่าจานใบไหนถูกย้ายบ้าง แต่ไม่ได้บอกว่าย้ายไปที่ไหน กฎของการย้ายจะเป็นตัวบอกการย้าย โดยการย้ายจานนั้น จานที่มี[[ภาวะคู่หรือคี่ (คณิตศาสตร์)|ภาวะคู่หรือคี่]] (parity) เหมือนกันจะไม่วางซ้อนทับกัน (
== แหล่งข้อมูลอื่น ==
|