MIT Açık Ders malzemeleri

http://ocw.mit.edu

 

6.046J Algoritmalara Giriş, Güz 2005

 

Bu materyallerden alıntı yapmak veya kullanım şartları hakkında bilgi almak için:

 

 Erik Demaine ve Charles Leiserson, 6.046J Introduction to Algorithms, Fall 2005. (Massachusetts Institute of Technology: MIT OpenCourseWare). http://ocw.mit.edu (Giriş Tarihi:  08, 01, 2010).                                   Lisans: Creative Commons Attribution-Noncommercial-Share Alike.

Not: Lütfen atıf taparken bilgilere eriştiğiniz gerçek tarihi kullanınız.

Atıflar ve Kullanım Koşulları konusunda daha fazla bilgi için:

 http://ocw.mit.edu/terms ve http://www.acikders.org.tr sitesini ziyaret ediniz.

DERS 16

 

Bugün, açgözlü algoritmalar, “greedy algorithms” olarak adlandırılan özel bir grup algoritma ile ilgili konuşacağız. Ancak bunu grafikler kullanarak yapacağız. Bu nedenle, kitabınızın EK B’sinde bulabileceğiniz grafiklerle ilgili bölümü kısaca hatırlatmak istiyorum. Eğer EK B’yi henüz  gözden geçirmediyseniz, şimdi tam zamanı. Ayrıca evde çözeceğiniz sınavınız için de bu oldukça önemli. Size, Digraf’ı hatırlatmak amacıyla, pekiyi, Digraf nedir? Neyin kısaltmasıdır? Directed Graph yani Yöneltilmiş Grafiğin kısaltmasıdır; G eşittir (V,E). V köşeler kümesi, --- E de kenar kümesi. İngilizcede “Vertex” tekil “Vertices” onun çoğulu.  İngilizcenin bir acayipliği. Belki de Fransızcadan gelme.

E kümesi, V çarpı V’lerin alt kümesi, yani kenarlardan oluşur. Bu bir digraftır. Yönlendirilmemiş grafik ise, sırasız bütün kenar çiftlerini barındıran bir E kümesine sahiptir.

Pekiyi, yönlendirilmiş veya yönlendirilmemiş grafiklerde, kenar sayısının büyük- O’su nedir? O( ), güzel. Grafiklerle uğraştığımız müddetçe, kümelerle oldukça haşır neşir olacağız. Genel olarak, büyük O’ların içinde düşey çizgi simgelemini kullanmayız, çünkü bu zaten anlaşılır. Kullanmak işi sadece karmaşıklaştırır. Aslında bu biraz üstünkörü bir simgelem; olması gereken “V karenin boyutunun düzeyi “ şeklinde bir anlatımdır. Ama bu yazılacakları oldukça karmaşıklaştırır; bütün bunları çarpıyoruz ve bütün bu dikey barlar bu bağlamda anlatımı zorlaştırır. Bu asimptotik bir simgelem olduğu sürece dikey barları kullanmayacağız.

E kümesi,  seviyesindedir, çünkü bu ikililerden oluşan bir kümedir ve eğer böyleyse n elemanlı bir küme en fazla n’in 2li kombinasyonu boyutunu alacağından, bu da en fazla  olabilir. Burada G‘nin bağlantılı (connected) olması başka bir özellik olarak karşımıza çıkıyor; bu E kümesinin V’nin büyüklüğü eksi -1 ‘den büyük olduğunu işaret ediyor. Pekiyi, bir grafiğin yani G’nin bağlantılı olması ne anlama gelir?

Bunun anlamı, bir köşeden, başka bir köşeye bir yol var demektir. Bu G’nin bağlantılı olduğunu ifade eder. Durum bu ise, kenar sayımız en az köşe sayımız eksi birdir. Bu durumda, size bir şeyi hatırlatmak isterim, eğer log E’ye bakarsam, yani kenarlar sayısının log’una bakarsam, buna göre büyük-O (log V)’dir.

Buna göre de, Omega (log V)’dir. Bu da teta (logV)’ye eşittir. Dolayısıyla, temel olarak, bağlantılı grafikte, kenar sayısı köşe sayısıyla polinomsal olarak bağlantılıdır; böylece, log’ları da kıyaslanabilir. Bu bize ileride çok yardımcı olacak. Çünkü bazı durumlarda logE’yi bulduğumuzda, birileri “ama logV’yi bulmadınız” diyebilir. Böyle bir durumda bu bağlantıyı hatırlatacağım.

Bilgisayarlarda grafikleri ifade etmenin birçok yolu var; ben de bunlardan önemli olan bir kaçını anlatacağım. Aslında daha fazlası var. Ama biz birkaç tanesini göreceğiz.

En basiti adjacency matrix yani komşuluk matrisi olarak adlandırılandır. Burada G  eşit (V,E) gibi bir grafiğin A komşuluk matrisi, V’yi 1’den n’e kadar tamsayılardan oluşan bir küme olarak seçersem, n çarpı n büyüklüğünde olur ve bu A matrisinin ij’inci elemanının değeri, eğer ij kenarlar kümemizde varsa 1, yoksa 0 olacaktır. Basitçe, bu matriste ij girdisi varsa 1 yazarsınız ve bu size i ile j arasında bir kenar olup olmadığının öndayanağını verir.,

Predicate yani ön-dayanak, eğer hatırlarsanız ya 0 ya da 1 olan bir Boolean formülüydü. Bu durumda i’den j’ye bir kenar varsa 1, aksi halde 0’ı kullanıyoruz. Bazen kenar ağırlıklı grafiklerimiz olur, O zaman insanlar bunları kenar ağırlıkları olarak kullanırlar; bu i’den j’ye giden kenarın ağırlığı olacak. Şimdi bir örnek çözelim ve sezgilerimizin matematiksel tanımlarla örtüştüğünden emin olalım.

İşte bizim örnek grafiğimiz.

Şimdi bu grafiğin komşuluk matrisini çizelim. Bu, 1’den 1’e bir kenar olduğunu söylüyor mu? Cevap hayır. 1’den 2’ye bir kenar var mı? Evet, 1’den 3’e? Evet. 1’den 4’e? Yok, 2’den 1’e, yok, 2’den 2’ye, hayır, 2’den 3’e, evet var, 2’den 4’e? Hayır. 3’ten hiçbirine giden bir kenar yok, 4’ten 3’e bir kenar var. Bu kadar. Bu komşuluk matrisi, bu grafiğin matrisidir. Demek ki, bir grafiği bu komşuluk matrisiyle ifade edebiliyorum.

