Decidere sotto-problemi per la programmazione dinamica


39

Ho usato più volte la tecnica della programmazione dinamica, ma oggi un amico mi ha chiesto come definire i miei sotto-problemi, ho capito che non avevo modo di fornire una risposta formale obiettiva. Come definisci formalmente un sotto-problema per un problema che risolveresti usando la programmazione dinamica?


Sembra che nessuna delle risposte esistenti (ad aprile 2019) sia abbastanza buona, specialmente per i principianti. Consiglierei tutorial su altri siti.
Apass

Risposte:


35

Il principio della programmazione dinamica è pensare dall'alto verso il basso (cioè ricorsivamente) ma risolvere dal basso verso l'alto. Quindi una buona strategia per la progettazione di una DP è formulare il problema in modo ricorsivo e generare sotto-problemi in quel modo.


14
Sostengo che sia l' unica strategia.
JeffE,

2
@JeffE Sì, ho letto e usato le tue note durante l'insegnamento delle mie lezioni di algoritmo ed è stato efficace. Citazione: "La dinamica non riguarda la compilazione di tabelle. Si tratta di ricorsione intelligente!"
Dai

2
La mia comprensione di come insegnare DP è fortemente influenzata dalle note di @ JeffE :)
Suresh,

3
È anche possibile trasformare automaticamente una procedura ricorsiva top-down in un algoritmo di programmazione dinamica. Quando stai per tornare, archivia la risposta in una tabella hash. All'inizio di ogni chiamata, controlla se la risposta è già nella tabella hash e, in tal caso, restituiscila immediatamente. Molti algoritmi diventano facili con questa idea. Ad esempio con una tabella di questo tipo, gli algoritmi ricorsivi sui tentativi funzionano automaticamente sui DAWG. Memorizzando un valore sentinella nella tabella all'inizio di una chiamata, gli stessi algoritmi possono funzionare anche su DFA. Gli algoritmi sui BDD diventano molto facili da specificare in modo ricorsivo.
Jules,

1
Ultimo ma non meno importante, questo può avere enormi vantaggi in termini di prestazioni. Ad esempio, il tradizionale algoritmo di somma dei sottoinsiemi bottom-up può calcolare tonnellate di voci di tabella non necessarie. Con questo metodo verranno calcolate solo le voci della tabella necessarie.
Jules,

4

Come ha sottolineato @Suresh, una volta che sai che il tuo problema può essere risolto da DP (cioè mostra una sottostruttura ottimale e sottoproblemi sovrapposti), potresti pensare a una divisione e a conquistare una soluzione ricorsiva.

Naturalmente, dividere e conquistare sarà altamente inefficace perché ogni sottoproblema riscontrato nell'albero di ricorsione associato sarà risolto di nuovo anche se è già stato trovato e risolto. È qui che DP differisce: ogni volta che si incontra un sottoproblema, lo si risolve e si memorizza la sua soluzione in una tabella. Successivamente, quando si incontra di nuovo quel sottoproblema, si accede in volta alla sua soluzione invece di risolverlo di nuovo. Poiché il numero di sottoproblemi sovrapposti è in genere limitato da un polinomio e anche il tempo necessario per risolvere un sottoproblema è polinomiale (altrimenti DP non può fornire una soluzione economica), in generale si ottiene una soluzione polinomiale.O(1)

Pertanto, pensare a una soluzione di divisione e conquista ti fornirà la visione di ciò che un sottoproblema potrebbe essere per il tuo problema specifico.


1
"sottostruttura ottimale" (qualunque cosa significhi) probabilmente non è una condizione sufficiente per la solvibilità DP. "Sottoproblemi sovrapposti" non è certamente necessario.
Raffaello

1
Sottostruttura ottimale e supproblemi sovrapposti sono entrambi esposti a problemi che possono essere risolti in modo efficiente da DP. Ovviamente la sottostruttura ottimale da sola non è sufficiente per la solvibilità DP. Tuttavia, se non si hanno sottoproblemi sovrapposti, è possibile risolvere il problema dividendo e conquistando ordinariamente con lo stesso costo: in effetti, il vantaggio di DP rispetto a dividere un conquistatore è che ogni sottoproblema viene risolto esattamente una volta quando viene rilevato nella struttura ricorsiva .
Massimo Cafaro,

1
Non è la mia formulazione: la troverai su "Introduzione agli algoritmi" di Cormen, Leiserson, Rivest e Stein e su molti altri libri di testo sugli algoritmi.
Massimo Cafaro,

1
Jup, e la maggior parte ha almeno parzialmente torto. Sono felice di elaborare se pubblichi una domanda adatta.
Raffaello

1
Non sono sicuro di aver capito correttamente il tuo ultimo commento. Per dimostrare che questo tipo di caratterizzazione è sbagliato (non può essere parzialmente sbagliato: o è corretto o è sbagliato), puoi semplicemente mostrare come controesempio, un problema che non mostra sia la sottostruttura ottimale sia i sottoproblemi sovrapposti, ma è adatto a una soluzione DP polinomiale. Ma nota che, in questo contesto, ciò significa una soluzione che è decisamente migliore della normale divisione e conquista.
Massimo Cafaro,

2

La mia esperienza è trovare un modo per "ridurre l'enumerazione ridondante con l'aiuto della memorizzazione di un valore utile già elencato". A proposito, la Programmazione dinamica è molto popolare nell'ICPC (Concorso internazionale di programmazione collegiale. Chiunque può avere la propria opinione sulla DP dopo aver esercitato diversi problemi dell'ICPC.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.