Programmazione dinamica: cos'è e tutto da sapere?

Programmazione dinamica
Fonte immagine: AfterAcademy
Sommario nascondere
  1. Cos'è la programmazione dinamica?
  2. Come funziona la programmazione dinamica?
    1. #1. Approccio dall 'alto verso il basso
    2. #2. Approccio dal basso verso l'alto
  3. Caratteristiche della programmazione dinamica
    1. #1. Sottoproblemi Sovrapposizione
    2. #2. La sottostruttura ha proprietà ottimali
  4. Usi della programmazione dinamica nel mondo reale
    1. #1. Problema dello zaino
    2. #2. Percorso più breve di tutte le coppie
    3. #3. Intaglio della cucitura
    4. #4. Apprendimento automatico e genomica
    5. #5. Crittografia
  5. Che cos'è un esempio reale di programmazione dinamica?
  6. Come risolvere i problemi di programmazione dinamica?
    1. #1. Riconoscere il problema della programmazione dinamica
    2. #2. Determinare le cause del problema
    3. #3. Scegli tra un metodo iterativo e uno ricorsivo
    4. #4. Incorporare un sistema di memorizzazione
    5. #5. Metti in parole la relazione di ricorrenza
  7. Programmazione dinamica degli algoritmi
    1. Diversi tipi di algoritmi di programmazione dinamica
    2. #2. Algoritmo di Floyd-Warshall
  8. In che modo un algoritmo di programmazione dinamica risolve i problemi Lcs più velocemente di una tecnica ricorsiva?
  9. Quali sono i problemi di programmazione dinamica in Python
    1. #1. Zaino (0-1) Rimbalzato
    2. #2. 0/1 Memoizzazione a zaino
    3. #3. Problema di sottoinsieme uguale
  10. Vantaggi della programmazione dinamica
    1. #1. Rimedio efficace
    2. #2. Facilita la facile ricerca dei problemi
    3. #3. Efficiente
    4. #4. Efficace quando un problema ha più soluzioni
  11. Quali sono gli svantaggi della programmazione dinamica?
    1. #1. Sotto-problemi che continuano a ripetersi
    2. #2. Complicazione nel tempo e nello spazio
    3. #3. Quadro per il problema
    4. #4. Difficile da mettere in pratica
  12. Conclusione
  13. Domande frequenti sulla programmazione dinamica
  14. Qual è la differenza tra programmazione lineare e programmazione dinamica?
  15. Quanto è difficile imparare la programmazione dinamica?
  16. La programmazione dinamica è molto difficile?
  17. articoli simili
  18. Riferimento

La programmazione dinamica è un termine che probabilmente è stato usato ormai se sei stato sul campo per un certo periodo di tempo. L'argomento emerge frequentemente nelle riunioni di revisione dei progetti e nelle interazioni quotidiane degli ingegneri, ed è anche un punto focale nei colloqui tecnici. La strategia divide et impera è un metodo infallibile per raggiungere qualsiasi obiettivo. Nella programmazione per computer, questa stessa idea è vera. Numerose difficoltà hanno sottotipi che possono essere isolati e trattati separatamente, consentendo la risoluzione definitiva del problema primario. In questo articolo discuteremo l'algoritmo di programmazione dinamica e Python.

Cos'è la programmazione dinamica?

La programmazione dinamica è un metodo per risolvere problemi complessi riducendoli prima a quelli più semplici, quindi utilizzando le soluzioni a quei problemi più semplici come elementi costitutivi per risolvere il problema originale. 

Segmentiamo il problema in questione in blocchi gestibili. Nella maggior parte dei casi, l'unica vera distinzione tra il problema del genitore ei problemi del figlio è la loro dimensione relativa. Pertanto, questi mini-problemi possono essere scomposti in ancora più mini-problemi, e così via, all'infinito. Immagina che un problema e i suoi vari sottoproblemi formino un albero. I problemi "foglia" vengono affrontati per primi, seguiti dai problemi "genitori" e così via lungo l'albero dei problemi. Man mano che affrontiamo difficoltà minori, registriamo i nostri progressi per un uso successivo. Questo ci permette di saltare quella parte del problema in futuro. 