Grafiği bu şekilde ifade ettiğim zaman ne kadar depolama yerine ihtiyaç vardır? Teta , çünkü ikisinin de depolanması için gerekli büyüklük aynıdır. ’nin depolanmasını biz dense representation yani yoğun gösterim denilen bir şekilde ifade ederiz. Grafik yoğun olduğu zaman bu iyi çalışır. Grafiğin yoğun olması, varolan kenarların sayısının, bütün olası kenarların sayısına yakın olması anlamına gelir. Bu durumda bu iyi bir gösterimdir. Ancak, birçok grafik için var olan kenar sayısı olası kenar sayısından azdır, bu durumda grafik daha seyrektir. Sparse yani seyrek grafiklere örnek vermek isteyen biri var mı?  Bir grafik sınıfı soruyorum, öyle ki, grafikteki kenar sayısı olan n artsın, ama kenarların sayısı karesi oranında artmasın, çok daha az oranda artsın. Bir bağlantılı liste, bir zincir; buna teorik grafik açısından bakarsanız, bu mükemmel bir örnek, n uzunluğundaki bir zincir için sadece n tane kenar. Bu durumda, kenarların sayısı V düzeyinde olacaktır. Her bir sıra için sadece bir kenarımız var. Başka hangi grafikler seyrektir? Düzlemsel yani planar  grafik. V tane köşesi olan ve V’nin en az 3, E’nin en fazla 3V - 6 olduğu, bir düzlem üzerine çizilebilen grafikler.

Sonuç olarak V düzeyinde kenar sayısına sahip olmuş oluruz. Ortak grafiklere başka örnek ne var? Evet, ikili ağaçlar, aslında her türlü ağaç; eğer eki okursanız, buna serbest ağaç denir. Bir ağaç, bağlantılı grafiktir, tabii içinde hiç döngü olmamak şartıyla.

 

Yoğun grafiklere örneğiniz var mı? Tam grafik, Evet, bunların hepsi 1 olur; eğer kenar ağırlığınız varsa, matrisiniz tamamen 1’lerle dolu olur. Sonuç olarak, bu, yoğun gösterimler için iyi bir seçimdir. Ancak bazen daha seyrek gösterimler yapmak isteyebilirsiniz, bunun için de  kadar yer ayırmak istemeyebilirsiniz. Sonuçta matrisinizin büyük kısmı 0’lardan oluşacaktır. Eğer bunun 0 olduğunu biliyorsak, neden onu 0 olarak göstermeye çalışalım?

 

Bu amaçla, adjacency list gösterimi yani komşuluk listesi gösterimi kullanılır. Aslında verilen bir köşenin komşuluk listesi, komşusu olan köşeleri V’nin Adj’si yani komşuluğu olarak gösterilmesidir. Terminoloji açısından köşeler V’ye komşuluk eder ama kenarlar köşelere denk gelir. Bu durum, bir köşe ile kenar arasındaki ilişkidir. Komşuluk ise iki köşe arasındaki ilişkidir. Bu sadece dil; bu amaçla niye iki terim kullanıyorlar bilmiyorum ama yapılan budur.

 

Grafiğimizde, birinci köşenin komşuluk listesi  2 ve 3’ten oluşan kümedir, çünkü 1’den sadece 2 ve 3’e kenarlar gitmekte.. 2’nin komşuluk listesi 3ve 4’tür. 3’ünkü boş kümedir. 4 için ise 3’tür. Bu bizim gösterimimiz. Bu gösterim için ne kadar depolama yerine ihtiyacımız olduğunu bulmak için, komşuluk listesinin uzunluğunu anlamamız gerekir.

 

Bir V köşesinin komşuluk listesinin uzunluğu nedir? Buna ne isim veririz? Bu derecedir. Yönlendirilmemiş bir grafikte buna köşenin derecesi deriz. Bu yönlendirilmemiş durum. Digraf, yani yönlendirilmiş grafikte ise, bunu şöyle yazmakta yarar var, dereceye dış derece denir. Yani yönlendirilmiş grafikte, her köşemiz için bizim bir dış derecemiz, bir de iç derecemiz olur.

Burada iç derecemiz 3; burada dış derecemiz 2, tamam mı? Burada önemli bir önkuramımız var; “handshaking lemma” yani “tokalaşma önkuramı”. Bu matematikteki önemli önkuramlardan biridir. Bu bir hikayeden geliyor. Bir partiye gidilir, bu partideki herkes birbiriyle tokalaşır. Bazıları kimseyle tokalaşmaz. Birileri bazılarıyla tokalaşır.  Kimse kendi elini sıkmaz. Parti sürerken, ev sahibi herkesin kaç kişiyle tokalaştığını saymaya başlar. Kaç kişinin elini sıktınız diye konuklarına sorar. Cevapları toplar, cevabın çift sayı olması garantidir. Bu tokalaşma önkuramıdır. Eğer bunu bizim grafiklerimize uygular ve köşelerin derecelerini toplarsak, bu herkesin tokalaşma sayısıdır,  bu her zaman kenarların sayısının iki katıdır.  Pekiyi, neden bu doğru, neden kenar sayısının 2 katı çıkar? Evet?

Evet. Ne zaman bir kenar eklerseniz, her iki uçtaki kişilere birer derece eklemiş olursunuz. Yani kenarları saymanın iki farklı yolu vardır. Benim grafikte dolaşıp her köşenin derecesini sayarken kenarlara da bir işaret koyduğumu hayal ederseniz, işim bittiğinde her kenarda iki işaret olacaktır. Tamam değil mi? Bu oldukça basit bir teoremdir.  Bunun anlamı, yönlendirilmemiş grafikler durumunda elde edilen komşuluk listesi gösterimi için – ne kadar depolama alanı gereklidir?

En fazla 2E. Bu E düzeyindedir, ama hepsi bu değil. Evet, köşelerimizin sayısı artı kenar sayısının düzeyini bilmeniz gerekir. Yönlendirilmiş veya yönlendirilmemiş farketmez, çünkü sadece köşelerden oluşan ve hiç kenarı olmayan bir grafik bile bana V seviyesinde maliyete neden olacaktır. Demek ki, bu, teta (V artı E) kadar depolama yeri kullanacaktır. Asimptotik olarak bu aynı şeydir. Aslında bunu görmek digraflarda daha kolaydır, çünkü digraflarda, dış dereceleri ekliyorum ve bu E’ye eşit. Aslında bu yeniden düzenleme gibi amortize edilmiş bir çözümleme ile yapılacak olursa, bütün kenarların sayısını toplamanın bir yolu da, hesaplama işini köşe bazında yapmaktır. Her köşenin derecesini alırım bunu kenar bazında hesaplar ve kenar sayılarını 2’ye katlayıp toplarım; bu muhasebe tekniğinde kullanılan çözümlemede uygulanan amortize edilmiş bir çözümlemenin aynısıdır. Bunu göreceğiz.

 

