Mannheim şehrinin en ünlü eserlerinden birisi Su Kulesi’dir. İnşasının bittiği 1889 yılından 1909 yılına kadar şehrin içme suyu ihtiyacını karşılayan bu kule, 1909 yılından sonra Luzenberg su kulesinin inşasıyla beraber 2000 yılına kadar sadece su deposu olarak kullanılmış.
Kulenin ve çevresindeki parkın süslemelerinde mitolojik figürler kullanılmıştır.
Kulenin en tepesinde bir balığın üzerinde elinde üç dişli mızrağıyla, tanrı Poseidon’un eşi Amphitrit heykeli bulunmaktadır.
Tanrıça Amphitrit
Kulenin iki yanında deniz kabuğundan yapılma borularına üfleyen iki adet Triton heykeli var. Triton tanrı Poseidon ve Amphitrit’in çocuklarıdır. Belden yukarısı insan, belden aşağısı da balıktır.
Triton
Kulenin duvarlarında ne olduklarını bilmediğim başka figürler de var.
Bu figürler kulenin çevresi boyunca sadece bu sırada sürekli tekrarlanıyor.
Bu da yukarıdaki figürlerin daha altında ve kulenin çevresi boyunca kullanılan bir figür.
Kulenin anayola bakan tarafında içinde dört tane triton figürü olan bir havuz var. Sıcak mevsimlerde bu havuz su dolu olur ve figürlerin ağızlarındaki borulardan su fışkırtılır.
Bu figürlerde kuledekilerin aksine deniz kabuğundan bir boru bulunmamakta.
Kulenin diğer tarafında ise daha büyük bir yeşil alan ve havuz bulunmaktadir. Bu alanın etrafı yine değişik figürlerle süslenmiştir.
Büyük havuzun iki tarafında ise birer tane centaur heykeli var. Centaurlar yarı insan yarı at şeklindeki mitolojik yaratıklardır.
Parkın en ucundaki duvarda da sekiz insan figürü var. Bunların da ne olduğunu bilmiyorum.
Bu yazıda internet sitelerinde sık sık gördüğüm bir geometri sorusu üzerine düşüneceğim. Yine aynı sitelerde verilen çözüm yöntemi üzerine de aklıma takılan noktaları inceleyeceğim.
ABC üçgeninin ikizkenar üçgen olduğu verilmiş. EDA açısının değeri soruluyor. Bu aynı zamanda A açısının da değeri çünkü AED üçgeni de ikizkenar. Bu tür soruların çözümünde genelde yardımcı çizimlerle bir eşkenar üçgen elde edilmeye çalışılıyor ve bu sayede bütün açı değerleri hesaplanabiliyor. Bu soru için verilen yardımcı çizim de şu şekildeydi:
|DV| = |BV| = |BD| olacak şekilde bir V noktası seçilmiş. Ya da VDB açısı 60 derece olacak şekilde bir DV doğrusu ve DBV açısı yine 60 derece olacak bir doğru çiziliyor ve bu iki doğrunun kesiştiği noktaya V deniyor. Bu şekilde açı hesaplarını yaparsak da şu sonucu elde ediyoruz.
Böyle güzel bir yardımcı çizimle elde edilen bu basit çözüm beni neden rahatsız etti peki?
Aklıma takılan soru baştan beri hep şu oldu: V noktasının AC kenarı üzerinde olduğunu nereden biliyoruz? BVD üçgeninin eşkenar olacak şekilde çizilebileceğinden şüphem yok ama V köşesinin ABC üçgeni üzerinde olmasını sağlayan bir şart var mı ve eğer varsa bu ne? Eğer yoksa bunu nasıl gösterebilirim?
Önce bu çizimi geogebra’da yaptım ve gerçekten de V köşesi AC kenarı üzerine geldi, bütün açılar ve mesafeler de problemde verilen özelliklere sahip oldu. O zaman ikna olmam çok zor olmamalıydı. Bu sefer o çizimi başka şekilde nasıl elde ederim diye düşünmeye başladım ve şu sonuca ulaştım.
Altmış derecelerle başlamak yerine DVE üçgeni ikizkenar olacak şekilde başlayabilirim. Bu şekilde AC kenarı üzerinde her zaman bir V noktası bulabilirdim. Peki bu V noktasını B noktası ile birleştirirsem ne olur?
Demek ki o eşkenar üçgen çizme yöntemi bu üçgende işe yarıyormuş ama bence bu iyi bir problem çözme yöntemi değil. Öncelikle bu heralde sadece 80-80-20 (iç açılar) ikizkenar üçgeninde işe yarar ve hiçbir açı verilmediğinden bu çizimi yapabilmek cevabı bilmeyi gerektirir. Bunun yerine yukarıdaki ikizkenar üçgen ile başlama hiçbir şekilde böyle bir ön bilgi gerektirmemekte ve aynı sonuca ulaşmakta.
Hislerim bu sefer doğru çıkmadı ama en azından bu soru için artık rahatça ikna olabilirim.
Bu oyunda kumarbaz yazı tura oynamakta. Bilemediği zaman ortaya bir önceki turda koyduğu paranın iki katını koymakta. Böylece daha önceki turlarda kaybettiği parayı da kazanıp kara geçecek. Eninde sonunda kazanacağından kesin kazançlı bir sistem gibi görünüyor.
Bu deneyde problemi matematiksel analiz etmeyeceğim. Sadece programla oyunu oynayıp sonuçları sayacağım. Matematiksel analizleri ders kitaplarında ya da internette bulmak mümkündür.
Yukarıdaki R programıyla bu oyunu kısmen denemeye çalıştım. Kumarbaz her oyunda yazı gelene kadar oynuyor. Yani paranın her tura geldiğinde önceki turda koyduğu paranın iki katını koyuyor. Yazı geldiğinde kazanıyor. Bin kere oynandığında yazı gelene kadar kaç kere yazı tura atıldığını bir diziye koydum ve sonunda toplam yazı tura atışını ve arka arkaya en fazla kaç kere tura geldiğini ekrana yazdırdım. Sonuçlar şuna benzer çıktı.
Yazı gelene kadar gereken ortalama para atışı: 2
Yazı gelene kadar gereken maksimum para atışı: 11
Bu sistemde ortalama para atışının çok düşük olması bu stratejiyi çok cazip yapsa da maksimum para atışı durumlarında kumarbaz başlangıçta koyduğu baranın en az bin katını oynamak zorunda kalacak ve bu bazen pek de mümkün olmayabilir. Özellikle bahisler için üst sınır koyulan yerlerde bu yöntem hiç işe yaramayabilir.
Üniversitede elektronik okumak istiyordum, çünkü aklıma gelen her şey için elektronik devre yapabileceğimi hayal ediyordum. İlk yıllarda bölümün düşündüğüm gibi olmadığını anlayınca bir boşluğa düşmüş oldum. Ne yapabilirim diye düşünürken dördüncü sınıfta aldığım bir dersten sonra istediğim devrelerin çoğunu yazılımla yapabileceğimi farkettim. O andan itibaren tamamen yazılıma kaydım.
Zaman geçtikçe deneyler de ilgimi çekmeye başladı. İlginç bir şekilde okulda deneylere yatkındım ama tembeldim. Deney yapmayı okul hayatım bittikten sonra daha çok sevmeye başladım. Kimya, elektronik deneyleri için bodrumda laboratuvar bile kurdum.
Çok daha sonraları deneylere bilgisayarı da ekledim. Genelde veri toplama ve işleme için kullandım. Son zamanlarda simülasyonlar ve olasılık deneyleri için de programlar yazmaya başladım.
Bugün kumarbaz yanılgısını denemek istedim. Simülasyonda bir kumarbazımız var. Bu kumarbaz yazı tura oyunu oynuyor. Parayı attıktan sonra tahminde bulunuyor ve eski tahminleri de not alıyor. Merak ettiğim şey şuydu: Eğer kumarbaz kararını eski sonuçlara göre verirse rastgele bir karara göre nasıl bir ortalama tutturabilir? Daha iyi mi daha kötü mü?
Bunun için çeşitli stratejileri karşılaştırdım:
Kumarbaz daha önce gelen sonuçları not alır ve eğer daha fazla tura gelmişse yazı, daha fazla yazı gelmişse tura der. Eğer eşit sayıda yazı ve tura gelmişse rastgele karar verir. Bunun da değişik türleri olabilir. Örneğin toplamlar arasındaki fark belli bir sayıdan büyükse bu şekilde davranır, fark küçükse rastgele cevap verebilir.
Kumarbaz her yazı tura atışı için aynı cevabı verir. Hep yazı ya da hep tura.
Kumarbaz her yazı tura atışı için rastgele bir cevap verir (Örneğin başka bir parayla yazı tura atar ve onun sonucunu söyler).
Çok daha farklı stratejiler de bulunabilir elbette ama hedeflerim sadece basit durumları denemek ve kolayca deney tasarlayabileceğim bir sistem kurmak olduğundan burada bıraktım. Şimdi kısaca deneyden ve sonuçlarından bahsedeyim.
Deney programını R dilinde yazdım. Her deney adımında 10000 yazı tura atıldı ve stratejiler doğru tahmin sayılarına göre birbirleriyle karşılaştırıldı. Kazanan strateji o tur için bir puan aldı, diğerleri ise sıfır. Eşitlik durumunda eşit skor alan stratejiler birer puan aldı. 1000 deney sonucunda her stratejinin puanı listelendi.
Programın son hali bu ama ilk denememde sadece kumarbazın en basit stratejisiyle (daha fazla tura gelmişse yazı, daha fazla yazı gelmişse tura demek) rastgele karar verme stratejisini karşılaştırmıştım. Onun sonuçları ilk bakışta bir sürpriz olmuştu.
1000 deney sonucunda
Kumarbaz = 85
Rastgele = 916
Toplam 1000 deney yaptım ve kazanma toplamları 1000’den fazla olduğuna göre bir deneyde ikisi de eşit skor tutturmuş olmalı. Kumarbaz yanılgısı durumu bildiğim bir olaydı ama durumun ciddiyetinin bu derece olduğunu beklemiyordum. Bu arada küçük bir not da ekleyeyim, bu kavramı biliyordum dedim ama bunun hesaplarını daha önce hiç yapmadım. Bu deneylerin amacı da hesap yapmak değil sadece bu konu hakkında basitçe fikir sahibi olmaktı.
Sonra deneye bir de kumarbazın her zaman yazı dediği stratejiyi ekleyeyim dedim. Beklentim bu stratejini en az rastgele karar verme kadar iyi olması yönündeydi.
1000 deney sonucunda
Kumarbaz = 0
Rastgele = 504
Hep yazı= 502
Üç stratejinin yarıştığı durumda rastgele karar stratejisi kendisine gerçek bir rakip bulmuş gibiydi. Bu ortamda kumarbazın basit stratejisinin artık bir şansı yok gibi görünüyordu.
Sonra programda da yaptığım gibi bütün stratejilerin aynı anda yarıştığı bir deneme yaptım. Bu da sonuçları:
1000 deney sonucunda
Kumarbaz türevleri = 0
Rastgele = 271
Hep yazı = 385
Hep tura = 351
Görüldüğü gibi hep yazı ve hep tura oyunu eşit derecede domine etmeye başladılar. İkisinin de tek başına yaklaşık yüzde elli doğru tahminde bulunacağını beklemek normal bir durum. Diğer stratejiler bundan daha iyi skorlar elde edemeyecektir. Peki kumarbazın stratejisine yardım edilebilir mi? Eğer kumarbazın verdiği kararları biraz daha rastgeleleştirirsek daha iyi sonuçlar almasını beklemek çok da yanlış olmaz. Eğer hep rastgele karar verirse rastgele stratejiye yaklaşacaktır. O zaman rastgele karar verdiği aralığı (toplamlar arasındaki fark) büyüttüm ve bir iyileşme gördüm ama beklediğim hızda bir iyileşme olmadı bu.
1000 deney sonucunda
Kumarbaz (toplamlar arasındaki fark 50 ise rastgele) = 99
Rastgele = 223
Hep yazı = 351
Hep tura = 339
Bu kadar basit bir problem üzerine bu kadar çok deney tasarlanabilmesi hoşuma gitti. Bence deneyler de teoriler kadar önemli bir alan, bence deneyin sonucu teorinin sonucundan daha etkileyici ve şaşırtıcı.
Bir programlama dilini neden öğrenmek isterim? Bunun çeşitli cevapları var tabii ki. Örneğin çalıştığım projede kullanılan bir dil olabilir ve bu nedenle o dili öğrenmem gerekiyordur. İleride bu dil işime yarayabilir diye düşünüyor olabilirim. Aklımdaki projelere uygun araçlar olduğu için öğrenmek isteyebilirim. Belki de sadece yeni bir şey öğrenmek için.
Programlama dili öğrenmek için kullandığım üç temel yöntem var:
Programlama dilini bilgisayarıma kurup dil ile ilgili dökümanları ya da bir kitabı sırayla okuyup denemek.
İlgilendiğim bir alanda bir proje seçmek ve o projeyi öğrenmek istediğim dil ile programlamak.
Hackerrank gibi sitelerdeki soruları çözmek.
Birinci yöntemde vurgulamak istediğim nokta dökümanlar ya da kitaplar değil tabii ki. Bu kaynaklara her yöntemde ihtiyacım var. Yöntemlerdeki farklar öğrenme yolculuğunda kullandığım araçlar değil de daha çok bu sırada izlediğim rotalar.
İlk programlama dillerimi kitaplardan öğrendim. Üniversitede öğrendiğim dilleri de bu yöntem altında değerlendiriyorum. Kaynaklar yardımıyla bir dili öğrenmek ve bu bilgileri denemek o dilin inceliklerini öğrenmek için iyi bir yöntem olabilir. En azından bu şekilde büyük olasılıkla dili doğru kaynaklardan, dilin hangi fikirlere önem verdiğini de anlayarak doğru şekilde öğrenebiliriz.
Birkaç dil öğrendikten sonra bu yöntem bana verimsiz gelmeye başladı. Verimsizliği biraz açıklamam lazım tabii. Örneğin her dilde ilk kısımlar, değişkenler, döngüler, fonksiyonlar gibi aynı kavramlar üzerine oluyor. Bu kadar tekrar hoşuma gitmemeye başladı haliyle. Oraları hızla geçince de başka bir sorunla karşı karşıya kaldım. Kavramlar ne kadar aynı olsa da buralarda kullanılan isimler farklı olabiliyor. Bir dilin değişken dediğine diğeri değer ya da nesne diyebiliyor. İlerdeki konularda bu kavramlarla karşılaşınca nasıl olsa biliyorum bunları diye hızla geçtiğimde bir süre sonra bazı çelişkilerle karşılaştığım oldu. Çelişkilerin nedeni tabii ki o sıkıcı ilk üniteleri atladığımdan kavramların tanımlarının kafamdaki tanımlardan farklı olduğunu fark edememiştim.
Demek ki yeni bir dili kaynaklardan öğrenmek için de yine kaynaklardaki sırayı takip etmem gerekiyordu. Tabii ki her istasyonda aynı süre duraklamama gerek yoktu ama yol haritası hemen hemen tamamen benim kontrolüm dışındaydı.
Eğer bir dili o an çok iyi öğrenmeme gerek yoksa ama ilerisi için yatırım yapmak istiyorsam o zaman elimdeki bazı projeleri o dilde yapmayı deniyorum. Bu projeler kişisel, hobi projeleri olabildiği gibi şirket içinde de olabiliyor. Bu şekilde dili öğrenme yolculuğunu gerçek bir hikayenin üzerine oturtmuş oluyorum ve motivasyon açısından da faydalı oluyor ama profesyönel işlerde biraz dikkatli olmak gerekiyor. Örneğin yöneticilere ya da arkadaşlara o proje için neden o dili seçtiğimi açıklamam gerekebiliyor. Kişisel projelerde böyle bir sorun yok ama. İşin geri kalan kısmında yine kaynakları okumam gerekiyor ama bu sefer kendimi motive etmem daha kolay oluyor. Belli bir hedefim var ve yarım yamalak da olsa dil öğrenmenin getirisini hemen alıyorum.
Üçüncü yöntemi, hackerrank ve benzeri siteleri yeni yeni kullanmaya başladım. Bunu da daha çok bildiğim dilleri unutmamak ya da yeni özelliklerini deneyerek öğrenmek için yapıyorum. Bu şekilde bir dil gerçekten öğrenilemez sanırım ama boş zamanlarda kısa antrenmanlar için iyi olabilir.
Bu kullandığım yöntemlerin doğru kombinlendiği zaman iyi sonuçlar vereceğine inanıyorum. İlk diller bence birinci yöntemle daha iyi öğrenilebilir, çünkü hiçbir dil bilmeden bir projeyi, hobi projesi bile olsa yapmaya kalkmak bu sırada verilecek bir sürü yanlış karar yüzünden hem zorlaştırır hem de dile karşı yalancı bir güvensizlik yaratabilir. Bir dili ve program geliştirmeyi iyi öğrendikten sonra yeni dillerde ikinci yöntem daha iyi sonuç verebilir. Bu sırada hem bir projenin başarılı olmasına şahit olmanın heyecanı da öğrenmeyi destekleyici bir etki yapabilir. Son olarak da eski bilgileri unutmamak için üçüncü yöntem kullanılabilir.
Aklıma ilk gelen yöntem şu şekildeydi. İçinde kağıt olan kutuyu göstermek için birden fazla yazı tura dizilimi tanımlayabilirsem ve bunların her birine hangi konumdan olursa olsun tek bir yazı tura değişimiyle gelebilirsem o zaman soruyu çözmüş olurum. Dört kutu ve dört para var. Dört para için toplam 16 tane değişik yazı tura dizilimi var. Her bir kutu için dört tane dizilim kullanma şansım var yani. Peki bunları yukarıdaki varsayımıma uygun bir şekilde seçebilir miyim?
Öncelikle birinci kutu için seçeceğim ilk para diziliminin herhangi bir dizilim olabileceğini düşündüm. Diyelim ki YYYY (yazı – yazı – yazı – yazı) dizilimi birinci kutuda kağıt var anlamına gelsin. Bu durumda gardiyan kağıdı birince kutuya koyduktan sonra paraların durumu YYYY de olabilir. Yani bu dizilimden bir yazıyı tura yaptığım dizilimin de birinci kutu anlamına gelmesi lazım. Bu dizilimi de YYYT şeklinde seçeyim.
Şimdi YYYY ve YYYT dizilimlerine tek bir değişimle erişebilen dizilimleri bulmaya çalışayım.
Not: Burada dizilimlere ayrıca sayısal bir değer vereceğim ki, tabloların bütünlüğü daha kolay anlaşılsın. Dizilimlerin sayı değerini hesaplarken ikilik düzeni kullanacağım. Y için 0, T için 1 değerini kullanacağım ve dizinin onluk düzendeki değerini dizinin yanında parantez içinde göstereceğim.
Bu şekilde sekiz dizilim için ilk kutuyu gösterebileceğim iki dizilim bulmuş oldum. Kalan sekiz dizilim için de birinci kutuyu simgeleyen iki dizilim bulmam lazım şimdi. Aklıma ilk gelen fikir yukarıdaki tablonun tam tersini almak oldu. Yani T yerine Y ve Y yerine T olacak şekilde seçimlerimi yapabilirim belki. Bu şekilde yukarıdaki tabloda olmayan dizileri elde edeceğimi göstermem lazım. Bunun en kolay yolu tabii ki yeni tabloyu yazmak olacaktır.
Böylece birinci kutuyu simgeleyecek dört adet dizilim bulmuş oldum: YYYY, YYYT, TTTT, TTTY. Olası her dizilimden bu dizilimlere tek bir hareketle geçiş yapabiliyorum.
Şimdi ikinci kutu için bir seçim yapayım. Şimdiye kadar seçtiğim dört dizilim dışındaki herhangi bir dizilim başlangıç için işe yarayacaktır. Örneğin YYTY dizisini alayım. Şimdi yine yukarıdaki mantığı yürüterek başlangıçta bu dizilimin oluşabileceğini varsayıp tek bir değişimle elde edebileceğim ve daha önce seçilmemiş başka bir dizilim seçeyim. O da YYTT olsun. Yine yukarıdaki gibi bu iki dizilime tek bir değişimle ulaşılabilen dizilimleri yazayım.
Böylece ikinci kutuyu kodlamak için şu dizilimleri bulmuş oldum: YYTY, YYTT, TTYT ve TTYY.
Bu yöntem madem şimdilik çalışıyor gibi gözüküyor, o zaman devam edeyim. Üçüncü kutuyu kodlama için bu sefer YTYY dizilimiyle başlayayım. Yukarıdaki yöntemleri tekrarlayacağım. Başlangıç dizisi YTYY olabileceğine göre tek değişiklikle ulaşabileceğim ama daha önceki kutular için seçmediğim bir dizilim seçeyim. Örneğin, YTYT. Tekrar bu dizilimlere her dizilimden tek bir değişiklikle geçebilir miyim kontrolünü yapayım.
Algoritma olarak her bir kutuyu kodlamak için yaptığım adımlar şöyle oldu: Daha önce seçilmemiş bir dizilim aldım. Sonra bu dizilime bir değişiklik uzakta başka bir dizilim aldım ve sekiz değişik dizilimin bu iki dizilime bir değişiklik uzakta olduğunu gösterdim. Kalan diğer iki dizilimi de bu seçtiğim iki dizilimin tersi olarak seçtim ve bu dizilimlerin de diğer sekiz dizilime birer değişiklik uzaklıkta olduğunu gösterdim.
Şimdi aklıma takılan bazı sorulara bakayım:
Her adımda seçtiğim ilk iki dizilim her zaman sekiz değişik dizilimden bir değişiklik uzakta mı? Birbirine bir değişiklik mesafede iki dizilimin bir basamakları farkllı ve diğer üç basamakları aynı olmak zorundadır. Seçtiğim iki dizilimin arasındaki mesafe bir değişiklik olduğundan ikisi de bu iki dizilime bir değişiklik mesafede olan dizilimler arasında olacak ve birbirlerinden farklıdırlar. Kalan üçer basamak için de ya elimdeki sayılara (ikisine de) o basamak değeri kadar ek yapacağım (eğer basamak değeri sıfır ise) ya da sayının değerinden o basamak değeri kadar çıkaracağım. İki durumda da oluşan sayılar elimdeki sayılardan ve birbirlerinden farklı olacaklar. Basamakların değerleri de 1, 2, 4 ya da 8 olduğundan değişik basamakların değerlerini (sadece bir basamağın) ekleyerek ya da çıkararak eşit sayılar elde edemeyiz.
Dizilimlerin tersini aldığımda (yani yazı yerine tura, tura yerine yazı koyunca) önceki sekiz dizilimle bir çakışma olabilir mi? Dizilimlerin onluk düzendeki değerlerine bakarsak bir dizilimin değeriyle o dizilimin tersinin değerini topladığımızda her zaman 15 sayısına ulaşıyoruz. Çakışma olabilmesi için sekizlik grupta toplamları 15 olan iki dizilimin olması gerekir. Şöyle bir mantık yürüteyim. Birbirine mesafesi bir olan iki dizilimden herhangi birine mesafesi bir değişim olan iki rastgele dizilim arasındaki mesafe en fazla üç olabilir olabilir. Dizilimlerin birine A diyelim ve bu seçtiğim ilk dizilime bir değişim mesafede olsun. Diğer B dizilimi de ikinci dizilime bir değişim mesafede olsun. O zaman A diziliminden B dizilimine önce bir seçtiğim iki dizilim üzerinden en fazla üç dizilimle gidebilirim. Şimdi toplamları 15 değerini veren dizilimlere bakayım.
Tablodan da görüldüğü gibi toplamın 15 olabilmesi için seçtiğim iki dizilimin ürettiği sekiz dizilimdeki iki dizilim arasındaki mesafenin dört olması lazım ama bu mesafe en fazla üç olabiliyor. Demek ki toplamı 15 eden iki dizilim bu sekiz dizilim arasında yok. O zaman tersleri ile aralarında bir çakışma da olamaz. Yani kullandığım yöntem gerçekten de işe yarıyor gibi gözüküyor.
Not: Literatürde bu dizilimler arasındaki mesafeye (birinden diğerine geçişte gereken değişiklik sayısına) Hamming mesafesi deniyor.
Lisedeki ya da üniversitedeki matematik derslerini hatırlıyorum da, her zaman ilk önce tanımlar ve kurallar verilirdi, ardından da bunlar kullanılarak bir şeyler inşa edilirdi. O zamanlarda çok kafaya takmıyordum bu sırayı. Sağlam bir temelle ilerlemek için bunun iyi bir yöntem olduğunu düşünüyordum. Daha fazla değil. Bu yöntemin belli alanlarda çok iyi iş gördüğünü kabul ediyorum. Bazılarında ise sanki insanın psikolojisine ters işleyen bir etki yapıyordu. Özellikle oldukça soyut alanlarda. Ne işe yaradığını ve yarayacağını çözemediğimiz tanımlar ve kurallarla bir yolculuğa çıkmak bence birçok öğrenciyi tedirgin ediyordur. Bu tedirginlik açısından bakınca bu yöntemin hedefinin sağlam temeller üzerinde ilerlemek olup olmadığını tekrar sorgulamaya başladım. Şimdiden söyleyeyim bir cevap bulamadım.
Matematik öyle okuyarak öğrenilebilen bir şey değil. Okuyarak öğrenilebilen bir şey var mı diye sorarsanız onu da bilmiyorum. Okuyarak bir şeyler ezberlenilebilir, hatırlanabilir ama öğrenilir mi bilemiyorum. Neyse işte, matematik de öyle. Kağıt kalem alıp bu yollardan geçmeden öğrenilemiyor. O zaman elime kağıt kalem aldım tanımları ve kuralları kullanmaya başladım. Bir çocuk gibi. Önce çok basit yapılarla başladım. Bu yapıları bulmak kolay, çünkü hemen hemen her kitapta bunlar örnek olarak var. Bu yapılarla oynarken aklıma bazı sorular da geldi tabii ki. İlk başta bunları deneme yanılma yöntemiyle anlamaya çalıştım. Bazen bir sorunun cevabı bir yapıda evet olurken, başka bir yapıda hayır oldu. O zaman yapıların arasındaki farkları da görmeye çalıştım. Tabii ilk başta pat diye bu farkı görmek kolay değil. Bunun yerine benzer büyüklükte başka yapılarla ya da aynı yapıların biraz daha büyük halleriyle de denemeler yaptım. Bazen sorumun cevabı olabilecek fikirleri görebildim, bazen göremedim. Eğer olası bir açıklama bulduğumu düşündüysem o zaman bu cevabı ispatlamaya çalıştım. Onu da her zaman başaramadım ama amatör olarak izlediğim yol bu oldu. Bu çok zaman isteyen ama bu şekilde anlatılan bir alan için aklıma ilk gelen öğrenme yöntemlerinden biriydi. Arada çok takıldığım bir yer olursa sorup öğrenebileceğim bir sürü kaynağa da sahip olmam ve üzerimde hiçbir zaman baskısının olmaması sayesinde de başka bir yöntem aramam gerekmedi henüz. Bu yöntemin beni pek memnun etmeyen bir yanı da bu kendi aramalarım sırasında bu tanımlara ve kurallara bir anlam vermek benim için hala çok zor bir uğraş olmasıydı. Anlamlar uzun süre yerine oturmadı ve birçoğunda da uzmanlardan yardım almam gerekti.
Bu arada aklıma ilk gelen sorulardan biri de, matematikçilerin bu tanımlara ve kurallara en baştan nasıl ulaşabildiğiydi ama tabii ki gerçekler düşündüğümden çok daha kolay ve mantıklı bir olaylar zinciriydi. Genelde bir konuda bir problemi çözmeye çalışırken denedikleri tekniklerin çok uzun zaman sonraki düzenleme çalışmalarının ürünü oluyordu bu tanımlar ve kurallar. Bu süreçler bana biraz bilgisayar programı yazmayı andırdı. Orada da önce elimizdeki problemi çözen bir programı elde edip sonra onu daha anlaşılır ve düzenli bir hale getirmeye çalışıyoruz ama sanki matematikteki tanımlar daha kavramsal şeyler ve kurallar da aslında zamanla keşfedilen şeyler. Programlamada ise çoğunlukla çözümü önceden bilinen şeyleri programlarız ve bu alanlardaki kurallarla tanımlar bize önceden verilir. Bu durumda bizim düzenlemede yaptığımız şeyleri ise problemin çözümüne yardımcı olan, problemin bileşenleri arasındaki ilişkileri daha anlaşılır hale getiren kavramsal olmayan, daha küçük kurallar ve tanımlar olarak düşünebiliriz.
Öğrenmek için tarihsel yöntem de kullanılabilir belki ama bu sırada da öğrencilerin dikkatleri çok kolay dağılabilir diye korkuyorum. Bir taraftan gerçek bir problem üzerinde çalışıp çıkan sonuçları tanımlara ve kurallara dökmek öğrencilere matematiğin doğal işleyişini daha iyi anlatabilir belki ama diğer taraftansa işlenen problemler doğru seçilmezse dikkatleri toplamak ciddi bir sorun olabilir.
Ümit bu sene üniversiteye başladı ve büyük bir şokla karşılaştı. Lisede kullandığı ve çok alıştığı öğrenme yöntemi artık hiçbir işe yaramıyordu. Hem konuların bir kısmı ona çok soyut geliyordu, hem de nasıl çalışacağı ya da öğrenebileceği konusunda hiçbir fikri yoktu. Ona uygulamalı olarak kendi kullandığım yöntemi anlattım. Arada matematiğin tarihsel gelişiminden de bilfiğim kadar bahsettim. Sonuçta bütün bunlar için zamanının yeterli olmayacağını anladı ama en azından biraz rahatlayıp ona göre plan yapmaya başladı. Bölümü tamamen bırakmak yerine bazı konuları feda etmeye ya da ikinci plana bırakmaya razı oldu ve en azından morali ve motivasyonu artık daha iyi. Keşke her öğrenciye, kendisine uygun öğrenme yöntemiyle çalışabilecek bir öğretmen verilebilse.
Tensional Integrity’nin kısaltması anladığım kadarıyla. Aralarında kablo gibi şeylerin gerilimiyle birbirine temas etmeyecek şekilde tutulan parçalardan oluşan yapılar. Sanırım twitter’da görmüştüm bu fikri ilk olarak ve youtube’da bulduğum şu videodan yararlanarak aşağıdaki modeli yaptım.
Parçaları tam dengeye getirmeyi videodaki kadar kolay yapamadım ama oluyor. Benim yaptığım model şöyle gözüküyor.
Ali ile Veli tutukludur. Bir gün gardiyan gelir ve bir oyun oynayacaklarını, eğer kazanırlarsa serbest bırakılacaklarını söyler. Oyunun kuralları şöyle:
Gardiyan sabah gelip Ali’yi bir odaya götürecek. Veli başka bir odada bekleyecek. Ali’nin getirildiği odada birden dörde kadar numaralanmış dört adet boş kutu olacak. Ali bu kutuları görürken gardiyan bir kutuya cebinden çıkardığı bir kağıdı koyacak. Ali kağıdın hangi kutuya koyulduğunu bilecek yani. Sonra gardiyan cebinden dört adet hilesiz madeni para çıkaracak ve sırayla yazı tura atıp her bir parayı birer kutunun üzerine koyacak. Ali hangi paranın yazı ya da tura geldiğini ve hangisinin hangi kutu üzerinde olduğunu da bilecek. Sonra gardiyan Ali’ye bir parayı seçmesini söyleyecek. Alinin seçtiği para yazı ise turaya, tura ise de yazıya döndürülecek ve Ali odadan çıkarılacak.
Ardından Veli odaya alınacak. Veli kutuların içini göremeyecek ama üzerindeki paraların durumunu görecek. Veli odaya girdikten sonra bir kutuyu seçecek. Eğer doğru kutuyu seçerse ikisi de serbest bırakılacak, bulamazsa tutukluluk devam edecek.
Ali kutuların olduğu odaya girdikten sonra Veli ile aralarında paralar dışında başka hiçbir iletişim olmayacak. Bütün bu bilgiler doğrultusunda Ali ve Veli oyun başlamadan önce beraberce bir strateji belirleyebilecekler. Serbest kalmalarını garantileyecek strateji nasıl olmalıdır?
Martin Nowak evolutionary dynamics kitabında üremeyi şöyle basitçe modeller:
\(\dot{x} = \frac{dx}{dt} = r\cdot x \)
Burada \(x \) değişkeni türün nüfusunu belirtiyor. Dolayısıyla \(\dot{x} \) terimi de türün nüfusunun zamana göre değişimini gösteriyor, yani zaman geçtikçe nüfusunun ne kadar arttığını ya da azaldığını ifade ediyor. Bu artış ya da azalış da o anki nüfusun sabit bir \(r \) sayısıyla çarpımına eşit olduğu bir modelle gösterilsin diyor. Bu arada doğum ve ölüm oranlarının çoğalma katsayısında olduğunu da unutmamak lazım. Yani aradaki fark çoğalmayı veriyor ve bu fark aslında nüfusun azalması da demek olabilir.
Bu şekildeki bir modelde nüfus artışı tabii ki üssel bir davranış gösterecektir.
\(r = 1.1 \) değeri için yukarıdaki grafiği elde ettim. Toplamda yirmi adım bile gidilmeden nüfus bir milyonu geçti. Böyle bir ortamda bütün türler aynı hızda çoğalırdı ama. Nowak hemen sonra gelen seçilim kısmının başında “seçilim değişik türlerin bireyli değişik oranlarda çoğalırsa meydana gelir” diyor. Eğer her tür aynı oranda çoğalsaydı nüfuslarını birbirlerinden ayıran tek fark başlangıçtaki nüfusları olacaktı. Diğer bir deyişle nüfusların başlangıçtaki oranları nesiller geçtikçe hiç değişmeyecekti. Bu durumda gerçekten de bir seçilimden bahsetmek zor olabilir.
İkinci cümlede ise seçilim olması için en az iki tür olmalıdır diyor. Bu da seçimden bahsedilebilmesi için anlaşılır bir varsayım hatta tanım bile olabilir.
O zaman iki türden oluşan modeli şöyle veriyor:
\(\dot{x} = a\cdot {x}\)
\(\dot{y} = b\cdot {y}\)
Burada \(a > b \) ise birinci tür ikinci türden çok daha hızlı üreyecektir ve zaman geçtikçe birinci türün nüfusunun ikinci türün nüfusuna oranı sürekli artacaktır. \(b > a \) olduğu durumda da tersi senaryo gözlenecektir.
Tabii ki her türün sınırsız büyüdüğü modeller pek gerçekçi değil. Ekosistemimizin maksimum birey sayısına sahip olduğunu varsayalım ve modelimizi buna uygun hale getirelim. Bu modelde toplam bir sayıdan bahsetmek yerine nüfus oranları kullanılacak. Yine aynı değişkenleri kullanıyoruz ama artık \(x \) değişkeni birinci türün nüfusunu değil de birinci türün nüfusunun toplam birey sayısına oranını veriyor. Bu oranlar haliyle minimum 0 ve maksimum 1 değerine sahip olabilirler.
Kitapta bunun için şu model veriliyor:
\(\dot{x} = a\cdot {(x-\phi)}\)
\(\dot{y} = b\cdot {(y- \phi)}\)
Buradaki \(\phi \) teriminin görevi türlerin nüfuslarının oranlarının toplamını 1 değerinde sabit tutmak. Bunu sağlamak için de
\(\phi = a\cdot {x} + b\cdot{y} \)
eşitliğinin sağlanması gerekiyor. Yani her adımda \(\phi \) değeri o adımdaki nüfusların oranına göre tekrar hesaplanıyor.
Aşağıdaki python programıyla bu modeli denedim.
import numpy as np
import matplotlib.pyplot as plt
a = 1.1
b = 1.3
number_of_iterations = 100
def constrainedA(x, phi) :
return x*(a - phi)
def constrainedB(y, phi) :
return y*(b - phi)
def phi(x, y):
return a*x + b*y;
x = 0.5
y = 0.5
x_population = np.array([[0, x]])
y_population = np.array([[0, y]])
total = np.array([[0, x+y]])
for i in range(0, number_of_iterations):
phi_value = phi(x, y)
delta_x = constrainedA(x, phi_value)
delta_y = constrainedB(y, phi_value)
x += delta_x
y += delta_y
x_population = np.append(x_population, np.array([[i, x]]), axis = 0)
y_population = np.append(y_population, np.array([[i, y]]), axis = 0)
total = np.append(total, np.array([[i, x+y]]), axis = 0)
plt.plot(x_population[:, 0], x_population[:, 1])
plt.plot(y_population[:, 0], y_population[:, 1])
plt.plot(total[:, 0], total[:, 1])
plt.xlabel("zaman")
plt.ylabel("nüfus")
#plt.plot(y_population[:, 0], y_population[:, 1])
plt.show()
Sonuç olarak da şu grafiği elde ettim:
Bu programda adım sayısını 20’den 100’e yükselttim. Bu sayede türlerin birinin diğerini ekosistemden nasıl sildiğini görebiliyoruz. Kırmızı çizgiyle gösterilen türün çoğalma katsayısı 1.3, mavi çizgiyle gösterilen türünkü ise 1.1 idi. Yeşi çizgi de nüfus oranlarının toplamını gösteriyor ve sürekli 1 değerine sahip.
Martin Nowak bu modeli daha iyinin hayatta kalmasına (Survival of the fitter) örnek olarak veriyor. Gerçekten de bu modelde daha iyi çoğalma yeteneğine kalan tür hayatta kalıyor ve diğeri yok oluyor. Sonra aynı modeli ikiden fazla tür için kurup bu sefer de en iyinin hayatta kalması (Survival of the fittest) fikrini gösteriyor. Bu modelde iki genellemeye gidiyor:
\(\phi = \sum_{i=1}^{n} x_{i} \cdot {f_{i}} \)
\(\dot{x_{i}} = x_{i} \cdot (f_{i} – \phi) \)
Bu modelde \(x_{i}\) i numaralı türün nüfus oranını \(f_{i}\) de aynı türün çoğalma fonksiyonunu (fitness) gösteriyor. Modelin gerisi aynı şekilde çalıştırılıyor.
Bu noktadan sonra Nowak iki yeni durum için modelimiz nasıl olmalı diye bir soru soruyor:
Ekosistemdeki ilk mevcut tür daha sonradan gelen tür ne kadar iyi olursa olsun mücadeleyi kazansın (Survival of the first)
Ekosistemdeki her tür hayatta kalsın (Survival of all)
Bu durumda Nowak doğrusal fitness fonksiyonu şartından vazgeçmemiz gerekir diyor ve şu modeli sunuyor:
\(\dot{x} = a\cdot {x^c}-\phi \cdot {x}\)
\(\dot{y} = b\cdot {y^c}- \phi \cdot {y}\)
Bu modelde nüfus oranlarının toplamını sabitlemek için şu eşitliğe ihtiyacımız var:
\(\phi = a\cdot{x^c} + b\cdot {y^c} \)
Modeldeki \(c \) sabitinin birden büyük seçersek 1. olasılığı modellemiş oluyoruz. 1. senaryonun aklıma takılan kısmı bunu nasıl programlayacağımdı. Bu senaryoda söylenen şey şu: Mesela bütün toplam nüfus sadece \(x \) türünden oluşuyorsa sisteme ekleyeceğimiz bir \(y \) türü bireyi çoğalma potansiyeli diğer türden yüksek olsa bile yok olmaya mahkumdur. Yani programda ilk anda \(x = 1 \) ile başlamam gerekecek. Ardından sisteme minimum bir \(y \) değeri eklemem lazım. Bunun yerine başlangıçta minimum \(y \) ile başlamayı seçtim.
import numpy as np
import matplotlib.pyplot as plt
a = 1.1
b = 2.0
c = 1.3
number_of_iterations = 20
def constrainedA(x, phi) :
return a*pow(x, c) - x*phi
def constrainedB(y, phi) :
return b*pow(y, c) - y*phi
def phi(x, y):
return a*pow(x, c) + b*pow(y, c);
x = 0.999
y = 0.001
x_population = np.array([[0, x]])
y_population = np.array([[0, y]])
for i in range(0, number_of_iterations):
phi_value = phi(x, y)
delta_x = constrainedA(x, phi_value)
delta_y = constrainedB(y, phi_value)
x += delta_x
y += delta_y
x_population = np.append(x_population, np.array([[i, x]]), axis = 0)
y_population = np.append(y_population, np.array([[i, y]]), axis = 0)
plt.plot(x_population[:, 0], x_population[:, 1])
plt.plot(y_population[:, 0], y_population[:, 1])
plt.show()
Bu sefer programda toplam nüfus oranlarını göstermek istemedim, çünkü o zaman birinci türün çok çabuk 1 değerine ulaşması net gözükmüyordu.
Grafikte çok net görülmüyor ama daha ilk adımda birinci tür bütün popülasyonu ele geçirdi.
Bu senaryo tabii ki her başlangıç değeri için bu sonucu vermiyor. Örneğin aynı \(c \) sabiti için \(x \) türünü nüfusun yüzde sekseni olacak şekilde başlatınca bu sonuç çıkıyor.
Görüldüğü gibi daha iyi fitness fonksiyonuna sahip olan \(y \) yok olmadığı gibi bütün ekosistemi de ele geçirdi.
Eğer \(c < 1 \) olacak şekilde bir seçim yaparsak iki tür de yok olmadan beraber yaşama şansını yakalayabiliyor.
Bunun denemesini de aşağıdaki programla yaptım.
import numpy as np
import matplotlib.pyplot as plt
a = 1.2
b = 0.8
c = 0.5
number_of_iterations = 20
def constrainedA(x, phi) :
return a*pow(x, c) - x*phi
def constrainedB(y, phi) :
return b*pow(y, c) - y*phi
def phi(x, y):
return a*pow(x, c) + b*pow(y, c);
x = 0.5
y = 0.5
x_population = np.array([[0, x]])
y_population = np.array([[0, y]])
for i in range(0, number_of_iterations):
phi_value = phi(x, y)
delta_x = constrainedA(x, phi_value)
delta_y = constrainedB(y, phi_value)
x += delta_x
y += delta_y
x_population = np.append(x_population, np.array([[i, x]]), axis = 0)
y_population = np.append(y_population, np.array([[i, y]]), axis = 0)
plt.plot(x_population[:, 0], x_population[:, 1], label='x')
plt.plot(y_population[:, 0], y_population[:, 1], label='y')
plt.legend()
plt.show()
Grafikte de görüldüğü gibi iki tür de yok olmadı.
Heralde bu özellikleri sağlayan daha başka modeller de vardır ama konuya bu şekilde girilmesi hoşuma gitti. Bir modelin olası sonuçlarından çok, istenen sonucu açıklayabilecek bir model sunma tekniği ilgimi çekti. Çalışmalarıma biraz da bu kitaptan devam edeyim, belki şansım bu sefer döner.