Questo metodo è simile alla tecnica divide et impera in quanto suddivide un problema in problemi più piccoli che possono essere risolti indipendentemente e poi combinati per ottenere la soluzione finale.

Come funziona la programmazione dinamica?

La programmazione dinamica è efficace perché semplifica i problemi difficili scomponendoli in parti costitutive. Il passo successivo consiste nell'individuare le migliori risposte a queste sfide che ne derivano. I risultati di queste procedure possono essere memorizzati in modo che le soluzioni corrispondenti possano essere recuperate dalla memoria e utilizzate senza ulteriori calcoli. Inoltre, la soluzione può essere salvata per evitare di ricalcolare sottoproblemi precedentemente risolti. 

Esistono due metodi per realizzare la programmazione dinamica:

#1. Approccio dall 'alto verso il basso

In informatica, i problemi vengono generalmente risolti costruendo soluzioni in modo ricorsivo o utilizzando i risultati dei passaggi precedenti per affrontare il problema in questione. È possibile memorizzare o tenere una tabella delle soluzioni ai sottoproblemi se sono simili. Il metodo top-down si basa sull'apprendimento attraverso la memoria meccanica. La memoizzazione equivale a eseguire la ricorsione e la memorizzazione nella cache due volte. La ricorsione comporta l'effettuazione di una chiamata indiretta alla funzione, mentre la memorizzazione nella cache implica il tenere traccia dei risultati intermedi.

Tra i molti vantaggi dell'approccio dall'alto verso il basso ci sono:

  • Il metodo top-down è semplice da comprendere e applicare. Per comprendere meglio ciò che deve essere fatto, questo metodo scompone i problemi nei loro elementi componenti. Ogni nuovo sviluppo porta con sé il sollievo di un ostacolo prima insormontabile. Alcuni dei pezzi potrebbero anche essere applicabili ad altri problemi.
  • Consente la soluzione di sottoproblemi su richiesta. Il metodo dall'alto verso il basso consentirà la scomposizione dei problemi in blocchi gestibili, con le soluzioni a tali blocchi archiviate per un uso successivo. Quindi, i clienti possono chiedere aiuto per riparare ogni componente. 
  • Anche il debug è semplificato. Dividere un problema in blocchi più piccoli rende più facile seguire la risposta e vedere potenziali errori. 

Di seguito sono riportati alcuni degli svantaggi dell'utilizzo di un approccio dall'alto verso il basso:

  • La strategia top-down utilizza il metodo di ricorsione, che occupa più memoria nello stack di chiamate rispetto ad altri approcci. Ciò si traduce in definitiva in una diminuzione delle prestazioni. Inoltre, può verificarsi un overflow dello stack se la ricorsione va troppo indietro nel passato.

#2. Approccio dal basso verso l'alto

Dopo che la soluzione di un problema è stata espressa in termini di sottoproblemi in un modo che ricade su se stessa, gli utenti possono riscrivere il problema utilizzando l'approccio dal basso verso l'alto, in cui risolvono prima i sottoproblemi più piccoli e poi applicano le loro soluzioni a quelli più grandi . 

Contrariamente al metodo top-down, la ricorsione viene eliminata quando si utilizza il metodo bottom-up. Pertanto, le funzioni ricorsive non aggiungono sovraccarico non necessario né provocano l'overflow dello stack. Inoltre, consente la compressione dei dati. La complessità temporale della ricorsione viene ridotta eliminando la necessità di ricalcolare gli stessi valori. 

Alcuni vantaggi di lavorare da zero sono i seguenti:

  • Innanzitutto determina come verrà costruito un enorme problema a partire da sottoproblemi più piccoli e riutilizzabili.
  • Eliminando la ricorsione, aiuta a fare un uso migliore della memoria disponibile. La complessità temporale è ridotta come effetto collaterale. 

