"You are not perfect..., that's why you are perfect."
Divide and Conquer เทคนิคแก้ปัญหาซับซ้อนด้วยการแบ่งเป็นปัญหาย่อย ๆ แล้วจัดการสอยมันให้ร่วงทีละอย่าง
16 Jun 2019 13:16   [31910 views]

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

"เราสามารถใช้เทคนิคที่ใช้ในการเขียนโปรแกรมมาประยุกต์ใช้ในชีวิตประจำวันได้เยอะเลย"

เรียกว่ามีประโยชน์กับการใช้ชีวิตมากเลยหละ

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

"การแก้ปัญหา"

เพราะงานเขียนโปรแกรมมักจะเป็นงานที่สลับซับซ้อน Requirement ที่ฟังดูเหมือนง่าย แต่เอาเข้าจริงตอนลงมือเขียนโปรแกรมก็จะมีเรื่องราวมาเกี่ยวข้องเยอะแยะมากมาย บางเรื่องก็อาจรู้อยู่แล้ว บางเรื่องก็เป็นเรื่องใหม่ รวมแล้ววุ่นวายไปหมด คราวนี้โจทย์ที่แท้จริงคือ "จะแก้ปัญหาเหล่านั้นแล้วทำออกมาเป็นงานเชิงโปรแกรมมิ่งได้อย่างไร"

ถ้าแก้ได้ก็จะเขียนโปรแกรมออกมาได้อย่างสมบูรณ์แบบ ยิ่งใครแก้ปัญหาเก่งก็จะยิ่งเขียนโปรแกรมออกมาได้ประสิทธิภาพสูงขึ้นเท่านั้น ทั้งเขียนออกมาเร็วและทำงานได้เร็ว

นี่ทำให้คนที่ทำงานด้านโปรแกรมมิ่งมาเลยมักจะมีความคิดและลอจิคในการแก้ปัญหาติดตัวมาด้วยเสมอ

และนี่แหละคือสิ่งที่เราคิดว่ามันมีประโยชน์มาก เพราะเอาจริง ๆ ถามว่าชีวิตมนุษย์แต่ละวันมันคืออะไร ? มันคือการแก้ปัญหาล้วน ๆ เลยนะ ไม่ว่าจะเป็นปัญหาทางการงานหรือชีวิต ทุกวินาทีมักจะมีความท้าทายมาเสิร์ฟให้เราแก้ปัญหาอยู่เรื่อยไป ใครแก้ปัญหาได้เร็วก็จะได้เปรียบคนอื่นเค้าเสมอ

เทคนิคการแก้ปัญหาเชิงโปรแกรมมิ่งที่มีสอนกันก็มีอยู่หลายตัว ทุกอย่างก็เหมาะกับบริบทที่ต่างกันออกไป แต่สำหรับเราแล้วจะมีอยู่ตัวนึงที่พิเศษหน่อยคือใช้ได้กับทุกบริบทเลย และเราจัดให้เป็นพื้นฐานความคิดของการแก้ปัญหาใด ๆ ในโลกเลย ไม่ได้จำกัดแค่ปัญหาทางคอมพิวเตอร์ด้วยนะ ปัญหาอะไรก็ได้เลย เทคนิคนี้มีชื่อว่า "Divide and Conquer" หรือ "แบ่งแยกและเอาชนะ" ครับ

ซึ่งเราเกลียดชื่อภาษาไทยมาก ดังนั้นบล็อกนี้เราจะเขียนชื่อเป็นภาษาอังกฤษหมดนะ เอาหละ ไปดูกันว่ามันคืออะไรและเจ๋งยังไง

อะไรคือ Divide and Conquer ?

ความจริงมันเป็นเทคนิคที่ไม่มีอะไรลึกลับซับซ้อนเลย ค่อนข้างตรงไปตรงมามาก นิยามแบบบ้าน ๆ คือ

Divide and Conquer คือการแบ่งปัญหาที่มีออกเป็นปัญหาเล็ก ๆ หลาย ๆ ข้อ ซึ่งมักจะแก้ได้ง่ายกว่า ถ้าปัญหาที่ย่อยออกมายังใหญ่ไปอีก ก็ย่อยมันลงไปอีกจนถึงจุดที่ย่อยไม่ได้แล้ว เมื่อแก้ปัญหาเล็ก ๆ นั้นได้หมด ปัญหาใหญ่ก็จะถูกแก้ไขไปได้ด้วย

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