Bu bir seyrek gösterimdir ve çoğu zaman komşuluk matrisi gösteriminden daha iyidir. Örnek olarak, internet ağının komşuluk listesi gösterimi yerine bir komşuluk matrisiyle yapıldığını hayal edin. İnternetteki linkleri göz önüne aldığımda, “Ben bunlara bağlıyım, bunlara ise bağlı değilim.” diye belirtmek zorunda olurdum. Herhangi bir sayfada, bağlı olmadığınız linklerin de listesini belirtme zorunluluğu, seyrek gösterimin avantajını gösterir.

 

Bunun yanısıra, komşuluk matrisi gösterimiyle ilgili güzel şey ise, her bir kenar tek bir bit ile gösterilebilir. Öte yandan komşuluk listesi gösteriminde her bir komşuyu ifade etmek için kaç bite ihtiyacımız olur? Her farklı komşuyu belirtmek için kaç bite ihtiyacımız var ? Her köşeyi isimlendirmek için LogV düzeyinde bite ihtiyaç olur. Bunun çok daha verimli olduğu gösterimler var. Eğer çok yoğun bir grafiğiniz varsa, bu daha iyi bir gösterim olacaktır. Gelecek hafta bu konunun üzerinde daha fazla duracağız; bir matris ve bir grafik aynı şeye bakmanın 2 farklı yoludur. Aslında komşuluk matrislerini çarptığınız birçok grafik teorisi vardır. Yani, grafikler ile matrisler arasında birçok ortak nokta var. Birine uygulayabildiğiniz matematiği, diğerine de çoğu zaman uygulayabilirsiniz.

Bir sorunuz mu var, yoksa parmağınızı öylesine mi havada tutuyorsunuz? Tekrar etmek için bu kadarı yeterli. Bugünün dersine geçmek istiyorum. Grafiklerle ilgili başka sorusu olan var mı? Bu aşama  EK B’yi tekrar etmek için iyi bir zamandır. Burada birçok güzel özellik vardır. Bugün ağaçların özelliklerinden birini işleyeceğiz. Ağaçlar çok özel türde grafiklerden biridir, bu nedenle gerçekten bu özelliklerin ne olduğuna bakmanızı istiyorum. Ağaçların hepsi birbirine denk olan 6 farklı tanımı var; bu teoreme bakmak ve okumak oldukça iyi bir fikir olur. Bunu sınıfta kanıtlamayacağız, ama anlamanız ve üzerinde düşünmemiz için iyi bir temel sağlayacaktır. Bundan ileride tekrar söz edeceğiz.

Bugün minimum span trees yani en az kapsayan ağaçlardan bahsedeceğiz.

Bu dünyanın en ünlü algoritmalarından bir tanesidir. Özellikle distributed yani dağıtık sistemlerde oldukça önemlidir. Hemen hemen bütün dağıtık sistemler “en az kapsayan ağaç” modelini bulmaya çalışırlar; her noktada canlı düğümler bulmaya çalışırlar. Bunun için AT&T firması yıllarca tekel olduğu dönemde, fatura sisteminde bunun algoritmasını geliştirdi; bu konunun üzerinde ileride biraz daha duracağız. Bunu uygulayan çok sayıda uygulama var.

Burada problemimiz şudur: Yönlendirilmemiş bağlı bir grafiğimiz, w ağırlık fonksiyonu ile birlikte, G eşittir (V,E) olarak tanımlıyoruz. w kenarlardan gerçek sayılara bir fonksiyondur. Bugünkü derste, basitliği sağlamak amacıyla önemli bir varsayımda bulunacağız; kitabınız bu varsayımı yapmıyor. Kitaptaki bu alternatif gösterime bakmanızı tavsiye ediyorum, çünkü o çok daha genel; ama anlamanız ve basitlik açısından ben problemi birazcık daha kolaylaştırıyorum. Biz bütün kenar ağırlıklarının birbirinden farklı olduğunu varsayacağız.

Bütün ağırlıklar birbirinden bağımsız.  Bu ne demek? Eğer bütün kenarlar farklı ağırlığa sahipse bu w fonksiyonu açısından ne anlama gelir? Ayrık matematik derslerini kim hatırlıyor? Bu injective yani bire birdir. Hem bire bir ve hem de onto yani örten olmak zorunda değil. Ancak bire bir olmadıklarında oldukça büyük bir kümeden bahsetmemiz gerekir, bu nedenle bire bir olmaları işimizi kolaylaştıracağından böyle bir varsayımda bulunuyoruz. Kitabınız bu varsayımı yapmıyor; kitapta bir şeyler teknik olarak daha kesin tanımlanıyor.

Böylece bu girdimiz, çıktı ise --

spanning tree yani bir kapsayan ağaç’tır. Bu ağaç T’dir ve kapsayan ağaç derken, bütün köşeler bağlantılı anlamına gelir. Bu en az ağırlığa sahip olmalıdır. Ağacın ağırlığını, bütün bağımsız kenarların ağırlığını toplayarak yazabiliriz. Buradaki simgelemde birazcık yolsuzluk yaptım; aslında (u,v) kenarının w’su şeklinde yazmam gerekirdi çünkü bu kenarların eşlemlenmesinden kaynaklanır ve bana çift parantez getirir. Ama bildiğiniz gibi ben simgelemlerde yolsuzluk yapmayı severim. Dolayısıyla buradaki fazladan parantezleri düşürüyorum, çünkü bunun kenarın ağırlığı olduğunu, sıralı ikilinin ağırlığı olmadığını biliyoruz. Bu simgelemin yazımı bağlamında daha uygun. Özellikle ev sınavlarınızı yaparken, uygun simgelemi kullanmak sizi problemi yazarken kaybedeceğiniz aşırı zamandan kurtaracaktır. Problemleri çözerken hangi simgelemi kullanacağınız üzerinde düşünmek önemlidir. Eğer iyi bir simgelem tercih ederseniz, teknik bir iletişim durumunda genel olarak insanlar sizi daha kolay anlayacaktır. Buna karşılık kötü bir simgelem, insanların sizi anlamamasına neden olabilir.

