Dinamik Programlama ve Böl ve Conqu Benzerlikleri
Şimdilik gördüğüm gibi, dinamik programlamanın bölün ve fethet paradigmasının bir uzantısı olduğunu söyleyebilirim .
Onlara tamamen farklı bir şeymiş gibi davranmam. Çünkü her ikisi de, bir sorunu doğrudan veya çözülecek kadar basit hale gelinceye kadar aynı ya da ilgili türdeki iki ya da daha fazla alt soruna tekrar tekrar bölerek çalışırlar . Daha sonra alt problemlerin çözümleri birleştirilerek orijinal probleme bir çözüm elde edilir.
Öyleyse neden hala farklı paradigma isimlerimiz var ve neden dinamik programlamayı bir uzantı olarak adlandırdım. Bunun nedeni, dinamik programlama yaklaşımının soruna ancak sorunun belirli kısıtlamaları veya önkoşulları olması durumunda uygulanabilmesidir . Ve bundan sonra dinamik programlama, bölme ve fethetme yaklaşımını notlama veya tablolama tekniği ile genişletir .
Adım adım gidelim…
Dinamik Programlama Önkoşulları / Kısıtlamaları
Az önce keşfettiğimiz gibi, dinamik programlamanın uygulanabilmesi için bölme ve ele geçirme sorununun sahip olması gereken iki temel özellik vardır:
Optimal altyapı - alt problemlerinin optimum çözümlerinden optimum çözüm oluşturulabilir
Çakışan alt problemler - problem, birkaç kez yeniden kullanılan alt problemlere ayrılabilir veya problem için yinelenen bir algoritma, her zaman yeni alt problemler üretmek yerine aynı alt problemi tekrar tekrar çözer
Bu iki koşul gerçekleştiğinde, bu bölme ve fethetme sorununun dinamik programlama yaklaşımı kullanılarak çözülebileceğini söyleyebiliriz.
Divide ve Conquer için Dinamik Programlama Uzantısı
Dinamik programlama yaklaşımı, bölme ve fethetme yaklaşımını, performansı önemli ölçüde artırabilecek alt sorun çözümlerini depolama ve yeniden kullanma amacına sahip iki teknikle ( notlama ve tablolama ) genişletir . Örneğin, Fibonacci fonksiyonunun saf özyinelemeli uygulaması, O(2^n)
DP çözümünün sadece O(n)
zamanla aynı şeyi yaptığı zaman karmaşıklığına sahiptir .
Memoization (yukarıdan aşağıya önbellek doldurma) , önceden hesaplanmış sonuçların önbelleğe alınması ve yeniden kullanılması tekniğini ifade eder. Kaydedilen fib
işlev bu şekilde şöyle görünecektir:
memFib(n) {
if (mem[n] is undefined)
if (n < 2) result = n
else result = memFib(n-2) + memFib(n-1)
mem[n] = result
return mem[n]
}
Tablolama (aşağıdan yukarıya önbellek doldurma) benzerdir ancak önbellek girişlerini doldurmaya odaklanır. Önbellekteki değerleri hesaplamak en kolay şekilde yinelemeli olarak yapılır. Tablolama sürümü fib
şöyle görünecektir:
tabFib(n) {
mem[0] = 0
mem[1] = 1
for i = 2...n
mem[i] = mem[i-2] + mem[i-1]
return mem[n]
}
Not alma ve tablo karşılaştırma hakkında daha fazla bilgiyi buradan edinebilirsiniz .
Burada kavramanız gereken ana fikir, bölme ve fethetme sorunumuzun çakışan alt problemlere sahip olması, alt problem çözümlerinin önbelleğe alınmasının mümkün hale gelmesi ve böylece not / tablonun sahneye çıkmasıdır.
Sonuçta DP ve DC Arasındaki Fark Nedir
Artık DP önkoşullarını ve metodolojilerini bildiğimiz için yukarıda belirtilenlerin tümünü tek bir resme koymaya hazırız.
Kod örneklerini görmek istiyorsanız, burada iki algoritma örneği bulacağınız daha ayrıntılı açıklamaya göz atabilirsiniz : DP ve DC arasındaki farkı gösteren İkili Arama ve Minimum Düzenleme Mesafesi (Levenshtein Mesafesi).