Caratteristiche della programmazione dinamica

Ci sono due caratteristiche distintive della programmazione dinamica:

#1. Sottoproblemi Sovrapposizione

Le modifiche di un problema primario che sono più gestibili sono chiamate "sottoproblemi". La sequenza di Fibonacci, in cui ogni numero è uguale alla somma dei due precedenti (0, 1, 1, 2, 3, 5, 8,…). Puoi dividere il compito di trovare l'ennesimo valore nella sequenza di Fibonacci in blocchi più gestibili. Man mano che trovi soluzioni affrontando lo stesso sottoproblema più e più volte, queste serie di difficoltà sovrapposte diventano sempre più difficili da risolvere.

La programmazione dinamica può essere utilizzata per suddividere grandi lavori di programmazione in blocchi gestibili a causa del verificarsi universale di sottoproblemi sovrapposti.

#2. La sottostruttura ha proprietà ottimali

La proprietà della sottostruttura ottimale si manifesta quando è possibile creare una soluzione ottima dalle soluzioni di tutti i sottoproblemi. Affinché la ricorsione funzioni, devi applicare la risposta che ottieni da ogni sovrapposizione all'intero problema. La proprietà ottimale della sottostruttura è mostrata dall'intero problema quando, come nel caso della sequenza di Fibonacci, ogni sottoproblema ha una soluzione che può essere applicata al sottoproblema successivo nella sequenza per determinarne il valore.

Usi della programmazione dinamica nel mondo reale

Ecco gli usi della programmazione dinamica.

#1. Problema dello zaino

La programmazione dinamica è stata ampiamente utilizzata per risolvere il problema dello zaino. Questi sono i problemi che stiamo affrontando:

Il valore ideale per ogni sottoproblema, determinato dal numero di articoli in questione e dalla quantità di spazio rimasto nello zaino, può essere memorizzato in un array bidimensionale, risolvendo rapidamente questo problema. Possiamo massimizzare il valore includendo o escludendo l'articolo corrente in ogni fase. La risposta può essere trovata nell'angolo in basso a destra dell'array.

Il problema dello zaino può essere utilizzato in un'ampia varietà di contesti, dall'imballaggio dei bagagli al prendere decisioni di investimento all'allocazione delle risorse.

#2. Percorso più breve di tutte le coppie

Il problema del percorso più breve in un grafico pesato è un altro uso tipico della programmazione dinamica. Utilizzando tecniche come Floyd-Warshall o Bellman-Ford, possiamo trovare il percorso più breve tra due coppie di nodi qualsiasi.

Per tenere traccia del percorso più breve tra due nodi qualsiasi, questi algoritmi utilizzano un array tridimensionale. Inoltre, per tenere traccia della loro distanza dal punto di partenza, confrontano il risultato con la distanza tra il punto di partenza e il nodo intermedio in ogni fase. Dopo tutto, le iterazioni sono complete, la soluzione finale sarà la matrice delle distanze.

Esistono diversi usi per risolvere il problema del percorso più breve di tutte le coppie, come nell'analisi della rete, nel routing, nella navigazione, nell'analisi dei social network, ecc.

#3. Intaglio della cucitura

Nel campo dell'elaborazione delle immagini, il seam carving è un'interessante applicazione della programmazione dinamica. Il compito a portata di mano è quello di ridurre le dimensioni di un'immagine senza alterare nessuna delle sue caratteristiche essenziali. I percorsi a bassa energia in un'immagine, noti come cuciture, possono essere utilizzati per sottrarre o aggiungere pixel per ottenere questo effetto.

Utilizzando la programmazione dinamica, possiamo calcolare l'energia cumulativa di ciascun pixel nell'immagine in base al suo gradiente e ai suoi vicini, quindi utilizzare tali informazioni per determinare quali cuciture devono essere rimosse o aggiunte. Quindi, procedendo verso l'alto dal basso dell'immagine, possiamo individuare la giunzione con la minor quantità di energia potenziale. Questo metodo può essere riutilizzato fino al raggiungimento della dimensione richiesta.

