Fisher’in kaçış evrim modeli üzerine denemeler

Evrim teorisi temelde basit olmasına rağmen birçok durumda akılda canlandırmakta zor oluyor. Bu nedenle bu konuyu daha iyi anlayabilmek için elimden geldiğince simülasyonlar yazmaya karar verdim. Bu ilk sümülasyonda cinsel seçilim konusunda Fisher kaçış modelini denedim. Önce anladığım kadarıyla bu noktalara kısaca değineceğim ve sonra da simülasyonu sunacağım.

Evrimde doğal seçilimin yanında cinsiyetler arası seçilim de oldukça önemlidir. Hayatta kalabilen bir birey eğer çiftleşemezse genleri bir sonraki nesle aktarılamaz.

Bazı kuş türlerinde erkeklerde hayatta kalma şansını artırmaya yaramayacak büyüklükte kuyruklar vardır. Bu kuyruklar yardım etmediği gibi aynı zamanda yük de olmaktadır. Peki, o zaman nasıl bu kadar büyümüşler?

Ronald Fisher, 1930’da bu durumu açıklayabilecek bir model öne sürdü. Erkekteki süs özelliğini güçlü bir şekilde seçen dişi bu şekilde doğal seçilimin etkisini zayıflatabilirdi. Bu şekilde bu süs, süsün masrafı cinsel seçilimin getirisinden büyük olana kadar artabilir ya da büyüyebilir. Burada masraftan kasıt örneğin kuşun artık hiç uçamayacağı bir kuyruğa sahip olması olabilir. Bu durumda bu erkekler dişiler tarafından seçilecek olsa bile hayatta kalamadıklarından çiftleşme şansı bulamayacaklardır.

Fisher’in açıklaması için erkeklerdeki abartılı süs ve dişilerdeki bu süsü tercih etme genetik özellikler olmalı, yani genlerle nesilden nesile aktarılabilmeli. Gruptaki diğer bireylere göre ortaya çıkan bu iki ayrılık da (erkekteki süs gelişimi ve dişideki bu süsü seçme eğilimi) Fisher’e göre birbirlerini pozitif bir şekilde ilerleteceklerdir.

Süslü erkeği tercih eden bir dişinin dişi yavrusu olursa kendi tercih geni de yüzde elli ihtimalle bu yavruya geçecektir ve bu yavru da yüzde elli ihtimalle annesinin tercih özelliğini gösterecektir. Bu dişi yavru aynı şekilde babadan da büyük süs genini yüzde elli ihtimalle alacak. Her ne kadar kendisi büyük süs özelliğini göstermese de yine kendisi bu geni bir sonraki nesle aktarma şansını sürdürecektir. Aynı mantığı erkek yavru için de yürütebiliriz. Erkek yavru babadan aldığı büyük süs geninin etkisini gösterirken anneden aldığı büyük süs seçim genini de bir sonraki nesle aktaracaktır.

Aşağıdaki linkten bu modelin simülasyonuna erişebilirsiniz. Simülasyon animasyonsuz çalıştırıldığında sadece her nesilde kaç tane normal erkek (normal süse sahip), normal dişi (eş seçimini süs büyüklüğünden bağımsız yapan), farklı erkek (büyük süse sahip) ve farklı dişi (eş seçiminde büyük süsü tercih eden) birey olduğu hesaplanıyor. Bir sonraki nesli üretmek için o nesildeki bireyler seçim yöntemlerine göre birer eş seçiyor ve sonraki nesilde toplam popülasyon büyüklüğünde çocuk oluşana kadar ürüyorlar. Çocukların erkek veya dişi olması ya da babadan ve anneden hangi genlerin geleceği rastgele seçiliyor. Eş seçiminde monogami ya da poligami olması seçeneği de mevcut. Poligamide bir erkek birden fazla dişi ile çiftleşebiliyor. Burada çiftleşmeden kastım başarılı döllemedir, beraber olma sıklığı ya da çeşitliliği simülasyonda ele alınmamıştır. Eğer animasyon seçeneği kullanılırsa popülasyon büyüklüğünü küçük tutmak iyi olacaktır yoksa hem simülasyon çok uzun sürecek hem de popülasyon ekrana sığmayacaktır. Animasyon modunda bireyler dikdörtgen şeklinde gösterilmektedir. Erkek bireyler E, dişi bireyler de D harfi ile işaretlenir. Dikdörtgenlerin alt tarafında anne ve babadan geçen genler gösteriliyor. S geni, büyük süsü gösterirken s geni de normal süsü göstermektedir. Aynı şekilde T geni büyük süsü tercihi simgelerken t geni de rastgele tercih anlamına geliyor. Üremeye katılan çiftler animasyon sırasında yeşil gösteriliyor. Sonra bir alt satırda bu birleşmeden ortaya çıkan çocuklar yeni nesilde genlerle beraber gösteriliyor. Ardından dişi birey bu nesilde bir daha çiftleşemeyeceğinden kırmızıya dönüyor. Eğer ilişki durumu monogamiyse erkek birey de kırmızı oluyor. Poligami seçilmişse aynı erkek başka çiftleşmelerde de bulunabiliyor.