และหากปัญหามันใหญ่และมีสิ่งเกี่ยวพันกันเยอะ หากลุยแก้ไปเลยโดยไม่คิดไม่วางแผน บอกเลยว่าไม่มีทางแก้ปัญหาได้สำเร็จหรอก และวิธีที่ดีที่สุดในการจัดการกับปัญหาซับซ้อน ๆ แบบนี้คือ "ย่อยมันออกมาเป็นปัญหาง่าย ๆ เล็ก ๆ ก่อนสิ !"

ธรรมชาติของปัญหาคือ ยิ่งปัญหาเล็กก็ยิ่งแก้ง่าย ดังนั้นยิ่งเรามีความสามารถในการย่อยปัญหาได้มากเท่าไหร่ ก็จะทำให้เราสามารถแก้ปัญหาที่ซับซ้อนได้มากขึ้นเท่านั้น หน่ึงใน Quote ที่ทำให้เรารัก Divide and Conquer มาก ๆ มาจากสุดยอดศาสตราจารย์ที่เราเคารพมาก ๆ อย่าง ศ.ดร.ประภาส แห่งภาควิศวกรรมศาสตร์คอมพิวเตอร์จุฬาลงกรณ์มหาวิทยาลัย เคยสอนไว้ว่า

"ปัญหาใหญ่ ๆ จริง ๆ แล้วอาจจะไม่ได้ใหญ่อย่างที่เห็นก็ได้ ปัญหาที่ดูแก้ยาก ๆ จริง ๆ ถ้าค่อย ๆ แบ่งมันเป็นปัญหาเล็ก ๆ แล้วแต่ละอันอาจจะแก้ง่าย ๆ ก็ได้ แล้วก็ไล่แก้ทีละอันไปสิ"
- ศ.ดร.ประภาส จงสถิตย์วัฒนา

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

ก็ตามนั้น จริง ๆ มันก็แค่เทคนิคการย่อยปัญหาให้เล็กจะได้แก้ไขได้ง่าย ๆ มาดูตัวอย่างกัน

ตัวอย่าง D&C กับข้าวผัดกระเพราไก่ไข่ดาว

ถึงเราจะรู้จัก Divide and Conquer จากการเขียนโปรแกรม แต่ตอนนี้เราบอกได้เลยว่าเราใช้กับทุกเรื่องจริง ๆ และเพื่อไม่ให้บล็อกมัน Geek เกินไป เลยขอยกตัวอย่างการนำ D&C มาใช้ในภาษามนุษย์ละกันนะ โดยขอยกเรื่องของ "การทำข้าวผัดกระเพราไก่ไข่ดาว"

ปัญหาก็ง่าย ๆ

"ทำไมทำข้าวผัดกระเพราไก่ไข่ดาวให้อร่อยเหมือนร้านข้างบ้านไม่ได้"

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

เอาใหม่ ไหนลองย่อยปัญหาดูว่ามีปัญหาอะไรบ้างที่เราต้องแก้

1) กระทะร้อนรึเปล่า ?
2) น้ำมันใส่เยอะไปรึเปล่า ?
3) ไฟแรงไปรึเปล่า ?
4) ใบกระเพราเน่ารึเปล่า ?
5) ใส่ซีอิ้วขาวมากไปรึเปล่า ?
6) ไก่สดรึเปล่า ?
7) ข้าวเละไปรึเปล่า ?
8) ใส่เครื่องปรุงผิดรึเปล่า ?
9) ใส่เครื่องปรุงไม่ถูกลำดับรึเปล่า ?
10) ไข่ดาวสุกไปรึเปล่า ?
11) ฯลฯ

คราวนี้ถ้าค่อย ๆ มาดูทีละข้อแล้วไล่เช็คก็จะทำให้เราแก้ไขปัญหาได้ภายในเวลาวันเดียวและได้ข้าวผัดกระเพราไก่ไข่ดาวที่อร่อยมาอย่างเร็วไว ในขณะที่ถ้ายังมัวงมว่าทำไมไม่อร่อยว้าแล้วก็มั่วไปเรื่อย ๆ เพราะไม่ยอมย่อยปัญหาก่อน อันนี้คงไม่ได้กินในเดือนนี้แน่นอน

สำหรับบางปัญหาที่สามารถย่อยลงไปได้อีก เช่น น้ำมันต้องใส่มากน้อยแค่ไหน เราก็สามารถสร้างเป็นปัญหาใหญ่อันใหม่ได้เช่นกันว่า "เราจะหาปริมาณน้ำมันที่พอดีให้เร็วที่สุดได้ยังไง" แล้วก็ย่อยมันออกมา สุดท้ายก็จะได้คำตอบของปัญหาใหญ่เองครับ

ตัวอย่าง D&C กับการอัปไฟล์ขึ้น Dropbox