Bir örnek yapalım. Burada bir grafiğimiz var; ben daha önce birilerinin bana biyokimyadan esinlenip esinlenmediğini sorduğunu hatırlıyorum. Hayır esinlenmedim. Bunları sadece yazıyorum. Burada grafiğimiz; bazı kenar ağırlıkları verelim.  Bunlar kenarların ağırlıkları-- ve istediğimiz, öyle bir ağaç bulabilmek ki, bağlantılı ve çevrimsiz olsun ve her köşenin ağacın bir parçası olduğu bir grafik olsun. Aynı zamanda da en az ağırlığa sahip olsun. Biriniz bana “en az kapsayan ağaç” için bazı kenarlar önerebilir mi?

Evet, 9, güzel. 9 burada olmalı, çünkü neden? Çünkü bu kenara tek bağlanan kenar 9. Aynı şekilde 15 de burada olmalı. Bu ikisi de olmalı. Başka hangileri olmalı? 14 olmalı. Neden 14 olmalı? 14 veya 3’ten biri mutlaka olmalı. Ben en az ağırlıklı olanı istiyorum. Toplamda en az ağırlığı olanı istiyorum. 3’ün burada olması gerektiğini benimle tartışmak isteyen var mı?

Evet? Bu ikisinden küçük olanı, yani “en az kapsayan bir ağacın” toplamını alırken 3 hesaba katılmamışsa, ben 14 olan kenarı siler ve yerine 3 olan kenarı koyabilirim. Böylece daha az ağırlığı olan bir şey elde ederim, değil mi? Yani 3 burada olmak zorunda. Burada olması gereken başka hangi kenarlar var? Biraz bulmaca mantığı kullanın. 6 ve 5’in de mi burada olması gerekiyor? Bunlar niye burada olmalı?

 

Evet ama bu yolla da birbirlerine bağlanabilirler; bu yolu takip etme zorunluluğu yok. 6, 3 ile aynı nedenle burada olmak zorunda, değil mi? Çünkü bu elemanı bağlamak için iki seçimimiz var. Çünkü 12 olmazsa onu yine de bu yoldan bağlayabilirim. Yani 6 kesin olarak bu, burada. Hala herşey bağlı değil. “En az kapsayan ağaç” için başka neye ihtiyacım var? 7,5 ve 8, neden 7, 5 ve 8? Bunu sırasıyla tartışabilir miyiz? 5 neden burada olmalı? Evet, dört bağlı ögemiz var, bu, bu, aslında bu ve bu bağlı, güzel. En az üç kenarın onları bağlaması lazım, çünkü her bir kenar,  bağlı ögeleri bir azaltacak. Dolayısıyla 3 kenara ihtiyacımız var, bu üçü en ucuz olanlar. Evet, bu çalışır.

Bu çalışır, değil mi? Diğer kenarlardan birinin seçimi daha büyük olurdu ve bu çalışır, güzel. Pekiyi, şu an kapsayan bir ağaca sahip miyiz? Büyük, “bağlı bir grafiğimiz” var doğru mu? Benim çözümüm de bu mu? Evet bu benimkiyle aynı; tamam hayat tahmin edilebilir.

Herkesin “en az kapsayan ağacın” ne olduğuna dair bir fikri  oldu mu? Burada neler olduğu hakkında? Bu bulmaca ile ilgili bazı gözlemler yapalım ve şimdi size “optimal substructure property” yani “en uygun altyapı özelliğini” hatırlatmak istiyorum; çünkü, “en az kapsayan ağaç” çok iyi bir “en uygun altyapı” özelliğine sahiptir.

Kurulumda, bir MST’ye yani “en az kapsayan ağaca” sahip olacağız; buna T diyelim. Grafikteki diğer kenarların gösterilmeyeceğini size göstereceğim. Grafiğimiz burada. İşte bu bir grafik. Benim kağıdımdakine benziyor. Bunun bir “en az kapsayan ağaç” olduğu fikrindeyiz. Şimdi “en uygun altyapı özelliğine” bakacağız. Bunun için, ağacımdaki bir kenarı yok edeceğim, rastgele bir kenarı, örneğin (u,v)’yi sileceğim. Buna u, buna da v diyelim. Bu kenarı kaldırıyoruz.

Ağaçtaki bir kenarı kaldırırsam, ağaca ne olur? Geriye ne kalır? İki ağaca sahip olurum, doğru mu? Geriye iki ağacım kaldı. Size okumanızı tavsiye ettiğim kitap ekinde bunun kanıtı var; böylece her ne kadar bu durum çok açıksa da kanıtlanması da önemlidir. Bunu kaldırdık. T iki alt ağaca bölüntülendi. Bunları ve olarak adlandıracağız. Burada bir alt ağaç var ve burada da diğer alt ağaç. Ağaçta bölüntü yaptık. Hangi kenarı alırsam alayım, 2 alt ağacımız olacaktır. Alt ağaç önemsiz olabilir, mesela içinde sadece bir köşe yani düğüm olabilir ve herhangi bir kenar olmayabilir.

İspatlayacağımız teorem, “en uygun altyapı özelliğinin” sağlandığını gösterecek., grafiği için “en az kapsayan ağaç”, , G’nin bir altgrafiği  ve ’in köşeleri tarafından oluşturulmuş. ,’deki köşeler.

Bu resimde bu, bu da. Bu resimde, bunlar ’in köşeleri, yani, tamam mı? , x ve y köşe ikililerinin kümesi -- ve x ile y’nin her ikisi de’deki kenarlar ve aynı zamanda ’e ait olan kenarlar.

G’deki kenarları burada göstermedim. Ama temel olarak, eğer bir kenar buradan buraya gidiyorsa bunlar ’de olmalı; buradan buraya gidiyorsa olmamalı. Ve buradan buraya gidiyorsa, yine olmamalı. ’in köşeleri tarafından oluşturulan alt grafik, sadece ’deki cisimleri bağlar; aynı şey için de geçerlidir.

Teorem, grafiğindeki köşelerin oluşturduğu kenarlara bakıldığında bunun, bu alt grafik için “en az kapsayan ağaç” olduğunu söylüyor. Bu, teoremin ne söylediği. Eğer buraya bakarsam, buradaki köşelerin kümesi tarafından oluşturulan kenarlar açısından da aynı şeyin için de geçerli olması gerekir.