Üreme aşamasında şöyle bir algoritma kullandım. Seçilen çiftleşmelerden önce sırayla birer çocuk ürüyor. Ardından toplam nüfus istenen değere ulaşana kadar aynı çiftleşmelerden rastgele seçimler yapılıyor ve basla çocuklar da ürüyor. Animasyon sırasında ise bu iki kademe aynı anda oluyor gibi gösterilmekte.

Simülasyonlarda da görüldüğü gibi poligaminin yaygın olduğu popülasyonlarda aşırı süs ve bu süslerin tercih genleri daha hızlı yayılıyor.

Simülasyon

Bu simülasyonda daha başka özellikler de görmek isterseniz bunu yorum kısmında belirtebilirsiniz.

Robot programlama (Çizgi sayma)

Bu sefer robotu üçüncü çizgide durdurma problemine bakayım dedim. Temel Lego programlama derslerinde işlenen bir problem. Robot zeminden farklı renkte çizgilerin üzerinden geçerken üçüncü çizgide durmalı. En basit çözümlerden biri heralde şöyle olabilirdi:

Yavaşça kısa süre hareket et.

Çizgi görene kadar ilerle.

Çizgiyi görünce dur.

Bu üç adımı üç kere tekrarlayan bir program bu problemi çözer.

Yeni şeyler öğrenebileceğim bir çözüm aradım ve aşağıdaki programı yaptım. Bu programda birbirine paralel (yani aynı anda) çalışan iki program akışı var. Başlangıç bloğundan çıkan iki ayrı yol bu program parçalarını belirliyor. Önce programa iki tane başlangıç bloğu koyup yaptım bunu ama nedense ikisini de tek tek çalıştırmam gerekti. Bu şekilde iki program parçası da tek bir tuşla başlatılabiliyor.

Alt taraftaki program parçası sadece robotu sürekli ileri doğru hareket ettiriyor ve sonsuz bir döngüye giriyor, yani bu program hiçbir şeye bakmadan sürekli ierliyor. Bu döngüden sonra ise robotu durdurma bloğu var. Demek ki bu döngü o kadar da sonsuz değilmiş. Evet, bu döngünün ömrünü üst taraftaki program parçası belirliyor.

Üstteki program parçası temelde şunu yapıyor. Renk değişimi olana kadar bekliyor. Değişiklik olunca yeni rengi bir değişkene yazıyor. Eğer yeni renk siyah ise (kullandığım çizgilerin rengi siyahtı) o ana kadar görülmüş çizgi sayısı değişkenini bir arttırıyor. Eğer toplam 3 olmuşsa alt taraftaki sonsuz döngüyü bitiriyor ve böylece motor duruyor.

Programda iki tane değişken var. Bunlar biri ‘color’ adında diğeri de ‘line’ adında kırmızı bloklar şeklinde tanımlanmış. Bu blok programlama dilinde beni en rahatsız eden şey değişken kullanımı oldu. Bir değişkenin değerini arttırmak için önce bir değişken okuma bloğu kullanıyoruz. Sonra bu değişkenin çıktısını toplama bloğuna sokuyoruz. Çıkan sonucu da tekrar değişken yazma bloğuna gönderiyoruz. Basit bir işlem için üç blok gerekiyor yani. Bu blokları bir araya getirip kendi bloklarımıza yapabiliriz ama bu işi henüz o kadar öğrenmedim.