Inoltre, le immagini possono essere ridimensionate, ritagliate, reindirizzate e altro ancora con l'aiuto del seam carving.

#4. Apprendimento automatico e genomica

Le sfide dell'apprendimento automatico e della genomica come l'allineamento delle sequenze, i modelli di Markov nascosti e gli alberi filogenetici sono tutti riconducibili alle capacità di risoluzione dei problemi della programmazione dinamica.

L'allineamento di più sequenze di simboli (spesso DNA o proteine) per scoprire punti in comune è chiamato allineamento di sequenze. Questo può far luce sui loro legami evolutivi, funzioni nella società o caratteristiche strutturali. Gli allineamenti ottimali possono essere trovati tramite la programmazione dinamica assegnando punteggi alle corrispondenze e alle discrepanze tra le sequenze.

I modelli probabilistici noti come modelli di Markov nascosti vengono utilizzati per descrivere i dati delle serie temporali condizionati a stati sconosciuti. Sono utili per modellare fenomeni difficili come il riconoscimento vocale, la PNL, la bioinformatica, ecc. Quando viene fornita una serie di osservazioni, le tecniche di programmazione dinamica come Viterbi e Forward-Backward possono determinare la sequenza più probabile di stati nascosti.

Gli alberi filogenetici mostrano le connessioni tra specie o geni nel tempo. È possibile dedurre antenati comuni, date di divergenza ed eventi evolutivi da questi punti in comune. Inoltre, un algoritmo di programmazione dinamica come Fitch e Sankoff può essere utilizzato per generare alberi filogenetici ottimali utilizzando i dati di sequenziamento.

#5. Crittografia

Anche la crittografia, lo studio della comunicazione segreta, beneficia delle capacità di risoluzione dei problemi della programmazione dinamica. Crittografia, decrittografia, firme digitali, autenticazione e altri processi simili fanno tutti parte della crittografia.

La crittografia converte le informazioni da leggibili dall'uomo a leggibili con chiave segreta. La decrittografia è il processo di riconversione dei dati crittografati in testo in chiaro utilizzando la chiave originale o una nuova. Le firme digitali consentono di verificare l'autenticità e l'integrità di un messaggio o di un documento. Il controllo delle credenziali del mittente o del destinatario può verificare l'identità del mittente o del destinatario.

Diversi tipi di crittografia, inclusa la crittografia a chiave dinamica, la crittografia basata su codice e la crittografia basata sulla programmazione dinamica, possono essere tutti implementati con la programmazione dinamica.

La crittografia a chiave dinamica è un meccanismo per crittografare e decrittografare i messaggi con chiavi che cambiano costantemente. Le chiavi "dinamiche" sono quelle che si evolvono nel tempo o in risposta ad altri fattori. Ciò le rende più sicure delle chiavi statiche, che sono vulnerabili agli attacchi. È possibile utilizzare la programmazione dinamica per generare e mantenere aggiornate le chiavi durante l'implementazione della crittografia a chiave dinamica.

Utilizzando una tecnica nota come crittografia basata su codice, è possibile crittografare e decrittografare i messaggi utilizzando codici di correzione degli errori nel processo. È possibile correggere gli errori di trasmissione con codici di correzione degli errori. L'uso della crittografia basata su codice è ampiamente considerato resistente ai quanti poiché è sicuro contro gli attacchi dei computer quantistici. La programmazione dinamica può essere utilizzata per cifrare e decifrare le comunicazioni utilizzando un sistema crittografico basato su codice.

Come metodo per crittografare e decrittografare i dati, la crittografia basata sulla programmazione dinamica si basa su un algoritmo di programmazione dinamica. Per affrontare le sfide dell'ottimizzazione, le tecniche di programmazione dinamica tipicamente suddividono il problema in un insieme di sottoproblemi più semplici. La crittografia a programmazione dinamica utilizza lo zaino, il percorso più breve e il seam carving.

