Thursday, September 07, 2006

ประตูสามบาน

เมื่อวันก่อนตอนประชุมกัน มีการหยิบยกโจทย์ประตูสามบานขึ้นมาคุยกัน
จำได้ว่าเคยอ่านเจอใน blog ของ ฮุ้ย ก็เลยไปค้นเจอหัวข้อ ปริศนาเกมส์โชว์
ในนั้นมีการอ้างถึงหนังสือ "Information Theory, Inference and Learning Algorithms"
ก็เลย download มาดูเฉลย

[กรุณาอ่านโจทย์ใน link ก่อน แล้วค่อยอ่านข้างล่างนี้]
ใน commonsense ของเรา เราก็ต้องบอกว่า chance ของการได้ทอง
มันเหลือ 50-50 แล้ว การเปลี่ยนหรือการไม่เปลี่ยน ควรจะมีความน่าจะเป็นเท่าๆกัน
แต่หลังจากอ่านเฉลย ทำให้เรารู้ว่ามันมี event หนึ่งที่เราลืมคิดไป
นั่นก็คือ event ของ พิธีกรเกมส์โชว์ ที่เลือกเปิดประตูเบอร์ 3
event นั้นมีการกระจายตัวที่ไม่เท่ากัน เช่น

สมมติว่าถ้าทองอยู่ที่ประตู 1, พิธีกร จะเลือกเปิดประตู 2 หรือ 3 ก็ได้
ดังนั้นโอกาสที่จะเปิดประตู 3 มีค่าเท่ากับ 50%
แต่ถ้าทองอยู่ที่ประตู 2 , พิธีกร มีทางเลือกแค่ทางเดียวในการเปิดประตู
ดังนั้นโอกาสที่จะเปิดประตู 3 มีค่าเป็น 100%

ในเฉลย เขาเอา Bayes' theorem เข้ามาคำนวณ
ซึ่งสำหรับคนที่ไม่คุ้นกับ language ทางคณิตศาสตร์ (เช่นผม)
ก็ต้องใช้เวลา absorb นานหน่อย

แต่สำหรับคนที่ขี้เกียจอ่าน math language
ก็มีเฉลยอีกแบบ ที่เขาเรียกว่า "more intuitive"
ก็คือให้ลองคิดโจทย์นี้ใหม่ โดยจับโจทย์มาขยาย scale
เปลี่ยนเป็นว่า มีประตูอยู่ 1,000,000 ประตู
เราเลือกประตูเบอร์ 1, พิธีกรเปิดประตู 999,998 ประตูที่เหลือ
เพื่อโชว์ว่าไม่มีทองในประตูเหล่านี้
ถามว่าเราจะยังเลือกประตูเบอร์ 1 อยู่หรือไม่ หรือจะเปลี่ยนไปเลือกอีกประตูหนึ่งดี

พอเปลี่ยน scale โจทย์มาแบบนี้ ก็เลย Bingo เลย
ถ้าเปลี่ยนประตู โอกาสชนะนี้เกือบ 100% เลย
เพราะในการเลือกครั้งแรก เรามี chance อยู่แค่ 1 ใน 1,000,000 เท่านั้นเอง

ps. ใน link ของฮุ้ยมีโปรแกรม simulation ที่ otto เขียนไว้
แต่เนื่องจากทืม mm.co.th กลับจากญี่ปุ่นกันหมดแล้ว
link ก็เลยหายไปด้วย
ผมเลยเขียนโปรแกรม simulate ใหม่ขึ้นมา
def rand_door
rand(3) + 1
end

def open_second_door(gold_door, first_guess)
doors = [1,2,3]
doors.delete(gold_door)
doors.delete(first_guess)
doors[rand(doors.size)]
end

def choose_left_door(first_guess, opened_door)
(1..3).each {|door|
return door if (door != first_guess && door != opened_door)
}
end

def play
gold_door = rand_door
first_guess = rand_door
opened_door = open_second_door(gold_door, first_guess)
left_door = choose_left_door(first_guess, opened_door)
result = gold_door == left_door ? "win" : "loss"
puts <<-EOS
Game begin.
You don't see this. -> (Gold is at
#{gold_door})
First. you choose door number
#{first_guess}.
I open door number
#{opened_door}.
So. You chnage your mind to door number
#{left_door}.

== You
#{result}. ==

EOS
gold_door == left_door ? 1 : 0
end

win = 0
loops = 30
loops.times do
win += play
end
puts "------------------"
puts "Play
#{loops}, win #{win}"

Related link from Roti

No comments: