Etiket: Squid Game, Python, simülasyon, olasılık, Monte Carlo

  • Squid Game’deki Cam Köprüyü Python ile Simüle Etmek: Hayatta Kalma Olasılığı

    Squid Game’deki Cam Köprüyü Python ile Simüle Etmek: Hayatta Kalma Olasılığı

    Squid Game’in cam köprü bölümünü izlerken aklımdan geçen ilk soru şuydu: sıranı seçebilseydin kaçıncı olmak isterdin? Bu yazıda bu soruyu Python’la cevaplıyorum. Önce oyunu 100.000 kez simüle edeceğiz, sonra aynı sonucu basit bir olasılık formülüyle doğrulayacağız.

    Kodun tamamı Colab’da hazır: Colab’da Aç

    Squid Game hakkında kısaca

    Squid Game, Hwang Dong-hyuk’un yarattığı, yazdığı ve yönettiği Güney Kore yapımı bir dizi. İlk sezonu 17 Eylül 2021’de Netflix’te dokuz bölüm olarak yayımlandı. Netflix’in açıklamasına göre ilk 28 günde 142 milyondan fazla hanede izlendi ve 1,65 milyar saatlik izlenmeye ulaştı.

    Hikâyede borca batık 456 kişi, büyük bir para ödülü için çocuk oyunlarından oluşan bir yarışmaya katılıyor. Oyunlar tanıdık, kuralları basit; ama kaybedenler elendiğinde hayatını kaybediyor. Dizinin adı da Kore’de çocukların oynadığı bir sokak oyunundan geliyor. Basit kuralların ardına saklı büyük riskler, diziyi olasılık ve oyun teorisi merakları için de ilginç bir malzeme yapıyor.

    Cam köprü oyunu

    Yedinci bölümde (“VIPS”) oyuncular iki sıra cam panelden oluşan bir köprüyü geçmek zorunda. Her adımda biri sağda biri solda iki panel var. Biri temperli cam ve bir insanı taşıyor, diğeri sıradan cam ve kırılıyor. Dışarıdan bakınca ikisi aynı görünüyor.

    Aslında bu bir yazı tura oyunu, ama bir farkla: oyuncular sırayla geçiyor ve arkadakiler öndekilerin bastığı yerleri görüyor. Önden giden biri doğru cama basarsa o adım artık herkes için güvenli. Yanlış cama basarsa düşüyor, ama o adımda diğer camın doğru olduğu da ortaya çıkıyor. Yani her bilinmeyen adım ya bir kişinin şansıyla ya da bir kişinin düşüşüyle çözülüyor.

    Modelin varsayımları

    Matematikçilerin bu oyun için kurduğu modelleri esas aldım (Chalkdust dergisindeki analiz gibi):

    • Köprü 18 adım, oyuncu sayısı 16.
    • Her adımda iki cam eşit olasılıklı: doğruyu seçme şansı %50.
    • Oyuncular camları ayırt edemiyor ve öndekilerin açtığı yolu hatasız hatırlıyor.
    • Süre sınırı, itip kakma ya da ışıkların kapatılması gibi dizideki olaylar modelde yok.

    Bu varsayımlar gerçek dünyayı basitleştiriyor. Bunun bedelini yazının sonunda, dizideki sonuçla karşılaştırırken göreceğiz.

    Simülasyonu yazmak

    Simülasyon, bir olayı bilgisayarda binlerce kez tekrar oynatıp ne sıklıkla ne olduğunu saymak demek. Gerçek hayatta bu oyunu 100.000 kez oynatamayız ama bilgisayarda birkaç saniyede yapabiliriz.

    Tek bir oyunu oynatan fonksiyon şöyle:

    import numpy as np
    def kopruyu_gec(oyuncu=16, adim=18, rng=None):
    """Bir oyunu simüle eder; hayatta kalan oyuncuların sıra numaralarını döndürür."""
    rng = rng or np.random.default_rng()
    bilinen = 0 # öndekilerin açtığı yol buraya kadar güvenli
    kalanlar = []
    for sira in range(1, oyuncu + 1):
    konum = bilinen # bilinen yolu güvenle yürü
    hayatta = True
    while konum < adim:
    konum += 1 # bir sonraki bilinmeyen adıma bas
    if rng.random() >= 0.5: # yazı tura: yanlış cam
    hayatta = False # düştü, ama bu adım artık biliniyor
    break
    bilinen = konum
    if hayatta:
    # bu oyuncu köprüyü bitirdi; arkadakiler de açılan yoldan geçer
    kalanlar = list(range(sira, oyuncu + 1))
    break
    return kalanlar

    Kodun mantığı adım adım:

    1. bilinen değişkeni, önceki oyuncuların çözdüğü son adımı tutuyor. Başta 0, yani hiçbir adım bilinmiyor.
    2. Sıradaki oyuncu bilinen yolu güvenle yürüyüp ilk bilinmeyen adımdan itibaren yazı tura atmaya başlıyor.
    3. Yanlış cama basarsa düşüyor. Ama bastığı adım da artık biliniyor, çünkü kırılan camın yanındaki doğru cam.
    4. Bir oyuncu 18. adımı geçerse köprü tamamen çözülmüş oluyor; ondan sonraki herkes güvenle geçiyor.

    rng.random() 0 ile 1 arasında rastgele bir sayı üretiyor. Sayının 0,5’ten küçük olma ihtimali tam %50, yani bu bir yazı tura.

    100.000 kez oynatmak

    rng = np.random.default_rng(42) # aynı sonucu tekrar alabilmek için tohum
    N = 100_000
    hayatta_kalma = np.zeros(17) # her sıra numarası için kaç kez hayatta kaldı
    kalan_sayilari = []
    for _ in range(N):
    kalanlar = kopruyu_gec(rng=rng)
    kalan_sayilari.append(len(kalanlar))
    for sira in kalanlar:
    hayatta_kalma[sira] += 1
    olasilik = hayatta_kalma[1:] / N # 1'den 16'ya kadar her sıranın hayatta kalma oranı
    print("Ortalama hayatta kalan:", np.mean(kalan_sayilari))

    default_rng(42) içindeki 42 bir “tohum” (seed). Rastgele sayıları her seferinde aynı sırayla üretir, böylece sen de not defterini çalıştırdığında benimle aynı sonucu alırsın.

    Sonuçlar: sıran ne kadar önemli?

    100.000 oyunun sonunda ortalama 7,0 oyuncu köprüyü geçti. Asıl ilginç olan, bu yedi kişinin kim olduğu:

    İlk sıradaki oyuncunun köprüyü geçmesi için 18 yazı turanın hepsini bilmesi gerekiyor: yaklaşık 262.000’de 1. Son sıradaki oyuncu ise neredeyse kesin geçiyor (%99,93). Eğri ortada çok dikleşiyor: 8. sırada %24 olan şans 10. sırada %59’a, 12. sırada %88’e çıkıyor. Yani dizideki gibi sıra numarasını görmeden seçmek, bu oyundaki en büyük kumar.

    Bir de en az bir kişinin köprüyü geçme ihtimali var: simülasyonda 100.000 oyunun %99,94’ünde en az bir kişi karşıya ulaştı.

    Aynı sonucu formülle bulmak

    Simülasyon güzel ama sonucun doğru olduğundan nasıl emin olacağız? Bu oyunun aslında çok basit bir matematiksel yapısı var.

    Şöyle düşün: 18 adımın her biri bir kez, ilk basan kişi tarafından “çözülüyor”. Her çözümde %50 ihtimalle biri düşüyor. Yani köprünün tamamında toplam kaç kişinin düşeceği, 18 kez yazı tura atıp kaç kez tura geldiğini saymakla aynı şey. Bu, olasılıkta binom dağılımı denen yapı.

    k. sıradaki oyuncu, toplamda k’den az kişi düşerse hayatta kalıyor. 18 atışta tam d kez tura gelme olasılığı C(18, d) / 2¹⁸, bunları 0’dan k − 1’e kadar topladığımızda cevabı buluyoruz:

    from math import comb
    def tam_olasilik(oyuncu=16, adim=18):
    """k. oyuncunun hayatta kalma olasılığı: 18 adımda k'den az düşüş olması."""
    return [sum(comb(adim, d) for d in range(k)) / 2 ** adim for k in range(1, oyuncu + 1)]
    olasiliklar = tam_olasilik()
    print(f"Beklenen hayatta kalan: {sum(olasiliklar):.2f}") # 7.00

    comb(18, d), 18 adımın hangi d tanesinde birinin düşeceğini seçmenin kaç yolu olduğunu veriyor. Formülün sonuçları simülasyonla her sırada en fazla 0,3 puan farklı; bu fark da sadece rastgelelikten. Beklenen hayatta kalan sayısı da yine 7.

    Buradan bir sezgi daha çıkıyor: ortalamada 18 adımın yarısında, yani 9 adımda biri düşüyor. 16 kişiden 9’u düşerse geriye 7 kişi kalır.

    Peki dizide neden sadece 3 kişi kaldı?

    Dizide köprüyü yalnızca üç oyuncu tamamlayabiliyor. Modele göre 3 veya daha az kişinin kalma ihtimali sadece %4,8. Peki bu kadar kötü bir sonuç nasıl çıktı?

    Modelimizin dışarıda bıraktığı şeyler dizide yer alıyor. Bölümde ışıkların kapatılması gibi bir avantajın ortadan kaldırılması, oyuncuların birbirine karışması ve süre baskısı var. Bunların her biri, adım başına %50 olan düşme ihtimalini artırıyor ya da bilinen bir adımı tekrar bilinmez hâle getiriyor.

    Bu, her modelin taşıdığı bir uyarı: sonuç, varsayımlar kadar iyi. Matematiğin yanlış olduğunu değil, gerçek dünyanın modelden daha karmaşık olduğunu gösteriyor.

    Diziyi izlerken bu bölümde kalbim kulaklarımdaydı. O sırada aklımdan geçen de şuydu: ben olsam ya ortalardan bir numara ya da 8. sırayı seçerdim. Seçimim tamamen sezgiseldi. Şimdi matematiksel temelini bildiğim için biraz farklı bakıyorum: 8. sırada hayatta kalma şansı %24, sadece iki sıra geride, 10. sırada ise %59. Sezgim beni ortaya yakın bir yere götürmüş ama hesap, birkaç adım daha geride durmanın ne kadar fark yarattığını gösteriyor.

    Kendin dene

    Not defterinde değerleri değiştirip şu soruları cevaplayabilirsin:

    • Köprü 18 değil 30 adım olsaydı kaç kişi kalırdı? (kopruyu_gec(adim=30))
    • Oyuncular camları biraz ayırt edebilseydi, doğruyu bulma şansı %50 yerine %60 olsaydı ne değişirdi? (Fonksiyondaki 0.5‘i değiştir.)
    • 16 oyuncunun kaçının hayatta kaldığının dağılımını histogram olarak çiz. En sık görülen sonuç hangisi?