Che cos'è un esempio reale di programmazione dinamica?

Numerose istanze di applicazioni software del mondo reale utilizzano la programmazione dinamica per mantenere l'agilità e l'efficienza, riducendo al contempo l'ingombro delle risorse sul sistema host. Alcuni casi sono i seguenti:

  • Google Maps. Google Maps utilizza la programmazione dinamica per trovare il percorso più rapido da una determinata origine a diverse destinazioni.
  • Rete. Trasferimento sequenziale di dati da un singolo mittente a più destinatari.
  • Correttori ortografici. L'algoritmo di modifica della distanza determina il numero di passaggi necessari per trasformare una parola in un'altra e fornisce una misura quantitativa del grado di dissomiglianza tra le due parole. 
  • Software antiplagio. I metodi di distanza del documento aiutano a determinare la somiglianza del documento di testo.
  • Motori di ricerca. Per determinare quanto siano effettivamente simili due contenuti Internet.

Come risolvere i problemi di programmazione dinamica?

Imparare la formula per risolvere i problemi di programmazione dinamica è il passo successivo dopo aver compreso il concetto di programmazione dinamica. Ecco alcuni suggerimenti su come applicare la programmazione dinamica al problema in questione e arrivare a una soluzione praticabile:

#1. Riconoscere il problema della programmazione dinamica

La parte più importante è rendersi conto che un algoritmo di programmazione dinamica può risolvere la dichiarazione del problema specificata. Per risolvere questo problema è necessario innanzitutto determinare se ciascuna delle affermazioni del problema può essere suddivisa in parti più piccole come funzione.

#2. Determinare le cause del problema

Se hai già concluso che la programmazione dinamica è lo strumento giusto per il lavoro, il passo successivo è identificare la struttura ricorsiva del problema tra i suoi sottoproblemi costituenti. In questo caso bisogna tenere conto della natura fluida delle condizioni del problema. Questa variabile potrebbe essere una posizione dell'array o una velocità di risoluzione del problema.

Inoltre, il conteggio delle parti costitutive del problema è cruciale.

#3. Scegli tra un metodo iterativo e uno ricorsivo

Per risolvere i problemi di programmazione dinamica, puoi utilizzare approcci iterativi o ricorsivi. Da quanto detto finora, è lecito affermare che il metodo ricorsivo è preferibile. Tutte le considerazioni di cui sopra, tuttavia, valgono da sole, indipendentemente dal metodo scelto per risolvere il problema.

Entrambi gli approcci ricorsivo e iterativo richiedono che tu specifichi la relazione di ricorrenza e il caso base del problema.

#4. Incorporare un sistema di memorizzazione

Quando si affronta un problema con una struttura simile, può essere utile ricordare l'esperienza passata nella gestione di sottoproblemi comparabili. Di conseguenza, la complessità temporale del problema diminuirà. La complessità temporale di un'attività potrebbe crescere in modo esponenziale se continuiamo a risolvere gli stessi sottoproblemi più e più volte senza utilizzare la memorizzazione.

#5. Metti in parole la relazione di ricorrenza

Quando risolvono un problema, molti programmatori saltano la definizione della relazione di ricorrenza e passano direttamente alla codifica. Avrai una migliore comprensione del problema e sarai in grado di codificarlo più rapidamente se puoi esprimere esplicitamente la relazione di ricorrenza prima di iniziare.

Programmazione dinamica degli algoritmi

La maggior parte delle applicazioni della programmazione dinamica include l'algoritmo ricorsivo. L'uso della programmazione dinamica per l'ottimizzazione implica che la ricorsione è intrinseca alla maggior parte dei problemi di ottimizzazione.

Tuttavia, non è possibile risolvere problemi tutti ricorsivi con la programmazione dinamica. Una ricorsione può trovare la soluzione solo con una strategia divide et impera a meno che non vi sia la presenza di sottoproblemi sovrapposti, come nel problema della sequenza di Fibonacci.