Üstteki program parçasının alt kısmında toplama bloğunun girişlerinin biri çizgi sayısı değişkeninin değeriyken diğeri de renk değişkeninin siyah olup olmadığını kontrol eden karşılaştırma bloğunun çıkışıdır. Eğer renk değişkeninin yeni değeri siyah ise karşılaştırma bloğunun çıkışı 1 değerine, aksi durumlarda ise 0 değerine sahip oluyor. Bu nedenle aşağıdaki toplama bloğu sadece renk geçisi siyaha olursa çizgi değişkenini 1 arttırıyor, diğer durumlarda ise 0 arttırıyor, yani sabit tutuyor.

Sonraki blok ise çizgi sayısı değişkeninin değerinin 3 olup olmadığını kontrol ediyor. Eğer 3 ise çıktı doğru oluyor ve bir sonraki döngü bloğu bitiyor. Eğer 3 değilse çıktı yanlış oluyor ve döngü devam ediyor. Bu döngü bitince de döngü durdurma bloğu çalışıyor ve bu blokta kullanılan numara bitirmek istediğimiz döngüye verdiğimiz numarayla aynı olmalı (Programda 02). Dikkat edersek üstteki program parçası 01 numaralı döngüye, alttaki program parçası ise 02 numaralı döngüye sahip. Biz de 02 numaralı döngüyü bitirmek istiyoruz, çünkü böylece motor duracak.

Aiağıdaki kısa filmde programı çalışırken görebilirsiniz.

Robot programlama

Bir süredir Serkan’a aldığım Lego Mindstorms EV3 setiyle oynuyorum. Pahalı olmasına rağmen oldukça hoşuma giden bir öğrenim imkanı.

Programlamayı şimdilik Lego Mindstorms EV3 yazılımıyla yapıyorum. İlk başta android için olan uygulamayı kullanmıştım ama orada çok daha az blok olduğundan bazı programlar daha zor oluyordu.

Aşağıda ilk denemelerimden birini görebilirsiniz. Sonsuz döngü içinde hareket eden bir robot. Kızılötesi sensörle önünde bir engel olup olmadığına bakıyor. Eğer bir engel varsa biraz geriye gidip restgele seçtiği bir yöne dönüp bir sonraki engele kadar ilerliyor. Programdaki ses blokları temel program için önemli değildir.

Program sonsuz döngü içinde çalıştığından robotu durdurmak için kontrol bloğunun üzerindeki düğmeyi kullanmak gerekmekte. Programda tabii ki hangi sensörün ve motorun hangi giriş kanalına bağlandığına dikkat etmek lazım. Aşağıdaki program B ve C kanallarına takılı büyük motorları ve 1. kanalda bulunan kızılötesi sensörünü kullanmakta. Bekleme bloğu kızılötesi sensör engel algılayana kadar motorun düz hareket etmesini sağlıyor. Engel algılandıktan sonra motoru durduruyorum çünkü diğer durumda ses dosyası motor gürültüsünden duyulmayabiliyor. Yani ses dosyaları kullanılmazsa motorları durdurmaya da gerek yok. Ses dosyası çalındıktan sonra motorlar geriye doğru bir tur döndürülüyor. Rastgele sayı bloğu 1 ile 4 arasında (1 ve 4 dahil) rastgele bir tamsayı üretiyor ve sonraki ‘switch’ bloğunda her bir ihtimale karşı ne yapılacağı programlanıyor.

Bir engelle karşılaşınca yön değiştiren robot progamı

Aşağıdaki videoda da robotu çalışırken izleyebilirsiniz.

Fimo – çiçeğimsi

Evdeki polimer hamurlarla ne yapayım acaba diye düşünürken aşağıdaki videoyu gördüm. Şansımı deneyeyim dedim.

[embedyt] https://www.youtube.com/watch?v=S2h6sEuoa4o[/embedyt]