Bunu burada bile yapabiliriz. Eğer örnek olarak bunlara bakarsam, diyelim ki 5’ten kestim. Eğer 5 kenarını çıkarırsam, bu 4 köşeden oluşur. Burada oluşan alt grafiğe baktığımda, bu kenarlar buradadır. Aslında 6, 8 ve 3 buradaki “en az kapsayan” ağacın kenarlarıdır. Evet bu teoremin söylediği; şimdi bunu kanıtlayalım.

Tamam, bunu ispatlamak için hangi tekniği kullanacağız? Bu tekniği daha yeni öğrendik: ipucu, ipucu. Bu, sizin metin düzenleyicinizde kullandığınız bir şey: kes ve yapıştır, güzel, kes ve yapıştır. Tamam, o zaman T’nin ağırlığını, sildiğim kenarın ağırlığı artı,’in ağırlığı artı’nin ağırlığı olarak bulabilirim. Tamam, bu toplam ağırlıktır. Yani, argüman oldukça basittir.  için’den daha iyi birüssü olduğunu kabul edelim. Bir kapsayan ağacı oluşturmak için daha iyi bir yolum olduğunu kabul edelim.

Tamam, o zaman sadece (u,v) kenarını ve üssü ile’nin birleşimini içeren bir T üssü bulabilirim. O zaman, daha iyi bir kapsayan ağacım varsa, için daha düşük ağırlıklı bir kapsayan ağaç olanüssünü oluşturabilir ve bunu burada (u,v) kenarımın, ve T ile üssü olarak her ne çalışıyorsa onların yerine koyabilirim. Bu da bir kapsayan ağaç olacak ve G için T’nin kendisinden daha iyi olacaktır; çünkü bunların ağırlığı aynen bunun ağırlığı gibidir. Sadece T üssünün ağırlığını kullanmaya alışmalıyım ve bu daha da azdır. T’nin “en az kapsayan ağaç” olduğu varsayımı eğer alt parçalar için daha iyi bir ağaç bulabilirsem bozulacak.

En uygun alt yapı özelliğimiz oldukça güzeldir. Bütün problemi kapsayan genel geçer en uygun çözümüm varsa, en uyguna uyan bazı alt problemlerim de olur ve ben bunların çözümlerini bulabilirim.

Şimdi soru, bu dinamik programlamada bir kalite olgusu olmakla birlikte, örtüşen altproblemler durumunda ne olur? Aynı özelliğe orada da sahip miyim? Bu tarz problemler için aynı tarz bir çözümden bahsedebilir miyiz? Örneğin, farklı kenarları kaldırdığımı hayal edin. Verilen bir kenara bakıyorum ve onu kaldırıyorum. Bu bütünü 2 parçaya bölüyor ve burada bir parçam daha var. Ve onu da kaldırıyorum. Sonunda

işi bir grup birbirine benzeyen alt problemler bularak mı bitireceğim? Evet, eğer bunu çıkarırsam, bunu buraya çıkarırsam, burada başka bir ağacım, burada da başka bir ağacım olur. Aslında bunu dışarı çıkarsaydım ve daha sonra da bunu dışarı çıkarsaydım aynı şey olacaktı. Eğer bir sıralamaya bakarak kenarları dışarı alsaydım, tam olarak bir grup örtüşme alt problemi ile karşılaşacaktım.

 

Evet, pekiyi, bu durumda nasıl bir yaklaşım kullanmamız gerekiyor? Dinamik programlama, güzel. Ne büyük sürpriz değil mi? Evet, dinamik programlama kullanabilirsiniz.  Ama “en az kapsayan ağaç” daha da güçlü bir özellikle karşımıza çıkar. Dinamik programlama için bütün ipuçlarına sahibiz, ama daha güçlü bir teknik kullanabilmemiz için daha büyük bir ipucu çıkacak gibi gözüküyor.

Buna aç gözlü algoritmaların Hallmark’ı yani kalite damgası diyoruz. Bizim aç gözlü seçim özelliği diye tabir ettiğimiz özellik -- bize yerel olarak en uygun seçimin, genel anlamda da en uygun olduğunu söylüyor. Ve tabii ki, bütün bu damgaları kutulamak istersiniz, çünkü bunlar bu yöntemi kullanmak için gereken ipuçlarına sahipler. Aç gözlü seçim özelliği diye adlandırdığımız bir özelliğe sahibiz. Bu durumda bunun nasıl çalıştığını göstereceğim. Bu özelliği kullanarak dinamik programlamadan bile daha iyi sonuçlar elde edebilirsiniz.

Eğer iki tane dinamik programlama özelliğini görürseniz, bu dinamik programlamayı kullanabileceğinize dair size ipucu verir, ama aynı zamanda, aç gözlülük özelliğinin olup olmadığına da bakmanız gerekir, çünkü eğer bu özelliği bulursanız, dinamik programlamadan daha iyi bir yöntem kullanabileceksiniz demektir. Eğer sadece 2 özellik bulursanız, bu genelde dinamik programlamayı kullanacağınız anlamına gelir, ama eğer bu üçüncüyü de bulursanız, yaşasın, büyük ikramiyeyi kazandınız demektir!

İşte bu fikri göstermek için ispatlayacağımız teorem. Bunların hepsi buluşsaldır. Size nerede dinamik programlamayı, nerede aç gözlü algoritmayı kullanacağınızı söyleyen bir algoritma veremem. Ancak hangi yapıda çalıştıklarını anlatabilirim.

İşte size teorem: T, grafiğimizin MST’si yani en az kapsayan ağacı olsun. A da V’nin yani köşelerin herhangi bir alt kümesi olsun.

Şimdi, (u,v) kenarımızın A kümesini ve A’nın tümleyenini en az ağırlıkta bağlayan kenar olduğunu varsayalım; A’nın tümleyeni V – A’dır. Bu durumda teorem, (u,v)’nin en az kapsayan ağaçta olduğunu söyler. Buradaki grafiğimize bakalım ve durumun gerçekten böyle olup olmadığını görelim. A’yı tek düğümlü seçerek bunu deneyebilirim. Mesela buradaki elemanı alalım, bu benim A kümem olsun ve geriye kalan herşey de V-A.

Bunu, diğer herşeye bağlayan en az ağırlıklı kenara bakıyorum. Bunu diğer her şeye bağlayan sadece 2 kenar var. Teorem hafif olanın en az kapsayan ağaçta olduğunu söylüyor. Kazandım. Ele aldığım her bir köşeye bakacak olursanız, o köşeden çıkan en hafif kenarın bizim en az kapsayan ağacımızda olduğunu göreceksiniz. Ama bu kenarların hepsinin burada olduğu anlamına gelmiyor.