Questo perché i sottoproblemi sottostanti in un algoritmo ricorsivo come Merge Sort non si sovrappongono, escludendo l'uso della programmazione dinamica.

Diversi tipi di algoritmi di programmazione dinamica

Ecco i diversi tipi di algoritmi di programmazione dinamica.

#1. Sottosequenza comune più lunga

È possibile che gli elementi della sottosequenza comune più lunga (LCS) appaiano in qualsiasi ordine all'interno delle sequenze originali; la LCS è definita come la sottosequenza più lunga comune a tutte le sequenze specificate.

Se sono fornite due sequenze S1 e S2, allora una sequenza Z che è una sottosequenza sia di S1 ​​che di S2 è chiamata la loro sottosequenza comune. Come ulteriore requisito, Z deve consistere in una sequenza strettamente ascendente degli indici degli insiemi S1 e S2.

Gli indici degli elementi selezionati in Z devono aumentare rigorosamente per formare una sequenza crescente.

#2. Algoritmo di Floyd-Warshall

Trovare il percorso più breve tra ogni coppia di vertici in un grafo pesato è l'obiettivo dell'algoritmo Floyd-Warshall. Questo metodo elabora grafici con pesi in entrambe le direzioni. D'altra parte, fallisce per i cicli in cui la somma dei loro archi è negativa.

L'algoritmo di Floyd, l'algoritmo di Roy-Floyd, l'algoritmo di Roy-Warhshall e l'algoritmo WFI sono tutti nomi dell'algoritmo di Floyd-Warhshall.

Questo algoritmo utilizza una tecnica di programmazione dinamica per individuare scorciatoie ottimali.

In che modo un algoritmo di programmazione dinamica risolve i problemi Lcs più velocemente di una tecnica ricorsiva?

La programmazione dinamica riduce l'overhead della chiamata di una funzione. Ricorda l'esito di ogni chiamata di funzione in modo che le chiamate successive possano utilizzare i dati memorizzati senza ripetere lo stesso lavoro.

Ogni volta che un elemento di X viene confrontato con un elemento di Y, i risultati vengono scritti in una tabella in modo che possano essere utilizzati nei calcoli successivi nel suddetto processo dinamico.

Pertanto, il runtime di un metodo dinamico è uguale al tempo necessario per riempire la tabella (O(mn)). Al contrario, la complessità dell'algoritmo ricorsivo è 2max(m, n). Inoltre, leggi Come scegliere il giusto tipo di algoritmo di crittografia per le tue esigenze aziendali

Quali sono i problemi di programmazione dinamica in Python

Utilizzando la programmazione dinamica, è possibile determinare la soluzione più appropriata a qualsiasi numero di diverse affermazioni del problema. Di seguito, esamineremo alcune delle famose dichiarazioni di problemi più frequentemente richieste e forniremo una breve spiegazione insieme al codice Python appropriato.

#1. Zaino (0-1) Rimbalzato

In questa situazione, ti vengono dati i prezzi e i pesi di N merci e hai il compito di inserirli in uno zaino di capacità W; l'obiettivo è ridurre al minimo il numero di articoli scelti pur inserendo tutto nello zaino.

La maggior parte dei colloqui tecnici per le organizzazioni di merci richiederà ai candidati di risolvere il problema dello zaino, che è un classico esempio di tecnica di programmazione dinamica.

Enunciato del problema Assumiamo di avere una borsa con capacità W e un elenco di cose, ognuna delle quali ha un peso e un profitto corrispondente. L'obiettivo è massimizzare i guadagni con un efficace cattivo riempimento.

La risposta è creare una tabella con colonne per ogni peso immaginabile compreso tra 1 e W e righe per i pesi effettivamente selezionati. Questa tabella sarà conosciuta come dp[][]. Se 'j' è la capacità dello zaino e sono inclusi i primi elementi 'i' nell'array peso/articolo, allora lo stato /cella dp[i][j] nella tabella indica il massimo profitto possibile.