Videoyu dikkatli izlememişim ki sarı silindirlerin etrafını tamamen beyaz hamurla çevirdim ve çıkan sonuç şu oldu:

https://www.instagram.com/p/BeEKUrpFDss/?taken-by=galahantine

Yıpratma savaşı

Bu oyunda bireyler yine ortak kaynaklar için mücadele ediyor. Bu sefer mücadele kazanç ya da kayıplarını bir tablo şeklinde göstermeyeceğiz. Bunun yerine bireylerin bu ortak kaynak için ne kadar masrafa gireceğine bakacağız. Bu oyunda da kaynak ve masraf tabii ki çok çeşitli şeyler olabilir.

Örnek: İki birey de yiyecek için kavga ediyor olabilir. Burada yiyecek ortak kaynak. Kavganın ne kadar süreceği de masraf olabilir. Kavga uzadıkça yaralanma riski artabilir ve eğer bu yiyecek kazanılamazsa bir başka kavga için hem zaman hem de enerji yetmeyebilir. İki bireyin aynı yiyecek için planladığı masraflar da farklı olabilir. İkisi de aynı derecede aç olmayabilir.

A ve B türü bireylerin aşağıdaki tabloya göre davrandıklarını varsayalım.

 

[table id=9 /]

\(V \) : kaynağın değeri

\(m_{a} \) : A bireyinin bu kaynak için yapmaya hazır olduğu masraf

\(m_{b} \) : B bireyinin bu kaynak için yapmaya hazır olduğu masraf

Daha yüksek masrafa girmeye hazır olan birey mücadeleyi kazanıyor. Tabloya göre iki birey de daha düşük masraf kadar harcama yapmış oluyor. Örnek olarak eğer masraf mücadele zamanıysa iki birey de hangi birey daha kısa mücadele etmeyi tercih etmişse o kadar süre mücadele ettiğinden, o kadar masraf yapmıştır. Mücadeleyi kazanın birey yaptığı masrafa karşın ödülü (kaynağı) de tek başına kazanıyor.

Eğer iki birey de eşit masrafta bulunmuşsa, net kazançları kaynağın yarısı (eşit paylaşıyorlar) eksi yaptıkları masraf kadardır.

Eğer bütün bireyler \(M\) masraflı stratejiyi benimserse o zaman \(M+\delta M \) masrafa (çok az bir ek masraflar) hazır bir mutant populasyonu işgal edebilir.

Örnek: \(V=4 \), \(m_{a}=1 \) olsun. Bu populasyona \(m_{b}=1.1 \) olan bir mutant katılsın. A bireyleri birbirleriyle karşılaştığında net kazançları \(\frac{4}{2} – 1=1 \) olacak. Buna karşın B bireylerinin A bireylerine karşı net kazançları \(4-1=3 \) olacak. A bireyleri ise bu karşılaşmalarda \(-1 \) kaybedecekler. Buna göre B stratejisi A stratejisine göre avantajlı olacak.

Başka bir örnek: Eğer populasyondaki bireyler kaynağın değerinin yarısından daha fazla masrafa girmeye hazırsa ilginç bir strateji bu populasyonu işgal edebiliyor. Hiç masrafa girmemek. Mutantların çok az olduğunu dikkate alırsak populasyondaki normal bireylerin çoğunlukla birbirleriyle karşılaşacağını görebiliriz. Bu durumda mutantlar hiçbir mücadeleyi kazanamayacak ama masrafa girmediklerinden kayıpları da olmayacak. \(\frac{V}{2}-m_{a} \) değeri bu senaryoda negatif olacağından normal bireyler birbirleriyle karşılaşmalarından hep kayıpla çıkacaklar. Bu da mutantları daha avantajlı duruma getirecek, çünkü aynı başlangıç durumuyla bir kayıpları olmayacak.

Bu örneklerden anlaşılıyor ki sabit bir stratejiyle populasyon mutantlara karşı korunamıyor. Peki nasıl bir strateji güdülmeli?

Problemi matematiksel olarak çözdüğümüzde (Çözümün nasıl yapıldığını burada vermeyeceğim) şöyle bir dağılım çıkıyor:

\(p(x)=\frac{1}{V}\cdot{e^{\frac{-x}{V}}} \)

Bireyler bu dağılıma göre rastgele bir x değerini masraf olarak seçmeli. Bu işlemin nasıl yapılacağı ilk bakışta karışık tabii. Özellikle doğada ‘basit’ canlıların bunu nasıl yaptığı. Bu dağılım daha basit bir şekilde söyle ifade edilebilir. Bu stratejiye göre davranan birey başlangıçta bir sabit sayı (\(\frac{1}{V}\)) seçiyor. Bu seçim tabii ki evrim sürecinde oluşmuş da olabilir, yani genetik olarak nesilden nesile ufak değişimlerle aktarılan bir sabit. Birey her birim zaman sonunda eğer rakibi hala mücadeleye devam ediyorsa bu sabit olasılıkla ya mücadeleye devam edecek ya da bırakacak. Bu davranış şeklini her birim zamandan sonra uygularsa yukarıda verilen dağılıma ulaşmış olur. Örneğin, sabit olasılık değeri 0.5 ise, mücadele sırasında her dakikadan sonra birey yazı tura atabilir. Eğer rakip devam ediyorsa ve tura gelirse devam eder, yazı gelirse çekilir. Bir sonraki dakikanın sonunda aynı işlemi takrarlar.

Bu yöntem aslında kısmen kolayca anlaşılabilir. Eğer rakipler birbirlerinin durumundan ek bilgi (acaba rakip mücadeleye devam edecek mi yoksa etmeyecek mi) elde edemiyorsa o zaman her adımda kullanılan olasılığı değiştirmek için bir neden yok. İlk başta hangi olasılık kullanılmışsa o olasılıkla devam edilebilir.

Ayrıca bu çözümün başka bir güzel tarafı da bazen en iyi stratejinin rastgele hareket etmek olduğunu göstermesi.

Aşağıdaki oyun linkinden bu oyunun oynanabileceği sayfaya erişilebilir. Oyunda sadece sabit stratejiler yer almakta. Ayrıca bu sabit stratejiler oyun başlamadan önce belirleniyor. Bu oyunun değişik varyantları da programlanabilir (ileride yapmayı düşünüyorum). Örneğin, bireyler rakibinin görünüşünden ek bilgiler elde edebilir. Büyüklüğünden, saldırganlığından ve daha başka özelliklerinden ne kadar masraf yapmaya eğilimli olduğunu çıkarıp ona göre değişken stratejiler uygulayabilir.

Oyun linki

Bir İşlem

Yurt dışında “Countdown”, Türkiye’de ise “Bir Kelime Bir İşlem” adıyla bilinen yarışma programının işlem kısmını sonunda bir Web uygulaması olarak bitirmiş bulunuyorum. Sayfa düzeni şimdilik mobil cihazlar göz önünde tutularak hazırlanmış durumda.

Oynanış: Oyunda hedef verilen altı adet sayıyyla dört işlem yaparak hedef sayıya mümkün olduğunca yaklaşmak. Bir kullanılan sayı bir daha kullanılamıyor. Bu sayılar kırmızı kenarlarla gösteriliyor. Sarı kenarlı sayılar kullanılabilecek sayıları gösterirken, seçilmiş sayı da yeşil kenarla gösteriliyor. İşlemin ilk sayısını seçtikten sonra bir işlem seçiliyor. Ardından da bu işlem için gereken ikinci sayı seçiliyor. Bu aşamada program işlemin sonucunu ilk seçilen sayının yerine yazıyor ve ikinci sayıyı kullanılmayacak şekilde işaretliyor. Bir sonraki adımda işlemin sonucu hemen kullanılabilsin diye bu sayı otomatik olarak seçiliyor. Eğer başka bir sayı ile işlem yapılmak istenirse kullanıcı sarı sayılardan birini seçebilir. Bu durumda seçilen sayı değişecektir.