Pekiyi, sadece hayal edin, bu köşeler kümesine bağlı 3 köşeye bakın. Buradan giden 3 kenarım var. En hafifi 5. Bu en az kapsayan ağaçtadır. Veya bunu bu şekilde kesebilirim. Bunlar bunun üzerinde, kenarlardan 7, 8, 14 aşağı gidiyor. 7 en az kapsayan. Nasıl seçersem seçeyim, bu içeri, bu dışarı, bu içeri, bu dışarı, bu içeri, bu dışarı, bu içeri bu dışarı, bütün kenarların ne olduğuna bakalım. En hafif kenar hangisi ise, en az kapsayan ağaca girer. Bu bir anlamda yerel bir özelliktir, Geri kalan ağacın ne olduğuna bakmam gerekmez. Sadece elimdeki küçük köşeler kümesine bakarım ve bunları dünyanın geri kalanına bağlamak için hangi kenarı seçmeliyim ona karar veririm. En ucuz olanı tercih ederim. Bu açgözlü yaklaşımdır ama gördüğümüz kadarıyla kazanır. Bu yerel seçim A alt kümesi için iyi olduğu gibi genelde de geçerlidir. Bu bütün fonksiyonu en uygun hale getirir. Bu teoremin söylediği şeydir. Şimdi teoremi kanıtlayalım. Buraya kadar herhangi bir soru var mı? Haydi teoremi kanıtlayalım. 

 

A’yı V-A’ya bağlayan en az ağırlıklı kenar (u,v) ve bu kenarın (u,v)’nin en az kapsayan ağaçta olmadığını varsayalım. Yani en hafif kenarı içermeyen bir en az kapsayan ağacımız olduğunu varsayalım. Burada teoremi ispat etmek için çelişki yöntemini kullanacağız. Kes ve yapıştır, güzel. Evet, kesip yapıştıracağız. Burada bir örnek çizeyim. Burada simgelem kullanacağım; bunların bir kısmını renklendireceğim. Simgeleme göre bunların bazılarını renklendireyim: A’nın elemanlarını renksiz bırakıyorum ve V-A’nın elemanlarını renklendiriyorum. Yani eğer renkli değilse A’nın elemanıdır.. Bu benim en az kapsayan ağacım. Yine grafikteki bütün kenarları göstermiyorum, ama onlar orada, tamam mı? Benim (u,v) kenarım, ki bu kenar benim en az kapsayan ağacımda yok, bu kenar şu diyelim. u, A’nın içinde, v ise V-A’nın içinde. Kurulumu herkes görüyor mu? Ben bu kenarın en az kapsayan ağacın içinde olması gerektiğini ispatlamak istiyorum.

 

Burada yapmak istediğim şu; bir T ağacım var, u ve v köşelerim var, ve ağaçtaki her bir köşe arasında sadece bir basit yol mevcut; basit yol, ileri geri gitmeyen, kenar ve köşelerden tekrar geçmeyen yol demek. u’dan v’ye tek ve basit bir yol var. Bu yolun olduğunu düşünelim. Böyle bir yolun olduğunu biliyorum çünkü kitabınızın EK B’sinde Bölüm B.5.1’i okudum; burada ağaçlarla ilgili güzel bir teorem bulunmakta. Burada tek ve basit bir yol olduğunu bu nedenle biliyorum.

Şimdi yapacağımız bu yola göz atmak. Bu durumda, bu yol, buradan buraya, buraya ve buraya gidiyor. Bu yol boyunca, A’daki bir köşenin V-A’daki bir köşeye bağlanacağı bir yer olmalı. Bu A’da olduğundan, ve bu da V-A’da olduğundan yolun bir yerinde bir geçiş olmalı. Bunların hepsi A’da değil; özellikle v, A’da değil.

Yapacağımız, (u,v) kenarını yol üzerinde olan ve A’daki bir köşeyi V-A’daki bir köşeye  bağlayan ilk kenar ile değiştirmek. Bu durumda, bu kenar o kenar. A’dan V-A’ya gidiyorum. Genel olarak, birçok zaman alternatif yollarım olabilir, ama ben ilk karşılaştığımı alıyorum; bu elemanı. Bu kenarı içeri koyuyorum. Pekiyi, ne oluyor? (u,v) kenarı A’yı V-A’ya bağlayan en hafif kenar. Yani bu kenardan daha hafif. Bunları değiştirerek, gelmiş geçmiş en hafif ağacı yaratmış olurum, bu da eski ağacın “en az kapsayan ağaç” olduğu varsayımını çürüttü.

Tamam, T’den daha hafif bir kapsayan ağaç bulmamız, bizi çelişkiye sürükledi. Bu bir çelişki. Nasıl gidiyoruz? Herkes benimle mi? Şimdi biraz algoritma yapalım.

Prim’in algoritması diye adlandırılan bir algoritmayı çalışacağız. Prim, en az kapsayan ağaçlarla ilgili bu algoritmayı bulmasından ötürü AT&T’de oldukça yükseldi. Bulduğu algoritma da şirketteki faturalandırma kodlarında uzun yıllar kullanıldı. Prim, aynı zamanda, Bell Laboratuvarların en enerjik yıllarında orada da epey yükselmişti. Bu, sizin tek yapmanız gerekenin bir algoritma keşfetmek olduğunu anlatıyor. Böyle bir durumda, bir tekelin başkanı olabilirsiniz. Tabii, devlet tekellere karşı birşeyler yapabilir, ama eğer bu sizin hayattaki amacınız ise, bir algoritma keşfedin.

Fikir şu. V-A’yı öncelikli Queue yani öncelikli kuyruk olarak yapılandıracağız. Buna Q diyeceğiz. Q’daki her köşeyi, A’daki bir köşeye bağlayan en az ağırlıklı kenar ile anahtarlayacağız.

İşte size kod. Q’nun bütün köşeleri kapsadığı durum ile başlıyoruz. Bu durumda A boş bir küme. Q’daki her en az ağırlıklı kenar sonsuz olarak anahtarlanıyor; çünkü onları boş küme olan A’ya bağlayan bir kenar yok. Şimdi tek elemanla başlıyoruz.

Buna S diyoruz ve buna 0 atıyoruz; S, V’nin içindeki rastgele bir eleman.. Bu bizim başlangıcımız ve sonra ana algoritma devreye girecek. Çözümlemeyi yaparken tahtanın sol tarafına bazı şeyler yazacağım. Siz de not alıyorsanız, belki boşluk bırakmak isteyebilirsiniz. Artık Q boş olmadığı sürece, en küçük elemanı dışına alıyoruz. Yani çekiyoruz. Sonra bazı işler yapıyoruz. Evet, işte bu.