ลองกับปัญหาที่เนิร์ดขึ้นมาหน่อย ... "ทำไมอัปไฟล์ขึ้น Dropbox ไม่ได้ว้า"

ปัญหาคลาสสิคที่สุดท้ายมักจะต้องรบกวน IT Support ให้มาช่วยดูให้ แต่จริง ๆ ถ้าเราสามารถย่อยเองได้ว่าปัญหาเกิดจากอะไรบ้างก็อาจจะแก้ไขเองได้เลย แถมเก่งขึ้นด้วย ไหนดูสิมีปัญหาอะไรบ้าง

1) คอมพ์ต่อเนตรึยัง ?
2) เนตที่ใช้บล็อค Dropbox รึเปล่า ?
3) Dropbox ล่มรึเปล่า ?
4) Dropbox พื้นที่เต็มรึเปล่า ?

ก็ไล่เช็คทีละปัญหาสิ สุดท้ายก็จะรู้แล้วว่าเกิดอะไรขึ้นแล้วก็แก้ไขได้

ก็จะเห็นว่าถ้าเราย่อยปัญหาเป็น ทุกปัญหาในโลกจะง่ายลงอย่างทันตา หลาย ๆ ปัญหาที่เราคิดว่าไม่มีทางแก้ได้แน่ ๆ ก็อาจจะกลายเป็นปัญหาจิ๊บ ๆ ไปในทันที

"ขอแค่ย่อยปัญหาเป็น"

การใช้ Divide and Conquer ในการสงคราม

Divide and Conquer ไม่ได้ใช้แค่ในงานโปรแกรมมิ่ง แต่จริง ๆ ถูกใช้ในทุกอย่างเลย การสงครามก็ไม่เว้น

ในอดีตตอนอาณาจักรโรมันเข้าตีและยึดครองอังกฤษ แผนการรบที่โรมันใช้ก็คือ Divide and Conquer นี่แหละ เพียงแต่ศัพท์ทางการที่ใช้จะใช้อีกคำนึงคือ "Divide and Rule"

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

"แบ่งกองทหารออกมาเป็นหลาย ๆ กองแล้วเข้าตีแยกกันจนได้ชัยชนะในที่สุด"

ซึ่งตรงนี้เป็นความหมายที่ตรงกับคำว่า Divide and Conquer สุด ๆ "แบ่งแยกและเอาชนะไง" ถ้าเอาชนะทุกปัญหา(ทุกกองทัพ)ได้ ชัยชนะทั้งหมดก็จะเป็นของเรา

ลองฝึกฝนดูนะ

จะเห็นว่า Key Takeaway ของเรื่องนี้คือ

"ยิ่งย่อยปัญหาเก่ง ก็จะยิ่งแก้ปัญหาเก่ง"

ความได้เปรียบจะเกิดกับคนที่มีสามารถในการมองปัญหาและย่อยมันออกมาให้เป็นปัญหาง่าย ๆ เล็ก ๆ ได้ และนั่นต้องใช้ "ประสบการณ์" พอสมควร

สิ่งที่อยากให้ลองคือ อยากให้ลองฝึกฝนย่อยปัญหาดู ซึ่งทำได้ไม่ยากเพราะชีวิตทุกวันเราจะมีปัญหาให้ต้องแก้ไขอยู่แล้ว ลองลิสต์เลยว่าปัญหานั้น ๆ ประกอบด้วยปัญหาย่อยอะไรบ้าง แล้วก็ลองพยายามแก้ไขด้วยวิธี Divide and Conquer ดู

ฝึกฝนซ้ำไปซ้ำมาเรื่อย ๆ แล้วพอถึงจุดนึง ไม่ว่ามีปัญหาอะไรเข้ามา คุณก็จะมองมันเป็นปัญหาเล็ก ๆ ได้ในทันที

ลองดูนะ เราว่ามันมีประโยชน์ต่อชีวิตมากกกก =)

เป็นบล็อกชิว ๆ สำหรับวันพักผ่อน ไว้มาต่อซีรีส์หนีมาอยู่เมกาต่อบล็อกถัดไปน้าาาา แว้บบบ

บทความที่เกี่ยวข้อง

Aug 30, 2018, 06:14
43661 views
สรุปงาน Pizza Hackathon ครั้งที่ 0 งาน Blockchain Hackathon กับธีม "ให้เกียรติคำว่า Hack ด้วย !"
Oct 14, 2018, 20:00
38985 views
เปรียบเทียบภาพ 3D Photo บน Facebook ที่ถ่ายจาก iPhone X และ Note 9
0 Comment(s)
Loading