İşlemlerin altındaki sırada ise oyunla ilgili tuşlar bulunmakta. En soldaki tuş o ana kadar bulunmuş en yakın sonucu çözüm olarak değerlendirmeye sokuyor. Bu tuşa basılınca kalan zamana ve hedefe ne kadar yaklaşıldığına göre bir skor hesaplanıyor. Onun yanında çözüm tuşuna basılınca program hedefe olası en yakın çözümü hesaplıyor ve bu tuşların altındaki alana bu çözümü yazıyor. Geri al tuşuna basınca son yapılan işlem geri alınıyor ve kullanıcı başka bir işlem yapabiliyor. Bu şekilde oyunun en başına dönmek mümkün. En sağdaki tuşla da yeni bir oyun başlatılıyor.

Programla ilgili biraz da bilgi vereyim. Oyun HTML, CSS ve Javascript kodlarından oluşuyor. Çözüm algoritması verilen sayılarla olası bütün işlemleri yapıyor ve her işlemden sonra sonuçla karşılaştırıyor. Eğer ciddi bir hata yapmadıysam çözüm tuşuna (ampule) basınca program en iyi çözümü gösterecektir. Bu en iyi çözüm sırasında bazen gereksiz işlemler de oluyor ama sonucu etkileyen bir durum değil bu. Henüz bu gereksiz işlemleri çözümden çıkaracak kısmı programlamadım.

Program mobil cihazlarda CSS viewport birimleri destekleyen tarayıcılarda doğru gösteriliyor. Şimdilik sadece Chrome (51 ve sonrası) ve Firefox (48) versiyonlarıyla test edebildim. Android standard tarayıcıda doğru çalışmadığına dair ekran görüntülerini de gördüm.

Programın geliştirilmesi aşamasında fikirlerinden (Kullanıcı ara birimi ve oynanış) faydalandığım Hatice Savaş’a da teşekkürlerimi sunarım.

Bir İşlem

CSS ile imtihanım

Birkaç gündür programda kullandığımız Audit dosyasının görünüşüyle ilgili sorunlarla uğraşıyordum. Audit dosyası verilei barındıran bir XML dosyası. Bu dosya bir XSL dosyası yardımıyla HTML sayfasına dönüştürülüyor. Test bölümü bu HTML çıktısında bazı satırların sayfaya sığmadığını bildirdi ve böylece bu maceramın başlangıcına gelmiş oldum. Çıktıda bazı satırlar sayfaya sığmadığı gibi en sağdaki sütun hep bir sonraki satırdan başlıyordu:

31-03-2016 13:14:16
Recep
Sistem ayarlarıyla öyle oynandı ki sistem artık saçmalamaya başladı
31-03-2016 13:14:15
Recep
Sistem ayarlarıyla oynandı

 

Aradığım çözüm ise son sütunun diğer sütunlarla aynı hizada başlaması ve sayfanın sağından taşan yazının da bir alt satırdan ama sütunun başladığı yerden devam etmesiydi. Ayrıca son sütun birden fazla satıra yayıldığında ise sütunları kapsayan bütün div elementi de aynı yüksekliğe sahip olmalı ki bu kayıt bir sonraki kaydın görüntüsünü bozmamalı. Sonunda şu sayfanın da yardımıyla aradığım sonuca ulaştım:

31-03-2016 13:14:16
Recep
Sistem ayarlarıyla öyle oynandı ki sistem artık saçmalamaya başladı
31-03-2016 13:14:15
Recep
Sistem ayarlarıyla oynandı

[sourcecode]
.table-layout {
display: table; width:100%;
}

.row-layout {
display: table-row; width:100%;
}

.dateTime {
white-space: nowrap;
width: 40%;
display: table-cell;
}

.source {
white-space: nowrap;
width: 20%;
display: table-cell;
}

.audit {
width: 50%;
display: table-cell;
}

<div class="table-layout">
<div class="row-layout">
<div class="dateTime">
31-03-2016 13:14:16
</div>
<div class="source">
Recep
</div>
<div class="audit">
Sistem ayarlarıyla öyle oynandı ki sistem artık saçmalamaya başladı
</div>
</div>
<div class="row-layout">
<div class="dateTime">
31-03-2016 13:14:15
</div>
<div class="source">
Recep
</div>
<div class="audit">
Sistem ayarlarıyla oynandı
</div>
</div>
</div>

[/sourcecode]