Burada dikkat çekmem gereken bir konu var, burada neler oluyor ona bakalım; sonra örnekte bunu deneyeceğiz. Her bir basamakta en küçük elemanı kuyruğun dışına çıkartıyoruz. Sonra da komşuluk listesindeki her adımda, yani v’den u’ya giden bir kenarın olduğu her durumda, v’nin hala V-A kümemizin içinde kalıp kalmadığına bakıyoruz; çünkü dışarıya çıkardığımız şeyler artık A’nın bileşenleri olacaktır. Tamam mı? Ne zaman dışarıya bir şey çıkarırsak, bu yapılandıracağımız yeni bir A olacak..

Her adımda, A’yı diğerlerine bağlayan en ucuz kenar hangisi bulmaya çalışıyoruz. Aslında temel olarak yaptığımız, en ucuz kenarı bulup, onu A’ya taşımak ve daha sonraki en ucuzu bulmaya çalışmak. Bu işlemi yapmaya hep devam ederiz. Şimdi örnekte yapacağız. Ve bu işlemi her yaptığımızda hangi köşenin beni içeri taşımaktan sorumlu olduğunun kaydını tutarız.

Benim iddia ettiğim, sonuçta, burada yarattığım ikililer kümesine, yani V ve V’nin Pi’sine baktığımda, bunlar “en az kapsayan ağacı” oluşturacaktır. Şimdi bunu yapalım. Bu neydi? Eski kurulum. Buradaki elemanlardan kurtulalım, çünkü bunları baştan tekrar hesaplayacağız. Siz grafiği tekrar notlarınıza almak isteyebilirsiniz. Bunu birazcık düzelteyim, evet başlıyoruz. Herşeyi sonsuz yapıyorum. Burası anahtar değerini tutacağım yer. Bundan sonra yapacağım şey bir köşe bulmak. Bunu seçiyorum ve S olarak adlandırıyorum. Bu köşeyi seçiyorum ve bunu 0 yapıyorum. Şimdi, en küçük değeri çıkışa vereceğim. Aslında yapacağım bu elemanı gölgelemek, böylece elemanın A’ya katıldığını göstermiş oluyorum. Şimdi A’nın simgelemi bu şekilde olacak; bu A’nın -- bu da V-A’nın elemanı. Yapacağımız bir gözatmak. Bu elemanı dışarı çıkardığımızda komşuluk listesindeki her bir kenar ve yine komşuluk listesindeki her bir köşe, yani bu elemanların hala Q’da yani V-A’da olup olmadığına bakıyoruz. Ve eğer öyleyse ve  anahtar değeri kenar ağırlığından küçük ise, bu değeri kenar değeri ile değiştiriyoruz. Bu durumda burayı 7 ile değiştiriyoruz. Bunu 15’le, bunu 10’la değiştiriyoruz; çünkü bizim ilgilendiğimiz en ucuzu. Dikkat edin, V-A’daki yani öncelikli kuyruğumdaki her şey, A’ya daha önceden taşıdığım ögelere en ucuz yol değerleri ile bağlı. Bu güncellemeyi yaptığımda bizim öncelikli kuyruğumuzda bir şeyler oluyor; anahtar değeri çok açık olmasa da kesin olarak azalıyor.

Bu nedenle “decrease key” yani "anahtar değerini azaltma” uygulamalıyım. Anahtar azaltma, bir öncelikli kuyruk işlemidir ve bu uygulamada anahtar değerini azaltır. Bu öncelikli kuyruğu oluşturmak için kullanılan veri yapılarında açıkça olmasa da kesin olarak çalışır. Öncelikli kuyruk oluşturmak için kullanılan en yaygın veri yapısı – Heap yani yığındır. Yığında bu işlemi yaptığımdan emin olmalıyım; yığını etkilemeden herhangi bir değişiklik yapamam. Dolayısıyla burada örtülü bir işlem var.

Şimdi tekrarlıyorum. En ucuzu buluyorum, sonra bu elemanlardan u’ya bir işaretçi oluşturuyorum. Bu eleman buraya giden bir işaretçi hazırlıyor. Bu eleman, bu yoldan giden bir işaretçi hazırlıyor, bu eleman da bu yolda. Bu benim Pi’m; Pi değeri benim değerimi değiştirmeme neden olan elemanı takip ve kaydeder. Şimdi tekrar gidelim ve en ucuzunu tekrar bulalım. Bunu biraz hızlı yapacağız, bu hızlı bir algoritma.

Aynı şeyi tekrar yapacağız. Dışarı çıkarmak için en ucuz olanı hangisi? Bu eleman değil mi? Bunu dışarı alacağız, bunun bütün komşularını güncelliyoruz. Bu eleman 5 oluyor, bu 12, bu da 9. Bu eleman değişmiyor. Bunu değiştirmiyoruz, çünkü artık öncelikli kuyrukta değil. Bu elemanların işaretçilerini ayarlıyoruz. Bu basamakta da işimiz bitti. Tekrar en ucuzunu buluyoruz. En ucuzu hangisi? Buradaki 5. Bunu dışarı alıyoruz. Komşuları güncelliyoruz. Bu 6 oldu şimdi. Ve bu işaretçimiz var.

Bu elemana bir güncelleme yapmıyoruz, çünkü öncelikli kuyrukta değil. Bu eleman 14 oluyor, bu 8. Bu elemanı güncelliyoruz, 8. Bunu doğru bir şekilde yaptım mı? Evet, Pi bu elemanın bir fonksiyonu. Bu eleman daha sonra yok oluyor. Burada unuttuğum birşey var, 12, evet, bu kaldırıldı. Çünkü Pi sadece bir fonksiyon, şimdi tamamım. Şimdi A kümem bu 3 elemanı içeriyor, şimdi en ucuz kenarı arıyorum. Biliyorum ki, bu en az kapsayan ağaçta. Bunu açgözlülükle seçebilirim.. 

