ดังตัวอย่างที่ยกไปเมื่อตอนที่แล้ว คือ
ฝึกวิเคราะห์ algorithm ด้วยตะแกรงร่อน Palindrome (2)
ผมทึกทักว่า ตัวเลข palindrome ใหญ่สุด น่าจะเป็น 9x xxx xx9 ซึ่งโอกาสที่จะผิด มีเพียง 0.0514 ยกกำลัง 1000 (โอกาสผิดราว 2 ใน 10 ยกกำลังหนึ่งพันเศษ ๆ)
ด้วยแนวคิดแบบเดียวกัน ผมลองนำไปใช้แบบให้สุดกู่ขึ้นอีก คือทึกทักว่า ตัวเลข palindrome ใหญ่สุด น่าจะเป็น 99 xxx x99 ซึ่งโอกาสที่จะผิด มีเพียง 0.0514 ยกกำลัง 100 (โอกาสผิดราว 1 ใน 10 ยกกำลัง 129) ซึ่งขอเรียกว่า เป็นกรณีที่สอง
เอาให้ตึงขึ้นมาอีกล่ะ คือทึกทักว่า ตัวเลข palindrome ใหญ่สุด น่าจะเป็น 99 9xx 999 ซึ่งโอกาสที่จะผิด มีเพียง 0.0514 ยกกำลัง 10 (โอกาสผิดราว 1 ใน 10 ยกกำลัง 13) ซึ่งในที่นี้ ขอเรียกว่า เป็นกรณีที่ 3
กรณีที่ 3 ซึ่งเป็นกรณีหลังสุด มีความเสี่ยงสูงไปนิดนึง เห็นแล้วไม่สบายใจที่จะใช้
ดังนั้น ผมจะรู้สึกว่า กรณีที่ 2 น่าจะลงตัว คือ ทึกทักว่า ตัวเลข palindrome ใหญ่สุด น่าจะเป็น 99 xxx x99
คราวนี้ผมจะใช้งานอย่างไรต่อล่ะ ?
ใช้การสังเกตุครับ
จากการสังเกตุ 99 xxx x99 จะต้องเกิดจากการคูณกันระหว่าง 99xx กับ 99yy (ดูตรงนี้ให้ดี ๆ นะครับ เพราะผมพลาดตรงนี้ !)
ดังนั้น กฎย่อยข้อแรกของเราคือ ใช้วิธีบังคับคูณแบบหักโหม แต่เลือกค่าตั้งต้นให้เหมาะสม ในที่นี้ เริ่มจาก 9900 ถึง 9999 มาคูณกันเองแบบพบกันหมด ซึ่งก็เป็นไปได้เพียง 1 หมื่นคู่เท่านั้นเอง
แล้วอันที่จริง ผมไม่ต้องคูณทุกรายการด้วย เพราะการที่ผลคูณลงท้ายด้วย 9 เกิดจากความเป็นไปได้เพียง 4 แบบ จาก 100 แบบเท่านั้นเอง
คือ
ลงท้ายด้วย 1 เจอกับลงท้ายด้วย 9
ลงท้ายด้วย 3 เจอกับลงท้ายด้วย 3
ลงท้ายด้วย 7 เจอกับลงท้ายด้วย 7
ลงท้ายด้วย 9 เจอกับลงท้ายด้วย 1
กฎข้อสองคือ กรองด้วยการดูเลขลงท้ายดังกล่าว ก็จะทำให้ 1 หมื่นคู่ ลดลงมาอีก เหลือเพียง 4 ร้อยคู่
ยังไม่หนำใจ ลองนึกถึงว่า การคูณแบบพบกันหมด มีความสมมาตรหน้าหลัง เลขมากคูณเลขน้อย ก็คือเลขน้อยคูณเลขมาก เวลาคูณ ก็อาจบังคับว่า ตัวหน้าใหญ่กว่าตัวหลังเสมอ จะได้ไม่ต้องคูณซ้ำซาก
เกิดเป็นกฎข้อสาม คือ ไม่ต้องคูณซ้ำคู่ที่เคยคูณไปแล้ว เพราะผมสามารถเลือกแต่กรณีที่ตัวเลขตัวหลัง ไม่ต่ำกว่าตัวเลขตัวแรก ก็พอ (เช่นถ้ารู้ 9953 x 9933 ก็ไม่ต้องหา 9933 คูณ 9953)
ทำแบบนี้ ก็จะลดฮวบ คูณทดสอบแค่สองร้อยคู่โดยประมาณเท่านั้นเอง (ผลคือ ความอืด จะลดจาก 8 ลงมาได้เหลือ 2.3 ซึ่งเยอะโขอยู่)
เขียนเป็น pseudocode ดังนี้ (ยืมคำศัพท์ภาษา Basic มาใช้ ... ก็เขียนเป็นอยู่ภาษาเดียวนิ -_-!)
- for x=9901 to 9999
- for y=x to 9999
- z=multiply if ended with {1,9} or {9,1} or {3,3} or {7,7}
- check for palindrome and keep the new-high
- next y
- next x
ลองรันดูจริง ต้องคูณกันทั้งหมด 210 ครั้ง
และได้ 9901 x 9999 = 99000099
ใน 210 ครั้งของการคูณ น่าจะมี palindrome ราว 95 % คือราวเกือบ 200 ครั้ง
แต่มี palindrome แค่ตัวเดียวเท่านั้น
เอ๊ะ ที่เหลือหายไปไหน ?
palindrome = ต้องแยก factor ได้
prime = แยก factor ไม่ได้
มี prime ราว 5 % จึงควรมี palindrome ราว 95 % สิ
ไม่ใช่ครับ
palindrome ต้องแยก factor ได้ แต่แยก factor ได้ไม่จำเป็นต้องเป็น palindrome
แถม palindrome ที่มีอยู่ชุกชุม ก็ไม่จำเป็นต้องเกิดจากเลข 4 หลักคูณเลข 4 หลักด้วย
หน้าแตกครับ แหกเป็นริ้วเลย !
ดังนั้น ในกรณีนี้ ต้องถือว่า algorithm นี้ ให้คำตอบแบบบังเอิญเฉียดฉิวมาก
ชัณสูตรแล้วเดาได้ไหมว่า ทำไมเจอแค่ 1 รายการที่เป็น palindrome ที่เป็นผลจากการที่ใช้เลข 4 หลักคูณเลข 4 หลัก ?
พอจะนึกออกราง ๆ ครับ แต่มองว่า เหตุผลที่อธิบายตรงนี้ได้ เป็นหัวข้อใหญ่เรื่องหนึ่งได้เลย
แต่ตอนนี้ ยังคิดไม่ค่อยลงตัว ไว้โอกาสหน้าถ้าคิดออก และไม่ลืมซะก่อน ค่อยมาต่อภาค 4 (อิ อิ อิ...)
ลองมาสรุปปฎิบัติการกันหน่อยดีไหม ?
แนวคิดทั้งหมดที่กล่าวมา จะเห็นได้ว่า ผมทำความเข้าใจกับโจทย์ และมีการปรับโจทย์ก่อน (optimize โจทย์) ให้อยู่ในสเกลที่กำลังพอจัดการได้
แล้วตามด้วยการพลิกแพลงแนวคิดในการเขียนโปรแกรม (optimize algorithm)
หลังจากนั้น ค่อยตามด้วยการเขียนโปรแกรมจริง
ในกรณีนี้ ปัญหามีลักษณะเฉพาะ บังเอิญว่ามองเชิงวิเคราะห์ออกก่อนเขียนโปรแกรม โดยใช้ความเข้าใจเรื่องเลข prime มาช่วย "ฟันธง" ถางทางไว้
แต่การใช้เทคนิคแบบนี้ ก็มีข้อจำกัด คืออาจมีกรณีที่มองไม่รอบด้าน ทำให้ล้มเหลวได้ ดังที่ผมสาธิตให้ดู (ทั้งที่ถูก และที่ผิด)
(ในที่นี้ ผมคาดว่า จะเจอ palindrome เยอะ จากการใช้เลข 4 หลักคูณเลข 4 หลัก ทั้ง 210 ครั้ง แต่เจอจริงแค่ 1 รายการ ซึ่งแม้ไม่ล้มเหลว แต่ถือว่าเป็นความสำเร็จที่ฟลุ้คไปหน่อย)
อย่างไรก็ตาม ปัญหาในสเกลใหญ่จริง ๆ ที่เกิดประโยชน์มาก ๆ มักต้องใช้ความพลิกแพลงเข้าช่วย เลี่ยงไม่ได้ เช่น ใน bioinformatics
เช่น การใช้ mass spectroscopy หา amino acid sequence ที่ยาวสัก 100 ตัวต่อกัน ระดับปัญหาที่คำนวณแบบหักโหม ต้องทำถึง 100! ครั้ง ซึ่งยังไม่มีฮาร์ดแวร์ที่ไหนรองรับได้ในบัดเดี๋ยวนี้ ต้องใช้วิธีพลิกแพลงด้วยการตั้งกฎย่อย ๆ มากระหนาบ กรองทิ้งหย่อมใหญ่ที่ไม่ต้องเสียเวลาตรวจสอบ
แต่ขนาดกรองแล้วเร็วขึ้นล้านล้านล้านเท่า ก็ยังช้ามากๆๆๆๆ ในกรณีเช่นนี้
algorithm จึงสำคัญสุด ๆ ในปัญหาโหด ๆ เช่นนั้น
แต่ใช่ว่า เราต้องพลิกแพลงคิดเสมอไป
ในบางงาน เขาอาจใช้วิธีที่ทื่อ ตรงดิ่ง แบบขวานผ่าซาก เช่น การเขียนโปรแกรมให้ใช้กำลังแบบหักโหม (brute force) เพื่อใช้ประเมินสมรรถนะของ hardware เช่น ในการแข่งขันหมากรุกระหว่างคนกับคอมพิวเตอร์
หรือในงานที่เล็กมาก หรือดูแล้วว่า ต่อให้ brute force ใช้เวลานานแค่ไหน ก็รอได้สบาย ๆ
แบบนั้น ไม่ต้องคิดให้เมื่อยก็ได้ เอาเวลาไปเขียนบล็อกซะดีกว่า
"การเลือกใช้ algorithm จึงต้องนับเป็นส่วนหนึ่งของตัว algorithm เองเสมอ"
ต้องกลับไปดูตอนก่อนๆ ก่อน. (ผมพลาดไปได้อย่างไร :-P)
ย้อนกลับไปอ่านก็เจอแล้วครับว่า 0.0514 คืออะไร :-P.
ดู psudo code แล้วก็แอบสงสัยครับว่าถ้า ตัด "z=multiply if ended with {1,9} or {9,1} or {3,3} or {7,7}" ออกไป โปรแกรมจะช้าลงหรือเปล่า. แต่พอย้อมกลับไปอ่านตอนแรก ก็พบว่านอกประเด็น เพราะว่าโจทย์ไม่ได้บอกว่าให้หาวิธีที่ใช้เวลาน้อย.
สวัสดีครับ อาจารย์
น่าสนใจดีครับ ผมยังไม่เคยเขียนการหาตัวเลขนี้เลยครับ
ต้องการหาตัวที่มากสุดด้วยใช่ไหมครับ
ผมเลยคิดว่า น่าจะปรับอัลกอฯ อาจารย์นิดหน่อยครับ แบบเทคนิคสวนทางครับ
จาก
เป็น
ไม่แน่ใจนะครับ ผมคิดว่าการใช้ downto เป็นการลดจากค่าสูงสุด และทำให้เร็วขึ้น และเมื่อเจอค่าตัวเลขนั้นก็ให้หยุดได้เลย ทำให้เราคำนวณได้เร็วขึ้นด้วยครับ
ขอบพระคุณมากครับ
แต่สำหรับคนที่เค้ามีเครื่อง supercomputer เค้าคงไม่ต้องมานั่งคิดมากเหมือนเราๆ เนอะครับ แต่สาเหตุนี้หล่ะครับที่ทำให้คนอินเดียเขียนโปรแกรมได้ฉลาดนัก เครื่องมือช้าให้หัวมากๆ ครับ
สวัสดีครับ น้องเม้ง สมพร ช่วยอารีย์
"แต่สำหรับคนที่เค้ามีเครื่อง supercomputer เค้าคงไม่ต้องมานั่งคิดมากเหมือนเราๆ เนอะครับ แต่สาเหตุนี้หล่ะครับที่ทำให้คนอินเดียเขียนโปรแกรมได้ฉลาดนัก เครื่องมือช้าให้หัวมากๆ ครับ "
คนอินเดียก็ไม่ได้มีชีวิตเหมือนรามานุจันไปเสียหมดหรือเปล่าครับ? ดูจากคอมฯที่นักเรียน/อาจารย์วิทยาการคอมพิวเตอร์ที่อินเดียใช้ ก็คล้ายๆกับที่คนไทยใช้ แต่ว่ามักจะลง GNU/Linux พ่วงมากับ Windows ด้วยเท่านั้นเอง :-P.
ผมคิดว่าต่อให้ใช้ super computer หรือแม้แต่ cpu ใหม่ก็ไม่ได้ทำให้เรื่องที่ต้องคิดน้อยลง ถ้าต้องการจะ optimize กันจริงจัง. ส่วนตัวแล้วผมคิดว่า cpu ใหม่ๆอาจจะต้องคิดมากขึ้นด้วยซ้ำ ถ้ามีคำสั่งเรียงกันมา.
ใน 8088 ผมเข้าใจว่าเวลาที่ใช้ในแต่ละคำสั่งมาบวกกัน ก็น่าจะได้เวลารวมแล้ว. แต่ใน CPU ที่ใหม่ขึ้นมาหน่อย บางคำสั่งอาจจะทำงานไปพร้อมๆกันได้ ถ้าไม่มีคำสั่งที่ทำให้โปรแกรมต้องกระโดดไปมา ซึ่งส่วนมากจะเกิดจากการเพิ่มเงื่อนไขเข้าไปในโปรแกรม. นี่ก็อาจจะเป็นไปได้ว่าเราเขียนโปรแกรมหลายๆคำสั่งแต่ไม่มี IF ก็อาจจะทำงานออกมาเร็วกว่าที่คาดไว้. นี่อาจจะเป็นอีกเหตุผลหนึ่งที่ทำให้โปรแกรมที่พยายามจะเขียนออกมาให้ฉลาด แต่ทำให้ทำงานช้าลง!!!. (ผมก็เสียเวลาทำอะไรแบบนี้บ่อยๆ :-P )
ใน super computer ก็ใช้หลักการทำงานแบบขนานเหมือนกัน? ถ้าเรานำ cpu เดี่ยวๆของ super computer ออกมา บางเครื่องอาจจะช้ากว่า cpu ที่เราใช้งานกันเดี๋ยวนี้ด้วยซ้ำ. ถ้าเราใส่โปรแกรมไปแบบไม่ค่อยได้คิดอะไรเท่าไหร่ ก็อาจจะเป็นไปได้ว่าใช้ super computer แล้ว โปรแกรมทำงานช้าลง.
เครื่องใหม่ๆเดี๋ยวนี้มักจะมี GPU ติดว่าด้วย เราอาจจะนำมาช่วยคำนวณอะไรได้บ้าง แต่วิธีใช้งาน วิธีคิดก็อาจจะเปลี่ยนไปพอสมควร. ก็ไม่ใช่ว่าเราเอา GPU มาแล้วเอาโปรแกรมเดิมไปให้ GPU รันแล้วก็จะเร็วขึ้นไปหมดอีกเหมือนกัน.
เหมือนที่อาจารย์ wwibul เคยเขียนเรื่อง multi-core cpu หละครับ. ของพวกนี้บางทีมันก็ไม่ได้เร็วโดยที่เราไม่ได้ออกแรงอะไร.
สวัสดีครับ คุณบ่าวवीर
ส่วนเรื่องการศึกษา เรื่องหนังสือ เรื่องทรัพยากรรองรับ...
สวัสดีครับ อ.วิบุล และบ่าววีร์
[a - b, a +b] โดยที่ b คืำำำำอค่าจำนวนเต็มที่คร่อมค่าที่หยิบที่มาในตำแหน่งเริ่มต้น
สวัสดีครับ น้อง เม้ง สมพร ช่วยอารีย์
ส่วนเรื่องที่ว่า
"จะเอาคณิตศาสตร์ไปช่วยคิดแก้ปัญหาการเมืองได้อย่างไรบ้างครับ เห็นยุ่งเหยิงจริงๆ ครับ..."
wwibul: อาจจะเป็นไปได้ว่าอินเดียระบบก็ดีกว่า เครื่องไม้เครื่องมีก็อาจจะดีกว่าประเทศไทยด้วย.
สวัสดีครับ อ.วิบุล และบ่าววีร์
เรื่องอัลกอริทึมนี้ Hoshen-Kopelman Algorithm น่าสนใจดีครับ
ผมเคยนำแนวคิดที่ตั้งโจทย์กับอาจารย์ เอาไปประยุกต์กับการไหลของน้ำในภาพครับ หรือการค้นหาโครงสร้างต่างๆ จากภาพ ได้น่าสนใจครับ แต่ผมแก้สมการโดยใช้หลักการน้ำไหล เป็น Parabolic PDE, heat equation หรือจะใช้แบบ wave equation ก็ได้ครับแต่เปลืองกว่า heat equation ครับ
มีภาพเคลื่อนไหวตัวอย่างให้ดูครับผม คลิกที่นี่ครับ เป็นโครงสร้างเส้นใบไม้ นะครับ
ประยุกต์อีกอย่างที่เคยทำในคือ ลองจำลองน้ำไหลในคลอง จากภาพถ่ายดาวเทียมครับ เพราะเราจะทราบลักษณะสีของลำคลองอยู่แล้วครับ ต่างจากสีอื่น ดังนั้น หากมีฝนตกหนักเราอาจจะจำลองหยาบๆ การไหลได้ว่าจะไหลอย่างไร แต่ให้ดีต้องทำแบบนิวเมอริคัล จริงๆ ครับ
ขอบคุณมากๆ ครับผม
น้องเม้ง สมพร ช่วยอารีย์
คุณบ่าวवीर
เป็นประเด็น ที่ยังต้องรอข้อมูลเพิ่ม
แต่อย่างน้อย ประเทศที่เคยเป็นอาณานิคมอังกฤษ เรื่องที่ค่อนข้างจะแน่ใจได้ คือ เรื่องภาษา และเรื่องส่งเสริมหนังสือแพร่หลายและราคาถูกนี่ ผมเชื่อว่า เป็นไปได้สูง
เรื่องอื่น ไม่รู้เหมือนกันครับ