Di conseguenza, il valore nella cella finale indicherà la soluzione. È importante mettere in valigia solo ciò che non superi il limite di peso dello zaino. Esistono due alternative al criterio “peso>peso[i-1]” in cui tutte le colonne possono essere riempite. 

#2. 0/1 Memoizzazione a zaino

Riempi una borsa con oggetti di peso e profitto noti, taglia K. Il tuo obiettivo è massimizzare i tuoi guadagni. Qui useremo la memoizzazione invece della tabulazione per vedere se possiamo risolvere il problema.

Il precedente problema dello zaino 0/1 utilizzava una strategia dal basso verso l'alto per scoprire una soluzione, mentre questo problema utilizza un approccio dall'alto verso il basso basato sulla memorizzazione per ottenere una soluzione.

La programmazione dinamica utilizza la memorizzazione per ridurre la necessità di risolvere più volte le stesse parti del problema. Ciò elimina la necessità di risolvere costantemente il problema secondario e semplifica il processo di generazione dell'output.

Enunciato del problema Assumiamo di avere una borsa con capacità W e un elenco di cose, ognuna delle quali ha un peso e un profitto corrispondente. Se la borsa è piena con la massima efficienza possibile, si può ottenere il massimo livello potenziale di profitto.

La soluzione è costruire prima un array bidimensionale per contenere le risposte finali ai singoli sottoproblemi. Le colonne della tabella elencheranno tutti i potenziali pesi tra 1 e W, suddividendolo in tante sezioni, e le righe mostreranno i pesi selezionati in ogni dato momento. 

Usiamo un array dp per tenere traccia di ogni sottoproblema risolto. Invece di risolvere un sottoproblema precedentemente risolto, restituiamo semplicemente la sua risposta.

#3. Problema di sottoinsieme uguale

Trova una partizione dell'insieme dato in modo tale che il totale degli elementi in entrambi i sottoinsiemi sia lo stesso usando la programmazione dinamica per risolvere il problema del sottoinsieme uguale. Oltre ai suoi altri nomi, il problema del sottoinsieme uguale (o problema della partizione) è un ottimo esempio del potere della programmazione dinamica.

Il compito a portata di mano ci richiede di dividere l'array arr a metà in modo che ciascuno dei sottoinsiemi risultanti abbia la stessa dimensione complessiva.

Come soluzione, dobbiamo costruire un array bidimensionale con dimensioni di (sum/2+1)*(target+1). Qui, i risultati della divisione dell'array originale possono essere memorizzati per ogni sottoinsieme e ogni somma, e successivamente recuperati. La prima dimensione dell'array rappresenterà i vari sottoinsiemi che possono essere creati, mentre la seconda dimensione dell'array rappresenterà le varie somme che possono essere calcolate combinando i sottoinsiemi.

Vantaggi della programmazione dinamica

Ecco alcuni dei vantaggi della programmazione dinamica.

#1. Rimedio efficace

La programmazione dinamica è un potente strumento per trovare soluzioni ottimali a problemi con sottostruttura ottimale e sottoproblemi sovrapposti. Scomponendoli in pezzi gestibili, queste sfide sono più facili da affrontare con il metodo. La Programmazione Dinamica è in grado di creare una soluzione ottimale evitando calcoli ripetitivi e riutilizzando le risposte ai sottoproblemi.

#2. Facilita la facile ricerca dei problemi

Risolvere un problema difficile può essere più facile scomponendolo prima in parti più semplici. Rende i problemi complessi più facili da affrontare suddividendoli in blocchi più gestibili. Questo metodo semplifica la soluzione e rende il problema più accessibile.

#3. Efficiente

Eliminando i calcoli non necessari e riciclando sottoproblemi risolti in precedenza, la Programmazione Dinamica può ridurre significativamente il tempo necessario per risolvere un problema. Quando i sottoproblemi si sovrappongono, il metodo può aiutare riducendo il numero totale di misure necessarie per risolvere il problema.

#4. Efficace quando un problema ha più soluzioni

