Category Archives: ภาษาไทย

1 กัป = กี่ปี เอ่ย

(มีผู้ทักท้วงว่าผมคำนวณผิดจึงได้คำนวณใหม่ไว้ที่ https://witpoko.com/?p=72 ครับ อันนี้ตัวเลขผิดครับ)

จากวิธีนับกัป ใน Wikipedia:

(วิธีที่ 1) วิธีนับกัป กำหนดกาลว่านานกัปหนึ่งนั้น พึงรู้ด้วยอุปมาประมาณว่า มีขุนเขากว้างใหญ่สูงโยชน์หนึ่ง (16 กิโลเมตร) ถึง 100 ปีมีเทพยดาเอาผ้าทิพย์เนื้อละเอียดลงมาเช็ดถูบนยอดขุนเขานั้นหนหนึ่งแล้วก็ไป ถึงอีก 100 ปีจึงเอาผ้าลงมาเช็ดถูอีก นิยมอย่างนี้นานมาจนตราบเท่าขุนเขานั้นสึกเกรียนเหี้ยนลงมาราบเสมอพื้นพสุธาแล้ว กำหนดเป็น 1 กัป เมื่อนั้น

(วิธีที่ 2) อีกนัยหนึ่ง กำหนดด้วยประมาณว่า มีกำแพงเป็นสี่เหลี่ยมจตุรัสโดยกว้างลึกกำหนดหนึ่งโยชน์ ถึง 100 ปีมีเทพยดานำเมล็ดผักกาดมาหยอดลง 1 เม็ด เมล็ดผักกาดเต็มเสมอปากกำแพงนั้นนานเท่าใด จึงกำหนดว่าเป็น 1 กัป (ดูการประมาณความยาวนานใน อสงไขย)

จากวิธีที่ 1 เราต้องประมาณว่าการเอาผ้ามาเช็ดหินนั้น หินสึกลงไปเท่าไร สมมุติว่าหินสึกไปน้อยที่สุดเท่าที่จะสึกได้ ก็แสดงว่าหินสึกไปประมาณขนาดของอะตอม ตีว่าขนาดอะตอมประมาณ 1 อังสตรอม (หรือเท่ากับหนี่งส่วนสิบนาโนเมตร = 0.1/1,000,000,000 เมตร) แสดงว่าทุกร้อยปีหินจะสึกไปหนึ่งส่วนสิบนาโนเมตร ถ้าจะให้หินสึก 16 กิโลเมตร ( = 16,000,000 เมตร) ก็ต้องใช้เวลา = 100 ปี x 16,000,000 เมตร / (0.1/1,000,000,000) เมตร = 16,000,000,000,000,000,000 ปี หรืออ่านว่า 16 ล้าน ล้าน ล้านปี (หรือประมาณเท่ากับพันล้านเท่าอายุจักรวาล) เวลานี้จะเป็น upper boundคือ 1 กัป จะไม่เกิน 16 ล้าน ล้าน ล้านปี

ถ้าจะหา lower bound เราก็สมมุติว่าหินสึกเท่ากับยางรถยนต์สึกเมื่อหมุนไปบนถนน เราสังเกตว่ายางเส้นผ่าศูนย์กลาง 1/2 เมตร จะสึกประมาณ 1 เซ็นติเมตร เมื่อวิ่งไป 50,000 กิโลเมตร ถ้าทุกครั้งที่ยางกลิ้งไปบนพื้นแล้วยางสึกไป d เราจะได้ความสัมพันธ์ d x 50,000 ก.ม. = 1 ซ.ม. x (1/2) ม. x Pi (การคำนวณนี้เป็น lower bound เพราะหินไม่น่าจะสึกได้มากกว่ายางรถยนต์)

จะได้ว่า d = 3.14 อังสตรอม พอเราแทนค่าความสึกเข้าไปในการคำนวณ upper bound เราก็จะได้ lower bound = 10 ล้าน ล้าน ล้านปี

หรือ 1 กัป อยู่ระหว่าง 10 ถึง 16 ล้าน ล้าน ล้านปี จากวิธีที่ 1

จากวิธีที่ 2 ถ้าเราจะถมหลุมขนาด 16 ก.ม. x16 ก.ม. x 16 ก.ม. ด้วยเมล็ดผักกาด (ตีว่าขนาดประมาณ 0.5 ม.ม. x 0.5 ม.ม. x 0.5 ม.ม.) เราจะต้องใช้เมล็ดผักกาดประมาณ 4 พัน ล้าน ล้าน ล้าน เมล็ด ถ้าแต่ละเมล็ดใช้เวลา 100 ปี ก็จะได้ว่า 1 กัป เท่ากับประมาณ 4 แสน ล้าน ล้าน ล้าน ปี

ปรากฎว่าวิธีที่ 1 และวิธีที่ 2 ต่างกัน 25,000 เท่า (ตาเหลือก)

— – —- – —– ———
ป.ล.

1. ถ้าจะให้วิธีที่ 2 ใกล้เคียงกับวิธีที่หนึ่ง เราต้องหาเมล็ดอะไรบางอย่างที่ใหญ่กว่าเมล็ดผักกาดประมาณ 30 เท่า คือขนาดเมล็ดต้องเป็นนิ้วขึ้นไป เช่นเมล็ดขนุน หรือทุเรียน แต่ไม่ควรใช้ลูกมะพร้าวเพราะใหญ่เกินไป

2. ผมสงสัยมานานแล้วว่า คำว่ากัป นานเท่าไรกันแน่ วันนี้พึ่งทดลองหาใน Google เลยเห็นคำจำกัดความ ก็เลยลองคำนวณดู

คำนวณเลข Fibonacci ด้วย Python แบบไม่ช้านัก

ผมเห็นหัวข้อ blog post ว่า “Holy Shmoly, Ruby 1.9 smokes Python away!” ก็เลยกดเข้าไปดู ปรากฎว่าผู้เขียนได้จับเวลาการคำนวณเลข Fibonacci (0, 1, 1, 2, 3, 5, 8, 13, 21, … ) หรือเลขตัวที่ n เท่ากับผลรวมของตัวที่ n-1 กับ n-2 และ Python ใช้เวลาประมาณ 30 วินาที ขณะที่ Ruby 1.9.0 ใช้ประมาณ 12 วินาที ในการคำนวณตัวเลข 35 ตัวแรก

โปรแกรมที่ใช้คำนวณหน้าตาแบบนี้:

def fib(n):
if n == 0 or n == 1:
return n
else:
return fib(n-1) + fib(n-2)

for i in range(36):
print "n=%d => %d" % (i, fib(i))

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

1. ตัวแปรในภาษา Python เป็นตัวแปรที่มี run-time type information ที่ CPU ไม่สามารถทำการคำนวณโดยตรงได้เหมือนตัวแปรพวก int หรือ double ในภาษา C

เวลา Python interpreter ทำการคำนวณ จะต้องหาว่าตัวแปรเป็นประเภทอะไรก่อน จึงจะเลือกคำสั่ง CPU ที่ถูกมาใช้

2. จะเห็นได้ว่าฟังค์ชัน fib(n) เป็นฟังค์ชันที่เรียกตัวเอง (หรือ recursive function) คือการคำนวณ fib(n) จะเรียกใช้ fib(n-1) และ fib(n-2) และค่า fib(0), fib(1), …, fib(k) ก็ถูกคำนวณซ้ำซากอยู่บ่อยๆ

ผมก็เลยคิดถึงวิธีที่จะแก้ปัญหาสองข้อนี้ สำหรับสาเหตุข้อแรกเราสามารถใช้เครื่องมือที่เรียกว่า Psyco ซึ่งทำหน้าที่เหมือน JIT (Just-in-Time) compiler ที่แปลงโปรแกรม Python เป็นคำสั่งที่มีประสิทธิภาพสูงของ CPU โดยตรง พอผมเพิ่มสองบันทัด (สีแดง) เข้าไป:

import psyco
psyco.full()


def fib(n):
if n == 0 or n == 1:
return n
else:
return fib(n-1) + fib(n-2)

for i in range(36):
print "n=%d => %d" % (i, fib(i))

เวลาในการคำนวณก็ลดจาก 36 วินาทีเหลือ 2 วินาที

สำหรับสาเหตุที่สองเราแก้ได้โดยไม่คำนวณอะไรซ้ำๆ โดยเก็บค่าที่เคยคำนวณไว้ไม่ต้องทำใหม่ทุกๆครั้ง (เทคนิคประเภทนี้เรียกว่า Caching หรือ Memoization):

class cachedFib:
def __init__(self):
self.f = {}
self.f[0] = 0
self.f[1] = 1

def fib(self,n):
if n in self.f:
return self.f[n]
else:
self.f[n] = self.f[n-1]+self.f[n-2]
return self.f[n]

cf = cachedFib()
for i in range(36):
print "n=%d => %d" % (i, cf.fib(i))

เวลาในการคำนวณก็ลดจาก 36 วินาทีเหลือ 0.08 วินาที

— – —- – —– ———
P.S.
1. โปรแกรมสำหรับการคำนวณแบบอื่น (โดยไม่ใช้ recursion และในภาษาอื่นๆ) ดูได้ที่นี่
2. ตาราง Fibonacci 300 ตัวแรก (แถมแยกตัวประกอบ)
3. Fibonacci ตัวที่ 10,000,000
4. สูตรน่าสนใจในการคำนวณเลข Fibonacci

ข่าวน่าชื่นใจ

เด็กออสเตรเลียอายุ 14 ปี (เป็นนักดนตรีพังค์ร็อคด้วย) เสี่ยงชีวิตเข้าช่วยชายอายุ 54 ปีที่เป็นลมตกลงไปในรางรถไฟ

เขาเรียนรู้เรื่องแรงลมดูดจากการเคลื่อนที่ของรถไฟจากรายการ Myth Buster ด้วย!

ฝูงปลาโลมาเข้าช่วยคนที่ถูกฉลามขาวกัด โดยว่ายน้ำล้อมรอบคนไม่ให้ฉลามเข้าใกล้

คุณสงสัยไหมว่าทำไมสิ่งมีชีวิตถึงช่วยเหลือกัน ถ้าสงสัยอาจจะอยากอ่านหนังสือที่ผมเคยแนะนำเรื่อง The Evolution of Cooperation

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