Bir problemi dinamik programlamaya uygun olarak nasıl tanımlıyorsunuz?


19

Son zamanlarda dinamik programlamayı okuyorum. Sıfırdan başlayan ve şimdi DP problemlerini belirleme ve çözmede oldukça iyi olan birinden duymak isterim. Bu sorunları DP olarak tanımlamakta ve kısa ve öz bir çözüm bulmakta zorlanıyorum.

Yeni başlayan DP sorunlarının ve MIT kaynaklarının çoğundan geçtim.

Yanıtlar:


17

Bir fizik geçmişinden geliyorum ve bu yüzden çok fazla matematik. Tümevarımlı kanıtlar ile benzerlikler bularak özyinelemeli / dinamik programlama çözümlerine çok uygun sorunları kolayca bulabilirim .

İndüksiyonla kanıtı olarak iki bölümünüz var:

  • eğer bir şey yineleme N için doğruysa, yineleme N + 1 için de doğrudur
  • Eğer iterasyon için doğru olduğunu kanıtlamak 1

Özyinelemeli programlama / dinamik programlamada:

  • bir çıkış koşulu tanımlarsınız (örneğin, yineleme 1 için çözümü zor bir şekilde bağlarsınız)
  • yineleme N-1 çözeltisi verildiğinde yineleme N için çözüm hesaplarsınız

Yani, diğerlerinin cevapladığı gibi, bu bir deneyim ve ipuçlarını seçme meselesidir, ancak size rehberlik etmek için diğer becerileri tekrar kullanabilirsiniz. Bundan sonra, her zaman bahsettiğim iki bölüme sahip olmanız gerekir: eğer yapmazsanız, işe yaramaz.

Örneğin, bir kümenin tüm permütasyonlarını oluşturmak için:

  • çıkış koşulu: yalnızca bir öğeniz varsa, döndürün
  • özyineleme: bir N öğesinin permütasyonları, her bir öğeyi seçerek ve öğeyi kaldırarak aldığınız alt kümenin tüm N-1 (çok) permütasyonları ile birleştirerek elde ettiğiniz N permütasyon kümesidir.

8

Dinamik programlama problemlerinin çoğu hafıza ile çözülebilir. Memoization normalde hem daha sezgisel hem de kodlaması daha kolaydır. DP yerine not verme konusunda düşünmeyi faydalı bulabilirsiniz.

Bir sorunun memoizasyona uygun olup olmadığını sezmek daha kolaydır (adımlar Slivvz'in cevabı ile aynıdır , ancak zihinsel kaymanın biraz daha kısa olduğunu düşünüyorum). Ancak, bir sorunu notla çözdüğünüzde, not önbelleğinizin nasıl doldurulduğunu inceleyebilir ve özyineleme olmadan, algoritmayı dinamik bir programlama algoritmasına değiştiren sırayla doldurabilirsiniz.

TL; DR; version: Dinamik programlamayı notlama açısından daha kolay anlayabilirsiniz.

Ayrıca bkz. StackOverflow: Dinamik programlama ve notlama: aşağıdan yukarıya ve yukarıdan aşağıya yaklaşımlar .


4

Dinamik programlama temel olarak iki şeyle ilgilidir:

  1. Optimal altyapı
    Daha büyük çözümler daha küçük çözümlerden elde edilebilir; çözme çift yönlü değildir.

  2. Çakışan alt problemler
    Küçük çözümler birçok kez yeniden kullanılacaktır. Alt sorunlar hiç örtüşmüyorsa DP / nottan yararlanamazsınız; sahip olduğunuz şey bölmek ve fethetmektir .

DP sorunlarına genel yaklaşım:

  • Çalışan naif bir özyinelemeli veya yinelemeli sürüm yazın.

  • İşlevin gereksiz iş yaptığına dikkat edin.

  • Bu gereksiz işi yapmaktan kaçınmanın bir yolunu, genellikle hatıralarla bulun.


Bütün bunlar teorik bir bakış açısından doğrudur. IMO hızlı tanımlama daha tanıdık olmak için biraz daha pratik gerekir :)
user110036

2

Project Euler problemlerini yapmaya başladığımdan birkaç yıl öncesine kadar, tek bir dinamik programlama çözücüsü uygulamamıştım - geçmişim CS değil matematik / fizik / sayısal hesaplama uygulandı . Orada DP'de çözülebilen sorunlar (örn. 76 , 158 , 161 , 242), ama çok daha fazlası var) benim en sevdiğim tür olduğu ortaya çıktı. Yararlı bir teknik olacağı zaman kesinlikle daha iyi hale gelirsiniz: temelde, ihtiyaç duyulan yolların patlamasını evcilleştirmenin mümkün olduğu bir çeşit özyinelemeli, böl ve fethet yaklaşımıyla çözülebilecek gibi görünen şeyleri arayın yinelenen alt problemleri tanıyarak ve önceden hesaplanan sonuçları yeniden kullanarak araştırılması; üzerinde durulacak minimal durum vektörünü - ve ilgisiz “tarih” in silinebildiğini belirleyebilmek çok önemli bir adımdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.