ผลต่างระหว่างรุ่นของ "ปัญหาการยุติการทำงาน"

เนื้อหาที่ลบ เนื้อหาที่เพิ่ม
use en:Quasi-quotation + reword on caution
copyedit
บรรทัด 1:
ใน[[ทฤษฎีการคำนวณได้]]นั้น '''ปัญหาการยุติการทำงาน''' ({{Lang-en|Halting problem}}) คือ[[ปัญหาการตัดสินใจ]]ที่ถามว่า
 
:''กำหนด[[ขั้นตอนวิธี]]และ[[ข้อมูลป้อนเข้า]]ให้ จงหาว่าขั้นตอนวิธีเมื่อทำงานกับข้อมูลป้อนเข้าดังกล่าวแล้ว จะยุติการทำงาน (ทำงานเสร็จสิ้น) หรือจะทำงานไปเรื่อย ๆ ไม่มีที่สิ้นสุด''
 
[[แอลัน ทัวริง]] (Alan Turing) พิสูจน์ในปี ค.ศ. 1936 ว่า ไม่มีขั้นตอนวิธีที่แก้ปัญหาการยุติการทำงานสำหรับข้อมูลป้อนเข้าใด ๆ ได้ทั้งหมดบน[[เครื่องจักรทัวริ่งทัวริง]] จึงกล่าวว่าปัญหาการยุติการทำงานนี้[[ปัญหาการตัดสินใจ#การตัดสินได้และการรับได้|ไม่สามารถตัดสินได้]]
 
== ความสำคัญและผลสืบเนื่อง ==
ปัญหานี้มีความสำคัญเพราะว่าเป็นปัญหาแรกที่พิสูจน์ได้รับการพิสูจน์ว่าเป็นปัญหาที่ไม่สามารถตัดสินได้ หลังจากนั้นการค้นพบของปัญหาในกลุ่มนี้อีกหลายปัญหาก็ถูกระบุออกมามีการค้นพบปัญหาอื่น ๆ ซึ่งไม่สามารถตัดสินได้เช่นเดียวกัน โดยวิธีพิสูจน์ทั่วไปทำโดยว่าปัญหาหนึ่ง ๆ ไม่สามารถตัดสินได้ มักจะใช้เทคนิค''[[การลดรูป (ความซับซ้อน)|การลดรูป]]'' ซึ่งเป็นการแสดงว่าถ้ามีขั้นตอนวิธีในการแก้ปัญหาต่าง ๆ เหล่านี้ เราจะสามารถนำขั้นตอนวิธีนั้นมาใช้เพื่อตัดสินปัญหาที่ไม่สามารถตัดสินได้ (โดยการแปลงตัวปัญหา (instance) ของปัญหาที่ไม่สามารถตัดสินได้นั้นให้อยู่ในรูปของปัญหาใหม่นี้) แต่เนื่องจากเราทราบว่า''ไม่มี''ขั้นตอนวิธีใดจะตัดสินปัญหาที่ไม่สามารถตัดสินได้ เราจึงสรุปได้ว่าไม่มีวิธีใดที่จะตัดสินปัญหาอันใหม่ได้ด้วย
 
การที่เรา[[การไม่สามารถตัดสินได้|ไม่สามารถตัดสิน]]ปัญหาการยุติการทำงานได้ มีผลสืบเนื่องทำให้เราไม่มีทางมีวิธีทั่วไปในการตัดสินได้ว่าถ้อยแถลง (statement) เกี่ยวกับ[[จำนวนธรรมชาติ]]ในเป็นจริงหรือไม่ ทั้งนี้เนื่องจาก[[ประพจน์]]ที่ระบุว่าขั้นตอนวิธีหนึ่ง ๆ จะยุติการทำงานเมื่อรับข้อมูลป้อนเข้าหนึ่ง ๆ นั้นสามารถเขียนให้อยู่ในรูปของถ้อยแถลงเกี่ยวกับจำนวนธรรมชาติที่เทียบเท่ากันได้ ดังนั้น ขั้นตอนวิธีที่ตัดสินความจริงของถ้อยแถลงเกี่ยวกับจำนวนธรรมชาติ จะสามารถนำมาใช้เพื่อตัดสินปัญหาการยุติการทำงานได้ ข้อสรุปก็คือ ขั้นตอนวิธีดังกล่าวจึงไม่สามารถมีอยู่จริง เพราะว่าเราทราบว่าไม่มีขั้นตอนวิธีใดที่ตัดสินปัญหาการยุติการทำงานได้ สังเกตว่าการแสดงการไม่สามารถตัดสินได้ดังกล่าวใช้วิธีการลดทอนปัญหาสู่ปัญหาการยุติการทำงาน
 
อย่างไรก็ตาม การแสดงว่าปัญหาบางปัญหาไม่สามารถตัดสินได้นั้น ยังสามารถแสดงได้ด้วยวิธีอื่น ๆ โดยไม่จำเป็นต้องผ่านการลดทอนสู่ปัญหาการยุติการทำงานเสมอไป เกเกอรี่ ไชตินได้แสดงว่ามีปัญหาที่ไม่สามารถตัดสินได้ใน[[ทฤษฎีข้อมูลเชิงขั้นตอนวิธี]]ที่ไม่ต้องใช้ปัญหาการยุติการทำงาน นอกจากนี้เขายังได้ให้นิยามที่น่าประหลาดเกี่ยวกับ[[ความน่าจะเป็นในการยุติการทำงาน]]ที่แสดงถึง[[ความน่าจะเป็น]]ที่โปรแกรมที่สร้างขึ้นแบบสุ่มจะทำงานสิ้นสุด
 
แม้ว่าบทพิสูจน์ของทัวริงจะแสดงว่าไม่มีวิธีใดที่สามารถตัดสินได้ว่าขั้นตอนวิธีที่ให้มานั้น ทำงานสิ้นสุดได้ สำหรับบางขั้นตอนวิธีแล้ว เราก็มีวิธีในการแสดงว่าขั้นตอนวิธีนั้นทำงานสิ้นสุด หรือแม้กระทั่งแสดงขอบเขตของเวลาที่ขั้นตอนวิธีดังกล่าวจะต้องใช้ในการทำงาน [[นักวิทยาศาสตร์คอมพิวเตอร์]]มักสร้างบทพิสูจน์ดังกล่าว เพื่อแสดงว่าขั้นตอนวิธีทำงานถูกต้อง ซึ่งบทพิสูจน์ดังกล่าวมักเป็นส่วนหนึ่งของ[[บทพิสูจน์ความถูกต้อง]] อย่างไรก็ตาม บทพิสูจน์ดังกล่าวแต่ละอันนั้น จะใช้รูปแบบในการให้เหตุผลที่แตกต่างกัน นั่นคือ: ไม่มี ''วิธีอัตโนมัติเชิงกล''ที่สามารถตัดสินได้ว่าขั้นตอนวิธีใด ๆ จะทำงานสิ้นสุดได้. สำหรับโปรแกรมทั่วไปแล้ว บ่อยครั้งความรู้เฉพาะทางบางอย่างสามารถนำมาใช้เพื่อสร้างข้อพิสูจน์ของการยุติการทำงานได้ การศึกษาเกี่ยวกับเรื่องนี้เรียกว่า[[การวิเคราะห์การยุติการทำงาน]]
 
=== ข้อควรระวัง ===
ข้อจำกัดอีกประการหนึ่งของบทพิสูจน์ว่าปัญหาการยุติการทำงานของโปรแกรมคือ โมเดลใน[[การคำนวณ]]ที่บทพิสูจน์ใช้นั้น อนุญาตให้โปรแกรมสามารถใช้หน่วยความจำได้ไม่จำกัด แม้ว่าในเวลาหนึ่ง ๆ โปรแกรมจะสามารถเก็บข้อมูลได้จำกัด แต่มันจะเก็บข้อมูลเพิ่มขึ้นได้เรื่อย ๆ และไม่มีวันที่หน่วยความจำจะเต็ม ถ้าหน่วยความจำและเนื้อที่เก็บข้อมูลเพิ่มเติมของโปรแกรมมีจำกัด เช่นเดียวกับเครื่องคอมพิวเตอร์ในปัจจุบัน ในทางทฤษฎีแล้ว ปัญหาการยุติการทำงานนั้น ก็จะสามารถแก้ได้ผ่านทางโปรแกรมที่ไม่ซับซ้อนนัก กล่าวคือ ในกรณีดังกล่าว สถานะที่เป็นไปได้ทั้งหมดที่โปรแกรมจะมีได้นั้นมีจำกัด ซึ่งจะทำให้โปรแกรมที่ไล่พิจารณาสถานะทั้งหมดสามารถตัดสินได้ว่า ขั้นตอนวิธีที่รับมานั้นจะยุติการทำงานหรือไม่ อย่างไรก็ดีโปรแกรมดังกล่าวจะใช้เวลาในการทำงานที่นานเกินไป จนไม่สามารถนำมาใช้จริงได้
ความยากในปัญหาการยุติการทำงานคือการที่ต้องตอบคำถามสำหรับทุก ๆ โปรแกรมและทุก ๆ ข้อมูลนำเข้าว่าจะเกิดการยุติการทำงานหรือไม่ ดังนั้นขั้นตอนวิธีที่ตอบเพียงว่าจะ "ยุติการทำงาน" (หรือ "ไม่ยุติการทำงาน") เพียงอย่างเดียวจึงไม่สามารถแก้ไขปัญหานี้ได้ พิจารณาโปรแกรมที่จำลองการทำงานของโปรแกรมอื่น หากโปรแกรมที่เราทดสอบนั้นยุติการทำงาน โปรแกรมจำลองก็จะให้ผลลัพธ์ถูกต้อง แต่หากโปรแกรมทดสอบไม่ยุติการทำงาน โปรแกรมจำลองก็ย่อมไม่ยุติการทำงานด้วยเช่นกัน ซึ่งส่งผลให้ไม่สามารถแก้ปัญหานี้ได้ตามที่ได้กล่าวไว้
 
ปัญหาการยุติการทำงานอาจเป็นปัญหาที่สามารถตัดสินใจได้ (นั่นคือสามารถแก้ได้) บนโมเดลใน[[การคำนวณ]]อื่น ๆ เช่น บนเครื่องจักรที่มีหน่วยความจำจำกัด (linear bounded automata; LBAs) เนื่องจากจำนวนสถานะในเครื่องจักรเหล่านี้มีจำกัด เมื่อทำงานไปเรื่อย ๆ โดย[[หลักรังนกพิราบ]] จะมีจุดหนึ่งที่สถานะในหน่วยความจำเหมือนกัน นั่นคือถ้าหากเราปล่อยให้โปรแกรมทำงานต่อไปอีก สถานะก็จะมาซ้ำที่จุดเดิมอีกไปเรื่อย ๆ ดังนั้นเมื่อมาถึงจุด ๆ นั้น เราก็สามารถบอกได้ทันทีว่าโปรแกรมนี้ ไม่ยุติการทำงาน
 
ถึงแม้คอมพิวเตอร์ในยุคปัจจุบันจะเป็นเครื่องจักรที่มีหน่วยความจำจำกัดประเภทหนึ่ง ทำสามารถแก้ปัญหาการยุติการทำงานได้ในทางทฤษฎี จำนวนสถานะที่แตกต่างกันทั้งหมดของคอมพิวเตอร์นั้นมีมากกว่า 2<sup>1,000,000</sup> สถานะ ซึ่งมากมายมหาศาล เวลาในการแก้ไขปัญหานี้จึงมากมายมหาศาลด้วยเช่นกัน (สามารถเปรียบเทียบว่าเวลาในการแก้ไขปัญหานี้ ทำให้ช่วงเวลาอายุของเอกภพไร้ความหมายได้เลย)
 
== ร่างบทพิสูจน์ ==
บทพิสูจน์ใช้[[การพิสูจน์แบบการสร้างข้อขัดแย้ง]] (หรือที่เรียกใน[[ภาษาละติน]]ว่า reductio ad absurdum) โดยสมมติว่า''มี''ขั้นตอนวิธีที่อธิบายได้ด้วยโปรแกรม <code>halt (a, i) </code> ที่ซึ่งตัดสินว่าขั้นตอนวิธีที่ระบุด้วยข้อความ ''a'' นั้นจะยุติการทำงานเมื่อได้รับข้อมูลป้อนเข้าเป็นข้อความ ''i'' เราจะแสดงว่าข้อสมมติดังกล่าวจะทำให้เกิดข้อขัดแย้ง, และนั่นหมายความว่าโปรแกรม <code>halt</code> นั้น''ไม่สามารถมีตัวตน''อยู่ได้
 
สมมติให้โปรแกรม <code>halt (a, i) </code> คืนค่า <code>'''จริง'''</code> ถ้าขั้นตอนวิธีที่ระบุด้วยข้อความ ''a'' ยุติการทำงานเมื่อรับ ''i'' เป็นข้อมูลป้อนเข้า และคืนค่า <code>'''เท็จ'''</code> ในกรณีอื่น ๆ ด้วยโปรแกรมดังกล่าว เราสามารถสร้างโปรแกรมอีกโปรแกรมหนึ่ง ชื่อว่า <code>trouble (s) </code> ดังนี้ดังต่อไปนี้:
 
'''function''' trouble (''string'' s)
เส้น 27 ⟶ 32:
loop forever
 
โปรแกรมนี้ <code>trouble</code> รับข้อความ ''s'' และเรียกโปรแกรม <code>halt</code> โดยใช้ข้อมูลป้อนเข้าทั้งที่เป็นข้อความที่ระบุขั้นตอนวิธี ''a'' และข้อความที่จะใช้เป็นข้อมูลป้อนเข้า ''i'' ของขั้นตอนวิธีดังกล่าวเป็น ''s'' กล่าวอย่างไม่เป็นทางการก็คือ <code>trouble</code> ถาม <code>halt</code> ว่าขั้นตอนวิธี ''s'' เมื่อรับข้อความที่ระบุตัวขั้นตอนวิธีเองแล้ว จะยุติการทำงานหรือไม่ จากนั้น ถ้า <code>halt (s,s) </code> คืนค่า '''เท็จ''' โปรแกรม <code>trouble</code> จะจบการทำงาน แต่ถ้า <code>halt (s,s) </code> คืนค่า '''จริง''' โปรแกรม <code>trouble</code> จะวนรอบไม่รู้จบ
 
เนื่องจากโปรแกรมใด ๆ สามารถเขียนระบุเป็นข้อความได้ ดังนั้นสำหรับโปรแกรม <code>trouble</code> เอง เราจะมีข้อความ ''⌜trouble⌝'' ที่ระบุโปรแกรมดังกล่าว พิจารณาคำถามต่อไปนี้:
 
: <code>trouble (⌜trouble⌝) </code> จะยุติการทำงานหรือไม่?
 
ลองดูความเป็นไปได้ทั้งสองกรณี:
 
เนื่องจากโปรแกรมใด ๆ สามารถเขียนระบุเป็นข้อความได้ ดังนั้นสำหรับโปรแกรม <code>trouble</code> เอง เราจะก็มีข้อความ ''⌜trouble⌝'' ที่ระบุโปรแกรมดังกล่าว <code>trouble</code> พิจารณาคำถามต่อไปนี้:
# สมมติว่า <code>trouble (⌜trouble⌝) </code> ยุติการทำงาน กรณีเดียวที่เป็นไปได้ก็คือ <code>halt (⌜trouble⌝,⌜trouble⌝) </code> คืนค่า '''เท็จ''' แต่นี่หมายความว่า <code>trouble (⌜trouble⌝) </code> จะทำงานไม่รู้จบ ดังนั้นเราได้ข้อขัดแย้ง
# สมมติว่า <code>trouble (⌜trouble⌝) </code> ทำงานไม่รู้จบ เนื่องจาก <code>halt (⌜trouble⌝,⌜trouble⌝) </code> ทำงานจบเสมอ ดังนั้นสาเหตุเดียวที่ทำให้ <code>trouble (⌜trouble⌝) </code> ทำงานไม่รู้จบก็คือ <code>halt (⌜trouble⌝,⌜trouble⌝) </code> คืนค่า '''จริง''' อย่างไรก็ตามนี่หมายความว่า <code>trouble (⌜trouble⌝) </code> จะต้องมีการยุติการทำงาน เราจึงได้ข้อขัดแย้งอีกเช่นกัน
 
: <code>trouble (⌜trouble⌝) </code> จะยุติการทำงานหรือไม่?
เนื่องจากทั้งสองกรณีทำให้เกิดข้อขัดแย้งที่ล้วนเป็นไปไม่ได้ ดังนั้นสามารถสรุปได้ว่าข้อสมมติเริ่มต้นที่ใช้นั้นไม่ถูกต้อง กล่าวคือไม่มีโปรแกรม <code>halt</code> หรือขั้นตอนวิธีใด ๆ ที่สามารถตัดสินปัญหาการยุติการทำงานได้
 
ลองดูมีความเป็นไปได้ทั้งทั้งหมดสองกรณี:
== ข้อควรระวัง ==
ความยากในปัญหาการยุติการทำงานคือการที่ต้องตอบคำถามสำหรับทุก ๆโปรแกรมและทุก ๆ ข้อมูลนำเข้าว่าจะเกิดการยุติการทำงานหรือไม่ ดังนั้นขั้นตอนวิธีที่ตอบเพียงว่าจะ "ยุติการทำงาน" (หรือ "ไม่ยุติการทำงาน") เพียงอย่างเดียวจึงไม่สามารถแก้ไขปัญหานี้ได้ พิจารณาโปรแกรมที่จำลองการทำงานของโปรแกรมอื่น หากโปรแกรมที่เราทดสอบนั้นยุติการทำงาน โปรแกรมจำลองก็จะให้ผลลัพธ์ถูกต้อง แต่หากโปรแกรมทดสอบไม่ยุติการทำงาน โปรแกรมจำลองก็ย่อมไม่ยุติการทำงานด้วยเช่นกัน ซึ่งส่งผลให้ไม่สามารถแก้ปัญหานี้ได้ตามที่ได้กล่าวไว้
 
# สมมติว่า <code>trouble (⌜trouble⌝) </code> ยุติการทำงาน: หากพิจารณาการทำงานของโปรแกรม กรณีเดียวที่เป็นไปได้ก็คือ<code>trouble</code> จะพบว่า <code>halt (⌜trouble⌝,⌜trouble⌝) </code> ต้องคืนค่า '''เท็จ''' แต่นี่ถ้า <code>halt</code> ทำงานถูกต้องก็หมายความว่า <code>trouble (⌜trouble⌝) </code> จะทำงานไม่รู้จบ ดังนั้นเราได้ทำให้เกิดข้อขัดแย้งกับสมมุติฐานว่า <code>trouble (⌜trouble⌝)</code> ยุติการทำงาน
ปัญหาการยุติการทำงานเป็นปัญหาที่สามารถตัดสินใจได้ (นั่นคือสามารถแก้ได้) บนเครื่องจักรที่มีหน่วยความจำจำกัด (linear bounded automata; LBAs) เนื่องจากจำนวนสถานะในเครื่องจักรเหล่านี้มีจำกัด เมื่อทำงานไปเรื่อย ๆ โดย[[หลักรังนกพิราบ]] จะมีจุดหนึ่งที่สถานะในหน่วยความจำเหมือนกัน นั่นคือถ้าหากเราปล่อยให้โปรแกรมทำงานต่อไปอีก สถานะก็จะมาซ้ำที่จุดเดิมอีกไปเรื่อย ๆ ดังนั้นเมื่อมาถึงจุด ๆ นั้น เราก็สามารถบอกได้ทันทีว่าโปรแกรมนี้ ไม่ยุติการทำงาน
# สมมติว่า <code>trouble (⌜trouble⌝) </code> ทำงานไม่รู้จบ: เนื่องจาก <code>halt (⌜trouble⌝,⌜trouble⌝) </code> ทำงานจบเสมอ ดังนั้นสาเหตุเดียวที่ทำให้ <code>trouble (⌜trouble⌝) </code> ทำงานไม่รู้จบก็คือ <code>halt (⌜trouble⌝,⌜trouble⌝) </code> ต้องคืนค่า '''จริง''' อย่างไรก็ตามนี่หมายความว่า <code>trouble (⌜trouble⌝) </code> จะต้องมีการยุติการทำงาน เราจึงได้ทำให้เกิดข้อขัดแย้งอีกเช่นกันกับสมมุติฐานว่า <code>trouble (⌜trouble⌝)</code> ทำงานไม่รู้จบ
 
เนื่องจากทั้งสองกรณีทำให้เกิดข้อขัดแย้งที่ล้วนเป็นไปไม่ได้ ดังนั้นสามารถสรุปได้ว่าข้อสมมติเริ่มต้นแรกสุด (''มี''ขั้นตอนวิธีที่ใช้อธิบายได้ด้วยโปรแกรม <code>halt (a, i) </code>) นั้นไม่ถูกต้อง กล่าวคือ''ไม่มี''โปรแกรม <code>halt</code> หรือขั้นตอนวิธีใด ๆ ที่สามารถตัดสินปัญหาการยุติการทำงานได้
ถึงแม้คอมพิวเตอร์ในยุคปัจจุบันจะเป็นเครื่องจักรที่มีหน่วยความจำจำกัดประเภทหนึ่ง จำนวนสถานะที่แตกต่างกันทั้งหมดของคอมพิวเตอร์นั้นมีมากกว่า 2<sup>1,000,000</sup> สถานะ ซึ่งมากมายมหาศาล เวลาในการแก้ไขปัญหานี้จึงมากมายมหาศาลด้วยเช่นกัน (สามารถเปรียบเทียบว่าเวลาในการแก้ไขปัญหานี้ ทำให้ช่วงเวลาอายุของเอกภพไร้ความหมายได้เลย)
 
== ดูเพิ่ม ==
* [[กราฟแสดงการไหลของส่วนควบคุม]] (control flow graph) สามารถใช้เพื่อจำแนกโปรแกรมอย่างรวดเร็วออกเป็นโปรแกรมที่ (1) ไม่มีการวนซ้ำ, (2) มีการวนซ้ำแบบง่าย (จึงยุติการทำงาน) , (3) มีการวนซ้ำแบบไม่ง่าย (กรณีไม่สามารถระบุอะไรได้) , หรือ (4) ทำงานซ้ำอย่างไม่รู้จบ
 
== อ้างอิง ==
* [[แอลัน ทัวริง]] (Alan Turing) , ''On computable numbers, with an application to the Entscheidungs problem'', Proceedings of the London Mathematical Society, Series 2, 42 (1936) , pp 230-265. [http://www.abelard.org/turpap2/tp2-ie.asp online version] ในงานวิจัยชิ้นนี้ ทัวริงนิยาม[[เครื่องจักรทัวริง]] วางรูปแบบปัญหาการยุติการทำงาน และแสดงว่าปัญหานี้ (รวมทั้ง [[Entscheidungs problem]]) เป็นปัญหาที่ไม่สามารถแก้ได้
 
[[หมวดหมู่:ทฤษฎีการคำนวณ]]