SORU
28 Mayıs 2011, CUMARTESİ


Dinamik programlama ve memoization: aşağıdan yukarıya vs yukarıdan aşağıya yaklaşımlar

Memoization ile aşağı ve aşağıdan yukarı yaklaşım üst yöntemi doğru anladığımdan emin değilim.

Aşağıdan yukarıya: Sana ilk" subproblems ve sonra çözmek büyük subproblems küçük sorununa çözüm kullanarak. "küçük bak nerede

Yukarıdan aşağıya: Eğer önce subproblem çözüm hesaplanan varsa doğal bir şekilde ve bir kontrol sorunu çözmek.

Biraz kafam karıştı. Biri bunu açıklayabilir mi? Ve fark nedir?

CEVAP
29 Mayıs 2011, Pazar


rev4: kullanıcı Sammaron tarafından çok anlamlı Bir yorum belki bu cevap daha önce yukarıdan aşağıya karışık ve aşağıdan yukarı. kaydetti Ederken aslında bu cevap (rev3) ve diğer cevapları dedi ki "aşağıdan yukarıya memoization" ("kabul subproblems") olabilir ters (yani, "yukarıdan aşağıya" olabilir "kabul subproblems" ve "aşağıdan yukarıya" olabilir "oluştur subproblems"). Daha önce dinamik programlamanın bir alt türü olarak karşı dinamik programlama farklı bir tür olmak memoization okuma yaptım, yani bu bakış açısı abone olmama rağmen, bu alıntı. Bu cevap doğru başvurular literatürde bulunabilir kadar terminoloji agnostik olması için yeniden yazılan ve bir topluluk wiki bu cevap dönüştürülmüş. Lütfen akademik kaynakları tercih ederim. Referans listesi: {Web:http://cs.stackexchange.com/questions/2644/top-down-bottom-up-dynamic-programing 1} {Edebiyatı: -}

Özetleyelim

Dinamik programlama iş yinelenen yeniden önlemek bir şekilde hesaplamalar sipariş hakkında. Ana sorun (subproblems senin ağacın kökü), ve subproblems (ağacı) var.Bu subproblems genellikle ve üst üste tekrarlayın.

Örneğin, Fibonnaci en sevdiğiniz örneği ele alalım. Bu biraz saf bir özyinelemeli arama yaparsak subproblems tam ağaç:

TOP of the tree
fib(4)
 fib(3)......................   fib(2)
  fib(2).........   fib(1)       fib(1)...........   fib(0)
   fib(1)   fib(0)   fib(1)       fib(1)              fib(0)
    fib(1)   fib(0)
BOTTOM of the tree

(Diğer bazı nadir sorunlar, bu ağacın bazı dalları, sigara sonlandırma temsil eden sonsuz olabilir, ve böylece ağacın dibinde sonsuz büyük olabilir. Bazı sorunları ayrıca, tam ağaç gibi vaktinden göründüğünü bilmiyor olabilir, ve bu nedenle ortaya çıkarmak için hangi bir karar vermek için bir algoritma/bir strateji gerekebilir.)


Memoization, Tablolama

Birbirini dışlayan değil, dinamik programlama, en az iki ana teknikleri vardır:

  • Memoization - Bu laissez-faire bir yaklaşım vardır: zaten tüm subproblems bilgisayarlı sahip olduğunuzu varsayalım. Hiçbir fikrim optimal değerlendirme sırası var. Genellikle gerçekleştirmek için yinelenen bir çağrı (ya da bazı yinelemeli eşdeğer) kök, ve de umarım alırsın yakın optimum değerlendirilmesi amacıyla, ya da bir kanıtı alacaksın optimal değerlendirme sırası. Sen özyinelemeli aramayı asla senin yüzünden bir subproblem yeniden hesaplar emin olunönbelleksonuçları, ve yinelenen alt-ağaçları yeniden değildir.

    • örnek:Eğer hesaplama Fibonacci dizisi fib(100), sadece buna, öyle de olur Ara fib(100)=fib(99) fib(98), hangi Ara fib(99)=fib(98) fib(97), ...vb..., hangi Ara fib(2)=fib(1) fib(0)=1 0=1. Sonunda fib(3)=fib(2) fib(1) ama biz önbelleğe çünkü fib(2), yeniden gerek yok çözeceğini.
    • Bu ağacın üst kısmında başlar, ve geri köklerine doğru ağaçlar/yapraklar subproblems değerlendirir.
  • Tablolama - ayrıca bir dinamik programlama aklınıza "tablo doldurma" (gerçi genellikle çok boyutlu, bu 'masa' çok nadir durumlarda non-Öklid geometrisi olabilir). algoritma Bu gibi memoization ama daha aktif içerir ve ek bir adım: almak gerekir, öncesinde zaman, tam olarak hangi sırayla yapacaksın, hesaplamaları (bu olmadığını ima emri olmalı statik, ama o size çok daha fazla esneklik ve daha memoization).

    • örnek:Eğer fibonacci yapıyor, bu sırada sayıları hesaplamak için seçin: *,*,***9 8 10*... gelecek olanlar daha kolay hesaplamak, böylece her değer önbelleğe alma. Ayrıca tablo (önbellekleme başka bir formu) doldurmak gibi düşün.
    • Ben şahsen 'Listeleme' çok, ama çok terbiyeli bir terim. kelime duymuyorum Bazı insanlar bu düşünün "dinamik programlama".
    • Algoritma çalıştırmadan önce, programcı tüm ağaç olarak görüyor, bir algoritma köküne doğru belli bir sırayla, genellikle bir tablo doldurmaktan subproblems değerlendirmek için yazar.

(Onun en genel, "dinamik programlama" ben söyleyebilirim, ben programcı olarak görüyor bütün ağaç, sonra yazar bir algoritma uygulayan bir strateji olarak değerlendirilmesi subproblems (optimize neyse istediğim özellikler, genellikle bir arada zaman karmaşıklığı ve alan karmaşıklığı). Strateji bu değerlendirme sonuçlarına dayalı bir yerlerde, belirli bazı subproblem, ve belki de uyum sağlar kendisi başlamalıdır. "Dinamik programlama" en genel anlamda, genellikle denemek için önbellek bu subproblems (ve daha genel olarak, aynı zamanda önlemek kaslı subproblems... bir ince ayrım belki de davanın grafikleri) çeşitli veri yapıları. Çok sık bu veri yapıları diziler veya tablolar gibi kendi özünde vardır. Subproblems çözüm varsa artık onlara ihtiyacımız varsa bile atılabilir.)

[Daha önce bu cevap bir açıklama yukarıdan aşağı vs-aşağıdan yukarıya doğru terminoloji yaptı; açıkça iki ana yaklaşım tamamen olmasa da bu şartlara tanımlansın olabilir Memoization ve Tablolama denir. Çok fazla kişi tarafından kullanılan genel terim hala" bazı insanlar "" dinamik programlama. özellikle alt başvurmak için Memoization demek "Dinamik Programlama. Bu cevap yukarıdan aşağı ve topluluk akademik çalışmaların uygun kaynaklar bulmak kadar aşağıdan yukarı olduğunu söylemek reddediyor. Sonuçta önemli terminoloji yerine farkı anlamak önemlidir.]


Artıları ve eksileri

Kodlama kolaylığı

Memoization çok kolay (genellikle "memoizer" sizin için otomatik olarak yaptığı açıklama veya sarıcı fonksiyon) ve yaklaşım ilk satırı olmalıdır. bir yazarsın kodu. Tablolama olumsuz bir sipariş ile gelmek zorunda olmasıdır.

Recursiveness

Yukarıdan aşağıya ve aşağıdan yukarıya hem doğal olmayabilir ama özyineleme veya yinelemeli tablo-dolum uygulanması gerektiğini unutmayın.

Pratik ile ilgilidir

İle memoization, ağaç çok derin (örneğin fib(10^6)), olur tükendi yığın alanı, çünkü her gecikmiş hesaplama olmalı giy yığın, ve sen-ecek var 10^6.

Eniyi

Her iki yaklaşım olmayabilir zaman uygun olursa sipariş başına (ya da denemek) ziyaret subproblems değil optimum, özellikle eğer orada birden fazla yolu hesaplamak için bir subproblem (normalde önbelleğe olurdu gidermek bu, ama teorik olarak mümkün olduğunu önbellekleme olmayabilir bazı egzotik olgu). Memoization genellikle eklemek zaman karmaşıklığı için uzay karmaşıklığı (örneğin tablolama daha fazla özgürlük için atmak hesaplamaları, gibi kullanarak tablolama ile Fib kullanmanızı sağlar O(1) boşluk, ama memoization ile Fib kullanır O(N) yığın alanı).

Gelişmiş iyileştirmeler

Ayrıca son derece karmaşık bir problem yapıyorsun, ama tablolama (ya da en azından gitmek istediğiniz memoization direksiyon daha aktif bir rol almak) yapmak için başka seçenek olabilir. Ayrıca optimizasyon kesinlikle çok önemli olduğu bir durumda siz ve optimize etmek gerekir, tablolama sen yoksa sen aklı başında bir şekilde izin vermez hangi iyileştirmeler yapmak için izin verir. Benim naçizane görüşüm, normal yazılım mühendisliği, hiçbiriniz bu iki dava daha geldi, bu yüzden sadece ben sadece kullanmak memoization ("bir işlevi olan önbelleğe cevaplar") tabii bir şey (gibi yığın alanı) yapar tablolama gerekli.


Daha karmaşık örnekler

Burada özellikle dikkat çekici örnekler listesi, DP genel bir sorun değil, ama ilginç bir şekilde memoization ve tablolama ayırt eder. Örneğin, bir formülasyon diğerinden daha çok daha kolay olabilir, ya da temelde tablolama gerektiren bir iyileştirme olabilir:

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Joshua Benedict

    Joshua Bened

    26 EKİM 2013
  • Kingsimba357

    Kingsimba357

    7 NİSAN 2008
  • thewinekone

    thewinekone

    17 Aralık 2005