İster Facebook’un kendi dilini geliştiren yapay zekası olsun, ister Google’ın yıllardır alay edilen yapay zeka çeviricisi olsun, tüm yapay zekalar aslında bir bilgisayar programından ibarettir ve benzer şekillerde çalışırlar. Yapay zekaları, ağının üzerinde dolaşan bir örümcek olarak hayal edebilirsiniz. Örümceğimiz ağdaki kesişim noktalarının arasında ilerleyip kesişim noktalarında yazan işlemleri gerçekleştirir. Bunu farklı şekillerde yapabileceği gibi, programcı ağı farklı şekillerde de kurabilir. Bunların hepsini inceleyeceğiz ama önce bu ağın ne olduğuna bakalım.
Graf Nedir?
Yukarıdaki takım yıldıza benzeyen şekil bir graftır (çizge). Graflar düğümler (vertex) ve düğümleri bağlayan kenarlardan (edge) oluşan yapılardır. Grafların bilgisayar bilimlerinin matematikteki gösterimi olduğu söylenebilir. Örümceğimiz (yapay zeka) düğümlerdeki komutları uygulayarak bağlı düğümler arasında gezer. Graflar günlük yaşamdaki pek çok şeyin gösterimi ve bilgisayara işlenmesi için kullanılabilir. İnternet ağı, metro sistemi, elektrik hatları bunların yalnızca birkaçıdır. İlk bakışta basit bir konu gibi görünüyor olabilir ama yazının devamında fark edileceği üzere graflar matematiğin en karmaşık ve derin alanlarından biridir.
Grafların yönlü-yönsüz, ağırlıklı-ağırlıksız gibi türleri de vardır ancak şu anda bunlardan bahsetmemize gerek yok. Ayrıca graflarla ilgili gerekli diğer detaylardan yazının devamında bahsedeceğiz. Artık söz konusu ağın ne olduğunu anladığımıza göre programcının bu ağı nasıl kurduğuna bakabiliriz.
Algoritma Nedir?
Algoritma en basit ifadeyle bir işin nasıl yapıldığı anlamına gelir ve programcılığın temelini oluşturur. Yazdığınız programı bilgisayarın anlayacağı dile çevirmek genellikle işin kolay kısmıdır. Zor olan programın algoritmasını, yani örümceğimizin dolaştığı ağı hazırlamaktır. Bu ağ pek çok farklı şekilde hazırlanabilir. Örneğin bir kişinin yüzünü tarayarak kadın mı erkek mi olduğunu anlayan bir yapay zeka yazıyor olalım. Bunu iki yöntemle yapabiliriz:
1. Dünyadaki tüm insanların yüzlerini ve cinsiyetlerini kaydederiz. Bu yöntem programcı açısından oldukça zordur ama bu bir zayıflık değildir. Algoritmayı analiz ederken programcı açısından değil bilgisayar açısından düşünürüz. Bu algoritmanın zayıflığı zaman ve alan karmaşıklıklarının çok yüksek olmasıdır. Yani program, en kötü durumda (worst case) karşısındakinin yüzünü, tüm insanların yüzleriyle karşılaştırırken çok zaman, tüm insanların yüzlerini hafızasında tutarken ise çok yer harcayacaktır.
2. Kadın ve erkek yüzlerinin belirgin özelliklerini kaydedip programın bunları karşısındakinin yüzüyle karşılaştırmasını sağlarız. Bu yöntemle hem hafızadan hem de zamandan tasarruf ederiz.
İlk yönteme kaba kuvvet (brute force) denir ve programcılıkta tercih edilmez. Buna rağmen iki program da karşılaştırmalar yaparak sonuca ulaştığı için yapay zeka olarak kabul edilir. Yapay zekalar, farklı durumlar arasında gereken duruma ulaşmak için arama algoritmalarını, karşılaştırma yapabilmek için ise sıralama algoritmalarını kullanılır. Bu iki algoritma türü yapay zeka çalışmalarının temelinde yer alır.
Arama Algoritması Nedir?
Arama algoritmaları bir noktadan diğerine giden yolu bulmaya yarayan algoritmalardır. Durumları bir grafta gösterdiğimiz zaman yapay zekanın bir durumdan diğerine ulaşmak için arama yapması gerekir. Eğer iki nokka arasında birden çok yol varsa bazı algoritmalarla en kısa yolu, bazı algoritmalarla ise herhangi bir yolu bulursunuz. Yapay zekalar genelde A* gibi daha karmaşık algoritmalar kullanır. Ama biz BFS ve DFS gibi basit örnekleri inceleyeceğiz.
BFS ile başlayalım. Breadth-first search yani genişlik öncelikli arama algoritması graftaki iki nokta arasındaki en kısa yolu bulmayı sağlar. BFS her grafta çalışabilmesine rağmen, DFS’ten yani derinlik öncelikli aramadan farkının daha kolay anlaşılabilmesi için ağaç (tree) adı verilen özel bir grafta örnekleyeceğiz.
Ağaçlar içerisinde döngü (cycle) bulundurmayan graflardır. Yani ağaçlarda diğer grafların aksine bir düğümden başlayıp aynı kenardan iki defa geçmeden aynı düğüme ulaşamazsınız. Aşağıdaki şekilde bir ağaçta BFS uygularken yaptığımız işlemler adım adım görülüyor. En yukarıdaki düğümden başlayarak mavi ile işaretlenmiş düğüme giden yolu arıyoruz. Bunun için bulunduğumuz düğümün ziyaret edilmemiş tüm komşularını sırayla ziyaret ediyoruz ve ziyaret ettiğimiz düğümleri sarıya boyuyoruz. Şekilde o adımda bulunduğumuz düğüm turuncu ile gösterilmiştir.
Fark edebileceğiniz üzere genişlik öncelikli arama yapılırken katmanlar halinde ilerlenir. Ancak ağacı, yolların dallandığı bir labirent olarak düşünürsek BFS işe yaramaz. Çünkü bir labirentte duvarların içinden geçemezsiniz. Bu yüzden çok mesafe kat ederek en kısa yolu bulan BFS’e alternatif olarak az mesafe kat ederek herhangi bir yolu bulan DFS geliştirilmiştir.
Depth-first search yani derinlik öncelikli arama yapılırken yolun sonuna kadar gidilir. Aranan düğüm bulunamazsa geri dönülüp başka bir yola gidilir. Örnek vermek gerekirse Labirentin çıkışını araken DFS, İzmir’den Manisa’ya giden yolu ararken BFS kullanırız. İzmir’den Manisa’ya giden yolu DFS ile bulmaya çalışırsak önce ilk denediğimiz yolun sonuna kadar (örneğin sınırlara veya Karadeniz’e) gitmemiz sonra İzmir’e dönüp başka bir yol denememiz gerekir. Graf üzerinde DFS şekildeki gibi uygulanır.
Sıralama Algoritması Nedir?
Sıralama aslında oldukça basit bir problemdir. Bir dizideki sayıları en az işlemle sıralamak için pek çok algoritma geliştirilmiştir. Bunlar arasında en gelişmişi yani zaman karmaşıklığı en düşük olanı quick sort (hızlı sıralama), kodlaması en basit olanı ve yazılımcılar tarafından en çok bilineni ise buble sort(baloncuk sıralaması)’tur. Sıralama algoritmalarının sayısı o kadar fazladır ki bogo sort (rastgele sıralama) isminde bir algoritma bile vardır. Programlamacıların tuhaf mizah anlayışının bir ürünü olan bogo sort algoritması, her adımda sayıları rastgele olarak sıralayıp sıralı bir dizi elde edip etmediğini kontrol eder.
Sıralama algoritmalarına en uygun örnek olan buble sortun nasıl çalıştığına bakalım. Bubble sort yapmak için sırayla dizideki komşu elemanları karşılaştırıp ilk sayı ikinciden büyükse ikisini yer değiştiririz. Dizinin sonuna geldiğimizde dizi sıralanmış olmazsa başa dönüp aynı işlemi tekrarlarız. Böylece n sayılık bir diziyi en fazla n*n işlemde sıralayabiliriz. 1,8,4,2 dizisi için algoritmayı adım adım uygulayalım.
1 8 4 2
1 4 8 2
1 4 2 8 -> dizi henüz sıralanmamış olduğu için başa dönüyoruz.
1 4 2 8
1 2 4 8
1 2 4 8 ->dizi sıralandı.
En kötü durumda, yani bize verilen dizinin büyükten küçüğe sıralı olması durumunda 4*4 yani 16 işlem yapmamız gerekirdi. En kötü durumda yapılan işlem sayısını küçük optimizasyonlarla azaltmak da mümkündür.
Yapay zeka çok geniş bir konu olduğu için bu yazının ancak yapay zekaya girişin özeti sayılabileceğini ve amacının okuyucuya yapay zekanın çalışmasıyla ilgili bir fikir vermek olduğunu unutmayın. Konuyu kısaca özetlemek gerekirse, yapay zekalar çeşitli durumlar arasında ilerleyip işlem yapmak için arama ve sıralama algoritmaları kullanırlar. Bu algoritmalar çok çeşitlidir ve farklı şekillerde çalışabilirler. Yapay zekayla ilgili çalışmalar yapmak isteyen bir insan algoritma ve graf konularına hakim olmalıdır.