Şimdi, en ucuz eleman hangisi? Bu eleman gibi gözüküyor? Evet, 6. Bunu alıyoruz ve bunları güncellememiz gerekiyor. Burada bir işlem yok. Bu elemanlar zaten A’da oldukları için bir şey değişmiyor. Şimdi en ucuzumuz 8. 8’i dışarı alıyoruz; bunu güncelliyoruz. Burada yapılacak bir şey yok; burada da yok. Hayır, hayır, burada 14 yerine bunu 3 yapabiliriz. Bu işaretçiden vazgeçip şunu alıyoruz; şimdi en ucuzu 3. 3’te yapılacak bir şey yok tabii ki. Son olarak 9’u alıyorum. Tamam. Ve 15. Tamam. Algoritma sona eriyor.

 

Şimdi baktığımda, başlangıçta sahip olduğum bütün kenarları aldığımı görüyorum.

 Burada bir çözümleme yapalım. Bu kısım bana Teta V düzeyinde maliyet getirdi, doğru mu? Şimdi bu kısımda ne yaptığımıza bakalım; burayı yaparken bu döngüye kaç defa girdik? V defa. Kuyruğa V tane eleman koyduk; hiç bir şey eklemedik. Onları sadece dışarı aldık; V defa. Burada V çarpı belli sayıda en küçüğü bulma işlemi yaptık. Daha sonra komşuluk listesine gittik ve sabit bazı işler yaptık. Ama azaltılmış anahtarlarımız açıkça olmasa da kesin olarak elde edildi. Bu buradaki işlemimiz.

Kaç tane kesin olarak azaltılmış anahtarımız var? Bu bizim pahalı işlemimiz olacak. Bu durumda küçük u’nun derecesi kadar. Sonuçta toplamda, kaç tane azaltılmış anahtarımız var? V tane geçiş var. Küçük u ne kadar büyük olabilir? En fazla küçük v düzeyinde. Yani kullanımda azalma oldu. Ama bundan daha iyi bir sınırlama elde edebiliriz.

 

Gerçekten kaç tane var? En fazla E seviyesinde. Çünkü, ne yapıyorum, bütün köşelerin derecelerini topluyorum. Bu benim bunu kaç defa yürüttüğümü gösteriyor. Yani Teta E düzeyinde kesin azaltılmış anahtarlarım var. Şimdi süre, Teta v çarpı en küçüğün dışarı alınması için gerekli zaman, artı E çarpı azalan anahtar için gereken süreye eşittir. Dolayısıyla, şimdi, veri yapılarına bakalım ve farklı veri yapılarında bu formül ne kadar zaman süre alıyor onu bulalım.

Bir veri yapısını oluştururken farklı yollarımız vardır. En küçüğü bulma, anahtarların azaltılması ve toplam alma maliyetleri. Bir veri yapısı oluşturmanın en kolay yolu sıralanmamış bir dizilim oluşturmaktır. Eğer sırasız bir dizilim varsa, dizinin en küçük elemanını bulmak neye mal olur?  Doğru, bu durumda büyük-O büyük V düzeyinde, çünkü bu dizilim V büyüklüğünde bir dizilimdir. Peki ya anahtar azaltma? Bunu 1 düzeyinde halledebilirim.

Toplamda . Güzel   seviyesinde bir algoritma. Veya bu insanların önerdiği gibi binary heap yani ikili yığında nasıl olur? En küçüğü bulma işleminde, ikili yığın bana      O (log V)’ye mal olacaktır. Anahtar azaltma ise, log V süresine mal olur, çünkü değerleri sadece karıştırırsınız, aslında köke doğru karıştırırsınız. Böylece buradaki toplam maliyet nedir?

 

E log V, güzel. Hangisi daha iyi? Bu duruma göre değişir. Hangisi ne zaman daha iyidir? Eğer yoğun bir grafik ise E  ’ye yakındır, bu durumda dizilim daha iyidir. Ama eğer yoğun değil, seyrek bir grafikse, E ’den oldukça küçüktür ve ikili yığın daha verimlidir. Bu Fibonacci Yığını diye çağrılan bir veri yapısının bulunmasını sağladı. Fibonacci Yığını kitabın 20. Bölümünde işleniyor. Sizi içerikten sorumlu tutmayacağız ama bu gerçekten ilginç bir veri yapısıdır, çünkü amortize edilmiş bir yapıdadır. Bu veri yapısıyla en küçüğü dışarı alma işlemini log V düzeyinde amortize edilmiş sürede yapabilirsiniz.

Anahtar azaltmayı ise amortize edilmiş 1 düzeyinde yaparsınız. Bunları kullandığımda ne elde ediyorum? Bu V kere log V artı E. E artı VlogV. Bunlar amortize edilmiş, pekiyi bu ne? Şaşırtmacalı bir soru. Bu en kötü durum. Burada amortize edilmemiş.. Bunlar amortize edilmiş; bu da zaten amortize etmenin güzelliği. Bunun en kötü durum olduğunu söyleyebiliyorum. E artı VlogV, çünkü amortize edilmiş işlem maliyetlerini eklediğim zaman, gerçek maliyetler için bir üst sınır bulmuş oluyorum. Bu nedenle farklı işlemlere farklı maliyetler atamanın amortize edilmiş analizin güzelliklerinden biri olduğunu söylüyorum. Hepsini toplarım ve en kötü durum maliyetini bulurum. Bu sonuçta VlogV olur.

Gitmeden önce bir kaç algoritma daha var. Kitabınızdaki Kruskal Algoritması amortize edilmiş veri yapısına başka bir örnek. Buna Disjoint Set yani Ayrışık Küme veri yapısı da deniyor. Bu da ikili yığın gibi E logV zamanında çalışıyor. Dolayısıyla kitabınızı okumanızı tavsiye ediyorum. Bu konuda bugüne kadar yapılmış en iyi algoritma bizim fakültedeki David Karger ile eski bir mezunumuz Phil Kline’nın, ki kendisi şimdi Brown’da profesör ve Princeton’da profesörlük yapan Robert Tarjan, ki kendisi hemen her veri yapısının ustası olarak görülüyor, bunlar tarafından 1993’te  geliştirildi. Bu rastgele bir algoritma. V artı E düzeyindeki beklenen süre ile sonucu veriyor. Bugüne kadar yapılmışların en iyisi bu.

Doğrusal zamanda bir deterministic yani belirlenimci bir en kötü durum sınırlaması olup olmadığı bugüne kadar çözülmemiş problemlerden biridir. Ama rastgele doğrusal çözüm vardır ve bunun dışında ek varsayımlar olmadan elde edilen en iyi sınır budur.

 

Tamam, çok ilginç konular işledik. Gelecek sefer pratikte kullanılan açgözlü algoritmalar ve dinamik programlama ile ilgili bir sürü fikir üzerinde çalışacağız.

 

Dersimiz burada bitmiştir.