La programmazione dinamica può aiutare a determinare quale delle diverse possibili spiegazioni è più probabile che sia il caso. Quando ci sono diverse opzioni praticabili per risolvere un problema, questo metodo può aiutarci a concentrarci su quello migliore.

Quali sono gli svantaggi della programmazione dinamica?

Ecco alcuni degli svantaggi della programmazione dinamica.

#1. Sotto-problemi che continuano a ripetersi

La programmazione dinamica funziona meglio quando il problema ha problemi secondari sovrapposti, il che potrebbe non essere sempre il caso. Non funzionerà e probabilmente non ti fornirà la soluzione migliore se i singoli problemi non si intersecano.

#2. Complicazione nel tempo e nello spazio

Se il problema è grande, la programmazione dinamica potrebbe richiedere molta memoria e spazio di archiviazione, il che aumenta la complessità temporale e spaziale della soluzione. Utilizzando la memoria, l'approccio memorizza i risultati provvisori in una tabella o in una tabella di memoizzazione.

#3. Quadro per il problema

Sebbene efficace per determinate strutture di problemi, la Programmazione Dinamica non è sempre la scelta migliore. Questo metodo funziona meglio quando il problema presenta problemi secondari sovrapposti, quindi potrebbe non essere applicabile ad altre situazioni.

#4. Difficile da mettere in pratica

 La programmazione dinamica richiede una conoscenza approfondita degli algoritmi e delle strutture dati, il che la rende difficile da implementare per i principianti. Il metodo richiede una riflessione preliminare e una profonda familiarità con il problema in questione.

Conclusione

In conclusione, la Programmazione Dinamica è un metodo efficace per trovare risposte, anche se sono preferibili altri approcci. È fondamentale conoscere i pro ei contro e scegliere il metodo giusto in base al problema in questione. Per problemi con sottostruttura ottimale e sottoproblemi sovrapposti, la Programmazione Dinamica può fornire una soluzione ottimale; tuttavia, questo metodo potrebbe non essere sempre applicabile. 

Sebbene sia difficile da sviluppare e utilizzi molta memoria, la sua capacità di semplificare il processo di risoluzione dei problemi e accorciare i tempi di calcolo lo rende una risorsa significativa per informatici e matematici.

Domande frequenti sulla programmazione dinamica

Qual è la differenza tra programmazione lineare e programmazione dinamica?

Per problemi di ottimizzazione lineare, abbiamo l'algoritmo di programmazione lineare (LP), e per generici problemi di ottimizzazione non lineare con vincoli non convessi, abbiamo la programmazione dinamica (DP), che garantisce l'ottimalità globale di una soluzione.

Quanto è difficile imparare la programmazione dinamica?

È risaputo che la programmazione dinamica è un argomento complesso, soprattutto per i nuovi arrivati ​​nel campo dell'informatica. Tuttavia, si può imparare facilmente la programmazione dinamica con una solida conoscenza dei principi fondamentali e un'ampia pratica.

La programmazione dinamica è molto difficile?

Sono difficili! Per iniziare, l'idea dei metodi di programmazione dinamica può essere difficile da comprendere. Qualsiasi programmatore esperto attesterebbe che la padronanza della DP richiede un notevole impegno di tempo. È inoltre necessaria l'abilità di scomporre un problema nelle sue parti costitutive e di riassemblarlo in un tutto lavorabile.

articoli simili

  1. GESTIONE DEL TEMPO DEL PROGETTO: processi, strumenti e software per una gestione efficace
  2. AMAZON SEO: come ottimizzare i tuoi prodotti per posizionarli meglio
  3. I LINGUAGGI DI PROGRAMMAZIONE PIÙ POPOLARI: Guida 2023
  4. CHE COS'È LA PROGRAMMAZIONE DEL COMPUTER: Esempi, tipi, corsi e software
  5. Testamenti online: i migliori produttori di testamenti online.

Riferimento

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati con *

Potrebbe piacerti anche