MATEMATICA III Programmazione Dinamica
Transcript
MATEMATICA III Programmazione Dinamica
Raffaele Pesenti MATEMATICA III dispense sulle lezioni di Programmazione Dinamica del Prof. Walter Ukovich giugno 1998 Consorzio Nettuno Università di Trieste Indice 1 INTRODUZIONE................................................................................................................................................... 3 1.1 1.2 1.3 1.4 1.5 2 FONDAMENTI ...................................................................................................................................................... 7 2.1 2.2 2.3 2.4 3 FORMULAZIONE DEL PROBLEMA .......................................................................................................................... 27 SOLUZIONE (PROCEDURA PROGRESSIVA).............................................................................................................. 29 SOLUZIONE (PROCEDURA REGRESSIVA)................................................................................................................ 31 L'ALGORITMO DI DIJKSTRA.................................................................................................................................. 33 PERCORSO MINIMO TRA TUTTE LE COPPIE DI NODI................................................................................................. 35 DOMANDE ED ESERCIZI ....................................................................................................................................... 38 ATTRIBUZIONE DI RISORSE........................................................................................................................... 40 6.1 6.2 6.3 7 IL PROCESSO DI SOLUZIONE DI UN PROBLEMA ....................................................................................................... 19 UN ESEMPIO: FORMULAZIONE .............................................................................................................................. 20 UN ESEMPIO: SOLUZIONE (PROCEDURA REGRESSIVA)............................................................................................ 22 UN ESEMPIO: SOLUZIONE (PROCEDURA PROGRESSIVA).......................................................................................... 24 SOLUZIONE COME PERCORSO MINIMO .................................................................................................................. 25 DOMANDE ED ESERCIZI ....................................................................................................................................... 26 PERCORSI SU GRAFI ........................................................................................................................................ 27 5.1 5.2 5.3 5.4 5.5 5.6 6 IL PRINCIPIO DI OTTIMALITÀ ............................................................................................................................... 12 CALCOLO RICORSIVO DEL COSTO ......................................................................................................................... 13 PROCEDURA REGRESSIVA DI SOLUZIONE .............................................................................................................. 14 STRATEGIA DI CONTROLLO OTTIMA...................................................................................................................... 15 PROCEDURA PROGRESSIVA .................................................................................................................................. 16 DOMANDE ED ESERCIZI ....................................................................................................................................... 17 SOLUZIONE DI UN PROBLEMA TRAMITE PROGRAMMAZIONE DINAMICA ...................................... 19 4.1 4.2 4.3 4.4 4.5 4.6 5 ELEMENTI DI UN SISTEMA DINAMICO ...................................................................................................................... 7 VALUTAZIONE DI UN SISTEMA DINAMICO ............................................................................................................... 8 FORMALIZZAZIONE DI UN PROBLEMA DI PROGRAMMAZIONE DINAMICA .................................................................. 9 DOMANDE ED ESERCIZI ......................................................................................................................................... 9 BASI TEORICHE................................................................................................................................................. 12 3.1 3.2 3.3 3.4 3.5 3.6 4 INTRODUZIONE ..................................................................................................................................................... 3 ESEMPIO: LA GESTIONE DELLE SCORTE................................................................................................................... 4 SCOPI E OBIETTIVI ................................................................................................................................................. 4 TESTI.................................................................................................................................................................... 5 DOMANDE ED ESERCIZI ......................................................................................................................................... 6 FORMULAZIONE DEL PROBLEMA .......................................................................................................................... 40 SOLUZIONE (PROCEDURA REGRESSIVA)................................................................................................................ 41 DOMANDE ED ESERCIZI ....................................................................................................................................... 42 SCORTE ............................................................................................................................................................... 45 7.1 7.2 7.3 7.4 7.5 7.6 7.7 RAGIONI DELLE SCORTE ...................................................................................................................................... 45 COSTI DELLE SCORTE .......................................................................................................................................... 46 DIMENSIONAMENTO DELLE SCORTE E TEMPIFICAZIONE DEGLI ORDINI ................................................................... 46 PROBLEMA DELLE SCORTE: FORMULAZIONE ......................................................................................................... 47 PROBLEMA DELLE SCORTE: SOLUZIONE ................................................................................................................ 48 ESEMPIO ............................................................................................................................................................. 49 DOMANDE ED ESERCIZI ....................................................................................................................................... 51 2 1 Introduzione 1.1 1.2 1.3 1.4 1.5 Introduzione Esempio: la gestione delle scorte Scopi e obiettivi Testi Domande ed esercizi 1.1 Introduzione Questo testo raccoglie e commenta le lezioni sulla Programmazione Dinamica svolte dal Prof. Walter Ukovich all’interno del corso di Matematica III. La Programmazione Dinamica è una metodologia matematica che si è sviluppata negli anni ‘50, principalmente ad opera di Richard Bellman. Essa permette di affrontare alcune classi di problemi in cui devono essere prese una serie di decisioni interdipendenti in sequenza. Programmare significa infatti: - pianificare, decidere attività future, - scrivere programmi per un calcolatore, - decidere per il meglio, ottimizzare, e, quindi, in matematica si parla di Programmazione Dinamica, Programmazione Lineare o, in generale, di Programmazione Matematica. Con il termine dinamico, invece, si intende che vi sono: - decisioni in sequenza, ripetute, - decisioni passate che influenzano quelle future. La Programmazione Dinamica permette di risolvere quei problemi che possono essere affrontati per stadi successivi. Essa si basa sul Principio di Ottimalità di Bellman1: "Una politica ottima ha la proprietà che, qualunque siano lo stato e le decisioni iniziali, l'insieme delle decisioni future devono costituire una politica ottima rispetto allo stato in cui si è giunti in base alle decisioni compiute fino al momento attuale." 1 Quanto segue è una libera traduzione da: R. Bellman: Dynamic Programming, Princeton, N.J, Princeton University Press 1957. 3 Si consideri, ad esempio, il percorso ottimo che unisce due località l0, ln. Il Principio di Ottimalità afferma che ogni sottopercorso compreso in esso, tra una qualunque località intermedia li e la finale ln, deve essere a sua volta ottimo (in generale ogni sottopercorso, che unisce una coppia di località intermedie, deve essere ottimo). Alla luce di tale principio la Programmazione Dinamica risolve un problema prendendo una decisione alla volta. Ad ogni passo essa determina la politica ottima per il futuro, indipendentemente dalle scelte passate, nell'ipotesi che anche queste ultime siano state compiute nel modo migliore. La Programmazione Dinamica è, quindi, efficacemente applicabile ogni qualvolta il problema originale può essere decomposto in un insieme di sottoproblemi di minore dimensione e quando il costo pagato (o il profitto ottenuto) è esprimibile come una somma di costi elementari, associati ad ogni singola decisione, eventualmente funzione dello stato. Più in generale il costo deve essere espresso, attraverso un qualche operatore, come composizione di costi elementari, ognuno dipendente da una singola decisione. 1.2 Esempio: la gestione delle scorte Nell'ipotesi che all'inizio di ogni giornata si possa decidere se e quanta merce ordinare, il costo complessivo della gestione delle scorte nell'arco di un dato periodo può essere espresso come somma dei costi elementari pagati ogni singolo giorno. In particolare questi ultimi costi hanno una componente variabile, legata al valore e/o alla quantità della merce in magazzino, ed una componente fissa, legata ad ogni emissione di un ordine di acquisto. Ogni giorno la decisione ottima è determinata dalla risposta alle seguenti domande: - conviene ordinare oggi, o rimandare l’ordine a domani? - (nel caso di risposta positiva alla prima domanda) quanto ordino oggi? Le risposte dipendono da quanto si ha in deposito, il che è funzione di quanto si è ordinato il giorno prima, e del rapporto tra il peso della componente fissa e di quella variabile dei costi. A seconda del valore di tale rapporto può, infatti, convenire emettere tanti ordini di piccola dimensione o, viceversa, mantenere molta merce a magazzino. La decisione corrente è condizionata dalle scelte passate ed influenza quelle future, ma, in ogni caso, il costo pagato per essa può essere espresso in termini della sola quantità di merce attualmente in deposito e dell'eventuale emissione di un nuovo ordine. 1.3 Scopi e obiettivi Lo scopo di questo testo è di introdurre alcuni dei concetti base che permettono l'applicazione della Programmazione Dinamica nella sua versione più elementare, applicata cioè a sistemi discreti e deterministici, su orizzonte temporale finito. A tal fine sono proposti anche alcuni esempi che hanno applicazione nel modo reale e che, al contempo, sono facilmente trattabili dal punto di vista matematico. 4 Questo testo è organizzato come segue: nei prossimi due capitoli sono introdotte le nozioni teoriche necessarie per una corretta comprensione ed applicazione della Programmazione Dinamica; nei capitoli rimanenti sono discussi alcuni esempi di applicazione di suddetta metodologia. Lo studente dovrebbe cercare di fare proprio il metodo di ragionamento utilizzato nella Programmazione Dinamica, piuttosto che memorizzare meccanicamente concetti e risultati. Per questo motivo è opportuno che, al termine di ogni capitolo, lo studente verifichi mentalmente la comprensione di quanto presentato e cerchi di rispondere alle domande e agli esercizi proposti. Obiettivo del corso e di questo testo è mettere lo studente in condizione di: − capire quando applicare la Programmazione Dinamica sfruttandone le caratteristiche e le proprietà; − risolvere semplici problemi reali facilmente riconducibili a quelli presentati nel testo; − usare criticamente la Programmazione Dinamica per affrontare problemi nuovi, non trattati esplicitamente nelle lezioni. 1.4 Testi Testo di riferimento F.S. Hillier, G.J. Lieberman: Introduction to Operations Research, quinta edizione, McGraw-Hill 1990, capitolo 11 (Dynamic Programming). Altri testi di consultazione - E. Denardo: Dynamic Programmig in: J.J. Moder, S.E. Elamghraby: Handbook of Operations Research I, van Nostrand 1978. - D. Bertsekas: Dynamic Programming and Optimal Control, Athena Scientific 1995. Il testo di Hillier e Lieberman è introduttivo e di facile lettura. Il capitolo di Denardo è un'utile sintesi, può servire di ripasso a chi ha già una minima conoscenza di base. Il terzo testo è certamente il più completo. Bertsekas è, infatti, forse l'autore correntemente più importante per quanto riguarda la Programmazione Dinamica, i suoi libri, anche se avanzati, sono comunque di facile lettura. Il testo di Hillier e Lieberman può essere utilizzato per una semplice introduzione alle applicazioni della Programmazione Dinamica a sistemi stocastici. Il testo di Bertsekas può servire per l'approfondimento di tali tematiche, ma è soprattutto fondamentale del nel caso si voglia applicare la Programmazione Dinamica su orizzonti temporali di cui non sia fissata a priori la lunghezza. I risultati più recenti riguardanti la Programmazione Dinamica e le sue applicazioni sono pubblicati su riviste scientifiche. Tali riviste, generalmente disponibili nelle biblioteche delle 5 Università italiane, afferiscono ai settori di: Ricerca Operativa, Controlli Automatici, Economia, solo per citarne alcuni. 1.5 Domande ed esercizi 1. Spiegare in che senso il Principio di Ottimalità garantisce l'indipendenza delle decisioni future da quelle compiute al passo corrente. 2. Presentare esempi di applicazione del Principio di Ottimalità. 3. Descrivere l'algoritmo, che implicitamente si utilizza, per raggiungere un luogo dove non si è mai stati in precedenza, ma che si trova vicino a località già note. 4. Descrivere l'algoritmo, che implicitamente si utilizza, per costruire un meccanismo costituito da tanti sottocomponenti relativamente autonomi. 5. Descrivere il criterio con cui si decide che quantità comperare di ogni prodotto quando si fa la spesa (al supermercato, sotto casa, ecc.). 6 2 Fondamenti 2.1 2.2 2.3 2.4 Elementi di un sistema dinamico Valutazione di un sistema dinamico Formalizzazione di un problema di Programmazione Dinamica Domande ed esercizi In questo capitolo sono introdotti i concetti fondamentali per trattare sistemi dinamici deterministici, in cui quindi tutto è noto senza incertezze, che evolvono in tempo discreto, ovvero in cui le decisioni sono prese in istanti predeterminati, e.g., all'inizio della giornata o alla fine di ogni mese. 2.1 Elementi di un sistema dinamico Gli elementi che consentono di definire un sistema dinamico a tempo discreto e la sua evoluzione sono: - gli istanti temporali o stadi, ovvero i momenti in cui vengono prese le decisioni; - il controllo, ovvero l'insieme informativo che permette di descrivere i termini delle decisioni prese nel tempo; - le quantità esogene, ovvero quelle quantità non controllabili che comunque influenzano l'evoluzione del sistema; - lo stato, ovvero l'insieme informativo minimo che, in un dato istante temporale, permette di conoscere l'evoluzione futura del sistema stesso, una volta note le realizzazioni dei controlli e delle azioni esogene; - la funzione di trasformazione dello stato, ovvero la legge, anche tempovariante, che descrive l'evoluzione del sistema. Tale legge, in funzione dello stato corrente, del controllo applicato e delle azioni esogene, permette di determinare lo stato che verrà raggiunto nell'istante temporale successivo. Questi elementi sono rappresentati matematicamente tramite i valori assunti dalle seguenti variabili o funzioni: - la variabile discreta tempo t, t∈ [0,Τ], dove T è detto orizzonte del problema; - le variabili di controllo u(t), u(t)∈U(t), dove U(t) è l'insieme dei controlli ammissibili; - le variabili esogene z(t), z(t)∈Z(t), dove Z(t) è l'insieme delle quantità esogene che si possono presentare; - le variabili di stato x(t), x(t)∈X(t), dove X(t) è l'insieme degli stati ammissibili; - la funzione di trasformazione dello stato f, f:X×U×Z×N→X, tale che: x(t+1)=f(x(t),u(t),z(t),t). (2.1) 7 Nel problema di gestione delle scorte, introdotto nel capitolo precedente, le singole giornate sono gli istanti temporali, l'entità dell'ordine emesso all'inizio di ogni giornata è il valore del controllo, la domanda che deve essere soddisfatta corrisponde alle quantità esogene, il livello delle scorte all'inizio della giornata è lo stato del sistema e, infine, la legge di conservazione dei flussi delle merci definisce la funzione di trasformazione dello stato. Tale funzione deve imporre che il livello di magazzino x(t+1) all'istante successivo dipenda dal livello attuale x(t), dalla domanda da soddisfare z(t) e dalla dimensione dell'ordine effettuato all'inizio della giornata u(t), secondo, ad esempio, la seguente equazione: x(t+1)=x(t)+u(t)-z(t). (2.2) In merito sempre allo stesso problema si deve osservare che sia il controllo sia lo stato possono essere soggetti a vincoli fisici o contrattuali. Molto spesso, infatti, i lotti ordinati possono assumere solo alcune dimensioni prefissate, mentre il livello delle scorte deve ovviamente essere non negativo e non eccedere le dimensioni massime del magazzino. Nel decidere il controllo ottimo si deve infine tenere conto che la domanda è nota a priori nel caso deterministico, mentre è al più descritta attraverso una distribuzione di probabilità nel caso stocastico. 2.2 Valutazione di un sistema dinamico L'evoluzione di un sistema dinamico è valutata in termini di costi (o di profitti). Questi ultimi, che possono essere tempovarianti, in generale dipendono: dagli stati assunti dal sistema, dalle azioni di controllo adottate e dalle quantità esogene. Ad esempio nel caso di gestione delle scorte sono presenti sia costi funzione dello stato, i costi di mantenimento, che i costi funzione del controllo, i costi di rifornimento. La Programmazione Dinamica, come già anticipato nell'introduzione, può essere efficacemente applicata ogni qualvolta il costo (o il profitto) complessivo è decomponibile. In altre parole il costo complessivo deve essere espresso come composizione di costi elementari pagati separatamente in base a ogni singola decisione presa e agli stati raggiunti. In questo contesto, nel seguito, si ritiene che possa essere definita una funzione di costo, g:X×U×Z×N→X, che esprima il costo (elementare) pagato all'intraprendere l'azione di controllo u(t) al tempo t, quando lo stato vale x(t) e le variabili indipendenti valgono z(t). Per semplicità si assume che il costo sia additivo, cioè che il costo complessivo nell'intervallo di tempo [0,T] sia dato dalla somma di tutti i costi elementari g(x(t),u(t),z(t),t), per t=0,1,…,T-1, ed eventualmente un costo g(x(T),T) legato allo stato finale raggiunto. Il costo complessivo è, quindi, espresso dal seguente valore T −1 ∑ g( x( t ),u( t ), z( t ),t ) + g( x( T ),T ) . (2.3) t =0 In molti casi applicativi il valore finale dello stato è imposto dal problema, quindi la componente di costo g(x(T),T) può essere omessa poiché indipendente dalle decisioni intraprese. In seguito si 8 ipotizza che si verifichino sempre tali condizioni, che quindi siano dati sia lo stato iniziale x0 che lo stato finale xT. In ogni modo non dovrebbe essere difficile per il lettore generalizzare i risultati alle situazioni in cui una pluralità di stati finali siano ammissibili. 2.3 Formalizzazione di un problema di Programmazione Dinamica Alla luce di quanto visto fino a questo momento si può ritenere che un problema sia affrontabile per mezzo della Programmazione Dinamica quando può essere enunciato come segue: Formulazione canonica: Dati un orizzonte temporale T e un sistema dinamico, ovvero: - i vincoli di stato X(t) e di controllo U(t); - la sequenza z(t); - le funzioni di transizione dello stato f e di costo (addittivo) g; - i valori iniziale x0=x(0) e finale xT=x(T) dello stato; determinare, rispetto a tutte le sequenze di controlli u(t) ammissibili, la sequenza ottima u*(t) che minimizza il costo complessivo. Nei prossimi capitoli sono presentati, formalizzati e risolti, alcuni dei problemi classicamente affrontati con la Programmazione Dinamica. 2.4 Domande ed Esercizi 2.1 Un pezzo meccanico dev’essere sottoposto a tre successive operazioni, ciascuna operazione può essere effettuata in uno di quattro centri (o macchine) diversi. Il costo di ogni operazione dipende dal centro in cui essa viene eseguita e dal centro in cui è stata effettuata l’operazione precedente. Si vuole determinare su quale centro effettuare ciascuna operazione in modo da minimizzare il costo complessivo. Formulare il problema in modo canonico. (per soluzione vedi Cap. 4) tabelle dei costi centro 1 35 prima operazione 2 3 40 4 30 54 9 centro attuale 1 2 1 105 100 2 90 85 centro precedente 3 100 90 4 110 105 seconda operazione 3 4 85 100 95 120 90 95 105 110 centro attuale 3 4 1 1 70 2 85 centro precedente 3 90 4 80 terza operazione 2 75 90 70 85 85 80 85 90 80 95 80 75 2.2 Una ditta che lavora su commessa deve pianificare la propria produzione per la prossima settimana. Tale ditta ha a disposizione 4 ordini e considera lavorativi tutti sette i giorni. La produzione di ogni ordine può essere interrotta con profitto al termine di ogni giornata e fatta completare da altre ditte in subappalto con conseguente variazione dei profitti. Ogni ordine non richiede più di quattro giorni di lavorazione e i profitti ottenibili da ogni commessa sono presentati nella tabella seguente. Massimizzare il profitto complessivo. Formulare il problema in modo canonico. tabella dei profitti commessa A B C 0 0 0 0 1 6 10 5 giorni lavorazione 2 10 10 8 3 12 12 15 4 15 20 17 D 0 11 15 18 20 2.3 Un candidato ad una alta carica pubblica deve decidere che aree visitare negli ultimi 5 giorni della sua campagna elettorale. Più a lungo il candidato è presente in una zona, maggiore è l'incremento del numero di voti che si attende di ricevere dagli abitanti del posto. Massimizzare l'incremento complessivo del numero di voti che riceverà il candidato. Formulare il problema in modo canonico. 10 tabella dell'incremento dei voti attesi (in migliaia) zona A B C D 0 0 0 0 0 1 7 6 5 4 2 8 11 8 9 giorni di soggiorno 3 9 15 14 10 4 10 15 14 11 5 10 15 14 12 11 3 Basi teoriche 3.1 Il Principio di Ottimalità 3.2 Calcolo ricorsivo del costo 3.3 Procedura regressiva di soluzione 3.4 Strategia di controllo ottima 3.5 Procedura progressiva di soluzione 3.6 Domande ed esercizi In questo capitolo sono introdotte le basi teoriche della Programmazione Dinamica. In particolare oltre al Principio di Ottimalità, enunciato a parole nell'introduzione, sono presentate le procedure ricorsive progressive e regressive utilizzate nella soluzione dei problemi. 3.1 Il Principio di Ottimalità Dato un sistema dinamico e un orizzonte temporale T, si definisce traiettoria l'insieme degli stati x(t) assunti dal sistema, a partire dallo stato iniziale x(0) = x0, in funzione delle azioni di controllo intraprese e dell'equazione di transizione dello stato. Inoltre si definisce ammissibile una sequenza di controlli u(t), con u(t)∈U(t), per ogni t=0,1,...,T-1, che produca una traiettoria x(t) per cui x(t)∈X(t), per ogni t=0,1,...,T-1, e x(T)=xT. I concetti di traiettoria e controlli ammissibili sono alla base del Principio di Ottimalità. Principio di Ottimalità: Si consideri un sistema dinamico lungo un orizzonte temporale [0,T]. Sia u*(t) la sequenza ottima dei controlli e x*(t) la relativa traiettoria ottima. Si consideri quindi un relativo sottoproblema con: - orizzonte: da t’ a t”, con 0≤t’<t”≤T - stato iniziale: x’=x*(t’) - stato finale: x”=x*(t”). Le sequenze u*(t) e x*(t) del problema originale sono ottime anche per il sottoproblema, se considerate per t=t’,t’+1,t’+2,...,t”-1. La dimostrazione del Principio di Ottimalità può essere data per assurdo. Si assuma che per il sottoproblema esista un controllo ammissibile u'(t) che produca una traiettoria x'(t) (vedi fig.3.1) da x’ a x” migliore di x*(t), per t=t’,t’+1,t’+2,...,t”-1, allora, in riferimento al problema originale, esisterebbe un controllo ammissibile che conduce ad una nuova traiettoria ottenuta dalla giustapposizione delle sottosequenze x*(t), per t=0,1,...,t'-1, x'(t), t=t’,t’+1,...,t”-1, x*(t), per t=t”,t”+1,...,T-1. La nuova traiettoria, poiché i costi sono addittivi, sarebbe migliore di x*(t), per t=0,1,2,...,T-1, ma questo è in contraddizione con l'ottimalità di x*(t). Ne consegue che l'ipotesi che esista x'(t) è falsa. 12 x*(T) x*(t” ) x*(t) x” x*(t’) x*(0) x’(t) x’ Fig. 3.1: traiettorie nello spazio degli stati Il Principio di Ottimalità viene sfruttato dalla Programmazione Dinamica per calcolare la politica di controllo ottimo in modo ricorsivo. 3.2 Calcolo ricorsivo del costo Dato un problema di programmazione dinamica, con stato iniziale x0, si definisca F(x0,0) il costo minimo cumulato da pagare sull'orizzonte temporale da 0 a T: T −1 F(x 0 ,0 ) = min ∑ g(x(k),u(k),z(k),k) . u(k)∈U (3.1) k =0 Si noti che la conoscenza del valore di F(x0,0) corrisponde ovviamente alla soluzione del problema. In generale si definisca F(x,t) costo minimo del sottoproblema su orizzonte [t,T] quando lo stato iniziale vale x: T −1 F(x,t) = min ∑ g(x(k),u(k),z(k),k) . u(k)∈U (3.2) k =t Il costo addittivo, la funzione di trasformazione dello stato ed il Principio di Ottimalità permettono di riscrivere la (3.2) come: F(x,t) = min{ g(x,u,z(t),t ) + F(f ( x , u , z( t ),t),t + 1 )} . u∈U (3.3) 13 In particolare l'equazione (3.3) deve essere interpretata nel modo seguente: poiché il costo su orizzonte [t,T] a partire dallo stato x risulta essere la somma del costo g(x,u,z(t),t) pagato all'istante attuale t, e del costo complessivo residuo F(x(t+1),t) che si deve pagare a partire dallo stato che si raggiunge in t+1, ne consegue che, per trovare il costo minimo F(x,t) da t a T, si deve compiere il passo da t a t+1 scegliendo il punto d’arrivo x(t+1)=f(x,u,z(t),t) in modo da minimizzare la somma di queste due componenti. In linguaggio matematico le equazioni come (3.3) sono dette ricorsive. In tali equazioni la stessa funzione, e.g., F(.,.), compare, con argomenti diversi, sia a destra che a sinistra del segno di eguale e deve essere calcolabile in tutto lo spazio in cui è definita, X×T nel caso di F(.,.), a partire dalla conoscenza dei valori assunti in alcuni punti di riferimento. Il concetto di ricorsione formalizza il comportamento tipico del matematico che cerca di risolvere un problema riconducendosi ad uno risolto in precedenza. Un elementare esempio di ricorsione è il seguente modo di definire i numeri fattoriali: 0!=1; n!=n(n-1)!. Noto il fattoriale di zero, è possibile conoscere il fattoriale di qualunque numero naturale a partire dal fattoriale del numero precedente. 3.3 Procedura regressiva di soluzione L'equazione ricorsiva (3.3) è alla base della Programmazione Dinamica poiché permette di calcolare il valore di F(x,t), se sono noti i valori di F(x’,t+1) in corrispondenza di ogni valore di x’. A partire da questa osservazione in seguito è presentata una procedura regressiva, o all’indietro (backward), che ricava la funzione di costo cumulato F(x0,0). In particolare il valore di F(x0,0) è determinato procedendo iterativamente all’indietro nel tempo a partire dall'istante finale. Al tempo T, per le ipotesi formulate nel capitolo precedente, F(x,T)=0 per x=xT F(x,T)=∞ per x≠xT . Noto il valore di F(.,.) in T è possibile ricavare F(.,.) in T-1dall’equazione ricorsiva (3.3): F(x,T − 1 ) = min{ g(x,u,z(T − 1 ),T − 1 ) + F(f ( x , u , z( t ),t),T )} . u∈U (3.4) In particolare se, per ogni stato ammissibile x in T-1, u*(x(T-1)) è un controllo a costo minimo che quando applicato conduce il sistema nello stato xT , i.e., xT = f(x,u*(x(T-1)),z(T-1),T-1), allora F(x,T-1) può essere scritto come: F(x,T-1)=g(x,u*(x(T-1)),z(T-1),T-1)+F(f(x,u*(x(T-1)),z(T-1),T-1),T)= =g(x,u*(x(T-1)),z(T-1),T-1)+ F(xT,T)=g(x,u*(x(T-1)),z(T-1),T-1)+0. (3.5) 14 Si osservi che in (3.5) il costo F(x,T-1) è solo funzione dello stato assunto in T-1. Noto F(.,.) al passo T-1, si può ricavare il controllo, e quindi il costo F(.,.), al passo T-2: F(x,T − 2 ) = min{ g(x,u,z(T − 2 ),T − 2 ) + F(f ( x , u , z( t ),t),T − 1 )} u∈U (3.6) In questo caso se, per ogni stato ammissibile x in T-2, u*(x(T-2)) è un controllo per cui è minima la somma tra il costo g(x,u*(x(T-2)),z(T-2),T-2), pagato all'istante corrente, e il costo residuo F(f(x,u*(x(T-2)),z(T-2),T-2),T-1), che rimane da pagare che quando il sistema raggiunge lo stato successivo, allora F(x,T-2) può essere scritto come: F(x,T-2)=g(x,u*(x(T-2)),z(T-2),T-2)+F(f(x,u*(x(T-2)),z(T-2),T-2),T-1). (3.7) Anche il costo F(x,T-2) può essere calcolato in base al solo stato assunto dal sistema in tale istante. Infatti il costo attuale, g(x,u,z(T-2),T-2), dipende da x, u e z(T-2), ma non dagli stati o controlli precedenti o futuri, mentre il costo residuo, F(x(T-1),T-1), dipende dallo stato assunto in T-1 che però è esprimibile in funzione di x, u e z(T-2). Ripetendo il ragionamento, ad ogni iterazione, si possono ricavare F(x,T-3),...,F(x,0) tramite il calcolo del controllo ottimo, ovvero il valore di u che corrisponde al minimo in (3.3). La procedura regressiva è stata presentata in modo da procedere per valori decrescenti del tempo trascorso t, ma un semplice cambio di variabile permette di ragionare per valori crescenti del tempo rimanente (anche detto time-to-go), t’=T-t. In entrambi i casi la procedura permette di ricavare la funzione F(x,t) per tutti i valori di x e t, ovvero qualunque sia lo stato e l'istante iniziale del problema in considerazione (questa proprietà è detta principio dell’invariant embedding). Il valore F(x0,0) cercato è quindi solo un caso particolare di quanto ottenuto. L'informazione a cui si perviene è in realtà molto più ricca e permette di definire una "strategia di controllo" ottima. 3.4 Strategia di controllo ottima Una qualunque funzione φ, φ:X×T→U, che restituisce il valore di un possibile controllo a partire dallo stato e dall'istante attuale: u=φ(x(t),t) (3.8) è detta strategia o politica di controllo. In pratica una politica di controllo è ciò che indica che decisione prendere qualunque sia il valore dello stato. Per quanto riguarda la Programmazione Dinamica l'equazione ricorsiva determina non solo la sequenza ottima dei controlli per il problema oggetto di considerazione, ma anche, più in generale, una anche strategia ottima φ*: u*(t)=φ*(x(t),t). (3.9) 15 Infatti la soluzione dell’equazione ricorsiva (3.3) fornisce, per ogni valore di x e t, il controllo ottimo u* da applicare. La politica di controllo φ*, determinata attraverso la (3.3), è utile quando, a causa di disturbi od imprecisioni del modello, lo stato del sistema evolve in modo diverso da quello previsto. In questi casi φ* fornisce lo stesso indicazioni sulle scelte da compiere e queste indicazioni, nella speranza che gli errori modellistici siano sufficientemente piccoli, non dovrebbero discostarsi molto da quelle realmente ottime. 3.5 Procedura progressiva Nel Paragrafo precedente è stata presentata una procedura regressiva di soluzione dei problemi di Programmazione Dinamica, viceversa in questo paragrafo viene presentata una procedura progressiva basata su un'equazione ricorsiva in avanti (forward). Dato un problema di Programmazione Dinamica, si definisce funzione di costo minimo cumulato in avanti la funzione G(x,t). Essa rappresenta il costo pagato fino ad un determinato istante temporale t. In particolare G(x,t) è la soluzione del sottoproblema che ha orizzonte [0,t] e stato finale x: t G(x,t) = min ∑ g(x(k),u(k),z(k),k) . u(k)∈U (3.10) k =0 Determinare il valore G(xT,0) corrisponde quindi a risolvere il problema originale. Il costo addittivo, la funzione di trasformazione dello stato ed il principio del massimo permettono di riscrivere la (3.10) come: G(x + 1,t) = min{ G( y ,t ) + g(x,u,z(t),t ) |u : f ( y ,u , z( t ),t),t ) = x } . y∈ X (3.11) In particolare l'equazione (3.11) deve essere interpretata nel modo seguente: poiché il sistema, a partire da x0 al tempo 0, giunge in x al tempo t+1 passando per lo stato intermedio y al tempo t, tale stato y deve essere scelto in modo da minimizzare la somma del costo pagato fino al suo raggiungimento e del costo attuale. L'equazione (3.11) permette di calcolare il valore di G(xt+1), se sono noti i valori di G(y,t) in corrispondenza di ogni y. Essa può quindi essere risolta con una ricorsione progressiva, procedendo in avanti nel tempo, a partire dalla seguente inizializzazione: G(x,1)=g(x0,u,z(0),0) con u:f(x0,u,z(0),0)=x. (3.12) 16 In altre parole, per raggiungere lo stato generico x al tempo 1, si deve pagare solo il costo legato al fatto che ci si trova nello stato x0 al tempo 0 e che viene applicato il controllo a costo minimo che permette una transizione di stato da x0 a x. Determinata l'espressione di G(y,1), la si inserisce nell’equazione ricorsiva (3.11) e ricava G(x,2). Si prosegue quindi fino ad arrivare a G(xT,T). Con la ricorsione in avanti si ricava la funzione G(x,t) per tutti i valori di x e t, si determina, quindi, la soluzione del problema oggetto di considerazione per qualunque orizzonte temporale non superiore a T e qualunque stato finale raggiungibile. 3.6 Domande ed Esercizi 3.1 Scrivere le equazioni ricorsive regressiva e progressiva del costo per il problema presentato nell'Esercizio 2.1. 3.2 Scrivere le equazioni ricorsive regressiva e progressiva del costo per il problema presentato nell'Esercizio 2.2. 3.3 Scrivere le equazioni ricorsive regressiva e progressiva del costo per il problema presentato nell'Esercizio 2.3. 3.4 Si devono eseguire quattro successive lavorazioni, ciascuna lavorazione può essere effettuata in uno di quattro centri diversi. Il costo di ogni lavorazione dipende dal centro in cui essa viene eseguita e dal centro in cui è stata effettuata la lavorazione precedente. Si vuole determinare su quale centro effettuare ciascuna lavorazione in modo da minimizzare il costo complessivo. Formulare il problema in modo canonico e scrivere le equazioni ricorsive regressiva e progressiva. tabelle dei costi centro 1 2 17 prima lavorazione centro attuale 1 1 51 2 45 centro precedente 3 52 4 60 seconda lavorazione 3 20 2 4 16 3 54 44 45 58 25 4 43 52 42 63 48 48 53 59 17 centro attuale 1 1 140 2 170 centro precedente 3 180 4 190 terza lavorazione 2 150 185 139 168 3 170 164 170 182 4 160 188 162 155 centro attuale 2 3 4 1 1 80 2 95 centro precedente 3 100 4 90 quarta lavorazione 85 100 80 95 95 90 95 90 90 105 90 95 18 4 Soluzione di un problema tramite Programmazione Dinamica 4.1 Il processo di soluzione di un problema 4.2 Un esempio: formulazione 4.3 Un esempio: soluzione (procedura regressiva) 4.4 Un esempio: soluzione (procedura progressiva) 4.5 Soluzione come percorso minimo 4.6 Domande ed esercizi In questo capitolo, attraverso la discussione di un esempio, viene presentata la maniera in cui è usualmente risolto un problema di Programmazione Dinamica. 4.1 Il processo di soluzione di un problema In generale il processo di risoluzione di un problema avviene per fasi e può essere schematizzato come segue: Realtà Analisi Problema Formulazione Modello Risoluzione algoritmica Soluzione Ridefinizione Fig. 4.1: Fasi di soluzione di un problema All'interno delle realtà produttive o di servizio il management ha la percezione dell'esistenza di problemi, ma spesso non riesce a focalizzarli. Per superare tali difficoltà è necessaria quindi una prima fase di analisi, che conduce a precisare il problema di interesse per la realtà in cui si opera. Nella fase di analisi si determinano gli elementi del problema attraverso l'individuazione degli attori decisionali e dei loro poteri (variabili decisionali), degli obiettivi, dei vincoli e dei disturbi esterni. A questa prima fase segue quella di formulazione del problema, durante la quale viene sviluppato un modello logico/matematico del problema reale. Segue poi la fase di risoluzione algoritmica, dove vengono determinate le soluzioni del problema applicando algoritmi logico/matematici al modello sviluppato nella fase precedente. Ovvie ragioni economiche impongono infine che, una volta determinata la soluzione, i risultati vengano applicati. In realtà pochi problemi, però, possono ritenersi risolti in via definitiva attraverso una singola esecuzione delle attività associate alle fasi di 19 soluzione appena descritte. Occorre, infatti, spesso ridefinire alcuni elementi del problema. Tale fase di ridefinizione è, in generale, motivata da nuove conoscenze sul sistema dovute ai nuovi dati raccolti a seguito di difficoltà insorte nella formulazione modello matematico oppure durante il primo tentativo di applicazione delle soluzioni ottenute. Durante la ridefinizione del problema vengono spesso modificate le ipotesi riguardanti sia le possibilità decisionali degli attori coinvolti che i vincoli del sistema. Il processo di risoluzione di un problema può ciclare più volte attraverso le differenti fasi; la presenza di una fase di ridefinizione permette di individuare soluzioni sempre migliori. All'interno del processo sopradescritto, se la formulazione del modello matematico del problema è strutturata in modo canonico, la Programmazione Dinamica può essere uno strumento utilizzato per la risoluzione algoritmica. 4.2 Un esempio: formulazione Dall'analisi della lavorazione cui è soggetto un componente meccanico è emerso il seguente problema: Problema di sequenziazione (descrizione a parole) Un pezzo meccanico dev’essere sottoposto a tre successive operazioni, ciascuna operazione può essere effettuata in uno di quattro centri (o macchine) diversi. Il costo di ogni operazione dipende dal centro in cui essa viene eseguita e dal centro in cui è stata effettuata l’operazione precedente. Minimizzare il costo complessivo determinando su quale centro effettuare ciascuna operazione. tabelle dei costi centro 1 35 prima operazione centro attuale 2 3 40 1 2 1 105 100 2 90 85 centro precedente 3 100 90 4 110 105 seconda operazione 4 30 54 3 4 85 100 95 120 90 95 105 110 20 centro attuale 1 1 70 2 85 centro precedente 3 90 4 80 terza operazione 2 3 75 90 70 85 4 85 80 85 90 80 95 80 75 Nel problema in oggetto si devono prendere tre decisioni successive circa quale centro adoperare per ciascuna operazione. L'orizzonte temporale è, quindi, costituito dai tre istanti [0,1,2] in cui si compiono le scelte e dall'istante finale, t=3, in cui si giunge dopo l'ultima decisione. Ovviamente nessun controllo è attuato in t=3, mentre, in ogni altro ogni istante temporale, il valore delle variabili di controllo non può che corrisponde al centro scelto per la prossima lavorazione. Indicati con i numeri dall'1 al 4 i centri di lavoro, u(t) deve, quindi, appartenere all'insieme {1,2,3,4}, per t=0,1,2. Le variabili di stato devono contenere tutte le informazioni che permettono di descrivere l'evoluzione del sistema ed, in particolare, una volta deciso il controllo, devono permettere di valutare i costi. Di conseguenza una possibile scelta è che, ad ogni istante diverso da quello iniziale, il valore delle variabili di stato corrisponda al centro in cui viene effettuata la lavorazione corrente, x(t)∈{1,2,3,4}, per t=1,2,3. Il valore dello stato iniziale è, invece, quello nullo, x(0)=0, dove 0 indica l'assenza di lavorazioni sul pezzo. In questo contesto l'equazione di transizione dello stato non può che imporre che lo stato successivo (il centro su cui si effettua la prossima operazione) sia semplicemente eguale al controllo, x(t+1)=u(t), per t=0,1,2. Alla luce delle precedenti considerazioni il problema, prima enunciato a parole, può essere formalizzato matematicamente nel modo seguente: Problema di sequenziazione (formulazione canonica): Dati: - orizzonte: t=0,1,2,3, T=3 stato x(t): x(t)∈X(t) con X(0)={ 0} e X(t)={1,2,3,4}, per t=1,2,3; controllo u(t): u(t)∈U(t) con U(t)={1,2,3,4}, per t=0,1,2; variabili esogene z(t): non necessarie; funzione di transizione dello stato f(x,u,z,t): x(t+1)=u(t), per t=0,1,2; - costo: g(x(t),u(t),t)=c(i,j,t), per t=0,1,2; con: i : stato attuale j : controllo attuale c : matrice dei costi. costo complessivo: c(0,u(0),0)+c(u(0),u(1),1)+c(u(1),u(2),2). Determinare la sequenza ottima di controlli u*(t). Date le tabelle dei costi indicate in precedenza, i valori dei parametri c(i,j,t) risultano essere: 21 matrici dei costi t=0 t=1 controllo: u(0)=j stato: x(0)=i controllo: u(1)=j stato: x(1)=i t=2 controllo: u(2)=j stato: x(2)=i 1 2 3 0 35 c(i,j,0) 40 1 1 105 2 90 3 100 4 110 c(i,j,1) 2 100 85 90 105 1 1 70 2 85 3 90 4 80 c(i,j,2) 2 75 90 70 85 4 30 45 3 4 85 100 95 120 90 95 105 110 3 85 80 85 90 4 80 95 80 75 4.3 Un esempio: soluzione (procedura regressiva) Il costo del problema in esame può essere espresso in forma ricorsiva. In particolare l'equazione ricorsiva (regressiva) generale: F(x,t)=minu{ g(x,u,z(t),t)+F(f(x,u,z(t),t),t+1)} diventa nel caso di interesse: F(i,t)=minj{c(i,j,t)+F(j,t+1)}. (4.1) Lo stato finale del sistema x(3) può essere un qualunque valore di X(3)={1,2,3,4}, in ogni caso il costo pagato in t=3 è nullo: F(i,3)=0 per i=1,2,3,4. (4.2) Noto F(.,.) per t=3 si ricava F(.,.) per t=2 dall’equazione ricorsiva (4.1) F(i,2)=minj{c(i,j,2)+F(j,3)} (4.3) 22 l’indice j relativo al minimo fornisce la politica ottima φ∗(i,t)=j. In particolare F(1,2)=minj{c(1,j,2)+F(j,3)}=min{70+0,75+0,85+0,80+0}=70 F(2,2)=minj{c(2,j,2)+F(j,3)}=min{85+0,90+0,80+0,95+0}=80 F(3,2)=minj{c(3,j,2)+F(j,3)}=min{90+0,70+0,85+0,80+0}=70 F(4,2)=minj{c(4,j,2)+F(j,3)}=min{80+0,85+0,90+0,75+0}=75 : : : : φ∗(1,2)=1; φ∗(2,2)=3; φ∗(3,2)=2; φ∗(4,2)=4; (4.4a) (4.4b) (4.4c) (4.4d) Si consideri ad esempio l'equazione (4.4a). In essa F(1,2) indica che, se si giunge nello stato 1 all'istante 2, il costo minimo residuo da pagare è di 70 e tale costo può essere ottenuto applicando il controllo φ∗(1,2)=1. Noto F(.,.) per t=2 si ricava F(.,.) per t=1, infine il costo ottimo F(0,0). Il seguente schema riassume tutte le operazioni da compiere: Procedura regressiva: t=3 i F(i,3) 1 0 2 0 3 0 4 0 t=2 j i 1 2 3 4 c(i,j,2) +F(j,3) 1 2 3 70 75 85 85 90 80 90 70 85 80 85 90 4 80 95 80 75 i F(i,2) φ∗(i,2) 1 70 1 2 80 3 3 70 2 4 75 4 t=1 j 1 2 i 3 4 c(i,j,1)+F(j,2) 1 2 3 175 180 155 160 165 170 170 170 165 180 185 190 4 165 170 180 185 23 i F(i,1) φ∗(i,1) 1 155 3 2 160 1 3 165 3 4 180 1 t=0 j i 0 c(0,j,0)+F(j,1) 1 2 3 190 200 195 4 225 i F(0,0) φ∗(0,0) 0 190 1 Una volta calcolati i valori di F(i,j), si può, a partire da t=0, determinare la sequenza dei controlli ottimi per il problema. In t=0 la soluzione prevede u*(0)=φ(0,0)=1, cioè di usare il centro 1 per la prima operazione e di giungere, di conseguenza, nello stato x(1)=1. La seconda operazione deve essere u*(1)=φ(1,1)=3, quindi deve essere utilizzato il centro 3 giungendo nello stato x(2)=3. In t=2 il controllo risulta essere u*(2)=φ(3,2)=2, quindi l'ultima operazione deve essere svolta nel centro 2. Il costo ottimo corrispondente è di 190. I calcoli necessari per determinare la soluzione ottima forniscono anche la strategia ottima φ∗(i,t). Tale strategia indica l'azione di controllo migliore a partire da qualunque condizione (i,t). Se si fosse deciso che la prima lavorazione doveva essere comunque fatta nel centro 4, poiché, ad esempio, le altre macchine erano temporaneamente in manutenzione, il valore di φ∗(4,1) indicherebbe che la seconda lavorazione dovrebbe essere svolta nel centro 1, infine, φ∗(1,2) imporrebbe l'ultima lavorazione di nuovo nel centro 1. 4.4 Un esempio: soluzione (procedura progressiva) Si può esprimere il costo del problema in esame anche tramite l'equazione ricorsiva progressiva: G(x,t+1)=miny{ G(y,t)+g(y,u,z(t),t)| u:f(y,u,z(t),t)=x} che diventa nel caso di interesse: G(j,t+1)=mini{G(i,t)+c(i,j,t)} (4.5) perché f(y,u,z(t),t)=u. All'istante t=1, G(j,1)=c(0,j,1), per j=1,2,3,4. I valori di G(.,.) per gli istanti successivi si ricavano dall’equazione ricorsiva secondo il seguente schema: 24 Procedura progressiva: t=1 j G(j,1) j i 1 2 3 4 j G(j,2) t=2 j i 1 2 3 4 j G(j,3) 1 2 35 3 40 4 30 45 G(i,1)+c(i,j,1) 1 2 3 140 135 120 130 125 140 130 120 125 155 150 165 4 125 135 135 155 1 130 3 120 4 125 G(i,2)+c(i,j2) 1 2 3 200 205 215 205 210 200 210 190 205 205 210 215 4 210 215 200 200 1 200 4 200 2 120 2 190 3 200 Una volta effettuati i calcoli si ottiene: G(1,3)=200; G(2,3)=190; G(3,3)=200; G(4,3)=200 (4.6) e, poiché qualunque stato finale è ammissibile (x(T)∈XT={1,2,3,4}), si sceglie quello più conveniente, cioè x(3)=2. Procedendo a ritroso si può poi determinare la sequenza delle azioni di controllo ottime. 4.5 Soluzione come percorso minimo Il problema del paragrafo precedente può essere interpretato anche come problema di percorso minimo su un grafo orientato2 G=(N,A), dove N è l'insieme dei nodi e A quello degli archi (vedi Fig. 4.2). Il grafo G ha un nodo in N per ogni coppia (x(t),t), t=0,1,2,3, più un nodo finale (0,T+1), inoltre ha un arco orientato in A per ogni transizione ammissibile da un nodo (x(t),t) a un nodo (x(t+1),t+1). Ciascun arco ha una lunghezza pari al costo della transizione corrispondente. Il problema in oggetto si riduce, quindi, a quello di trovare il cammino più breve da (0,0) a (0,T+1). 2 Si faccia attenzione, qui e nel seguito, a non confondere il grafo G=(N,A) con il costo dell'equazione ricorsiva G(i,t). 25 stato 4 3 2 1 0 tempo 0 1 2 3 4 Fig. 4.2: Grafo (N,A) In generale ogni problema di Programmazione Dinamica può essere visto come un problema di ricerca del percorso più breve su un grafo caratterizzato da una struttura a livelli, o strati, in cui sono connessi solo nodi di livelli contigui. La determinazione di un percorso minimo su un grafo è un problema semplice, ovvero il numero di operazioni necessarie a risolvere tale problema cresce al massimo secondo una legge quadratica nel numero dei nodi, però il numero dei nodi del grafo considerato dipende dagli stati ammissibili e questi ultimi, per certe classi di problemi, possono essere numerosissimi, crescere cioè in modo esponenziale con la dimensione del problema. 4.6 Domande ed Esercizi 4.1 Risolvere il problema presentato nell'Esercizio 2.2. 4.2 Risolvere il problema presentato nell'Esercizio 2.3. 4.3 Risolvere il problema presentato nell'Esercizio 3.4. 26 5 Percorsi su grafi 5.1 Formulazione del problema 5.2 Soluzione (procedura progressiva) 5.3 Soluzione (procedura regressiva) 5.4 L'algoritmo di Dijkstra 5.5 Percorso minimo tra tutte le coppie di nodi 5.6 Domande ed esercizi Nel capitolo precedente è stato mostrato che un problema di Programmazione Dinamica può essere ricondotto ad un problema di percorso minimo. In questo capitolo, viceversa, un problema di percorso minimo su un grafo generico è affrontato attraverso la Programmazione Dinamica, a tal fine il concetto di "tempo" t viene opportunamente ridefinito in senso più ampio di quello intuitivo. Un ottimo libro che tratta di problemi di percorsi su grafi è Ahuja, Magnanti, Orlin: Network Flows, Prentice Hall 1993. 5.1 Formulazione del problema Si consideri ad esempio il grafo in Fig. 5.1, con p=1 e f=5. Problema di percorso minimo (descrizione a parole) Dato un grafo con distanze associate agli archi, trovare il percorso più breve da un nodo di partenza p ad uno finale f. 5 8 6 1 5 4 1 6 1 8 2 1 6 1 3 Fig. 5.1: Grafo di esempio 27 Per applicare con successo la Programmazione Dinamica, si deve scomporre il problema di percorso minimo in una sequenza di sottoproblemi parziali in modo da poterlo affrontare attraverso una serie di decisioni sequenziali ripetute. Dato un grafo generico G=(N,A), sia |N| cardinalità dell'insieme N, ovvero il numero di nodi del grafo. Si consideri quindi la sequenza dei seguenti sottoproblemi, per t=0,1,2,...,|N|-1: Sottoproblema(t) di percorso minimo: Trovare, quando possibile, i percorsi di lunghezza minima da p a tutti gli altri nodi in N aventi al più t archi. La soluzione del sottoproblema per t=|N|-1 coincide con quella del problema originale, infatti, in assenza di circuiti negativi, come da qui in seguito sempre assunto, un percorso ottimo visita al più una sola volta ogni nodo del grafo e, quindi, non può includere più da |N|-1 archi. Sia G(i,t) la lunghezza del percorso più breve con al più t archi dal nodo di partenza p al nodo i. Se sono note tutte le distanze G(i,t), è possibile calcolare, tramite la seguente equazione ricorsiva, la lunghezza G(j,t+1) del percorso più breve con al più di t+1 archi dal nodo p a un qualunque nodo j: G(j,t+1)=mini{G(i,t)+c(i,j)} (5.1) dove lunghezza arco ( i , j ), se ( i , j ) ∈ A c( i , j ) = 0 , se i = j ∞ , altrimenti (5.2) Confrontando l'equazione (5.1) con l'equazione ricorsiva (3.11), si può osservare che la (5.1) utilizza il numero massimo di rami dei percorsi in modo analogo a come viene usato il tempo t nella (3.11). Alla luce delle considerazioni precedenti, una possibile formulazione canonica del problema di percorso minimo può essere: Problema di percorso minimo (formulazione canonica): Dati: grafo G=(N,A) e - orizzonte: t=0,1,2,3,...,|N|-1, T=|N|-1; - stato x(t): nodo del percorso considerato, X(0)={p} e X(t)=N={1,2,3,...,|N|}, per t=0,1,2,3,...,|N|-1; - controllo u(t): prossimo nodo visitato, U(t)=N, per t=0,1,2,3,...,|N|-2; - variabili esogene z(t): non necessarie; - funzione di transizione dello stato f(x,u,z,t): x(t+1)=u(t), per t=0,1,2,...,|N|-2; - costo: g(x(t),u(t),t)=c(i,j), per t=0,1,2,...,|N|-2; con: i : stato attuale 28 j : controllo attuale - costo complessivo: c(p,u(0))+c(u(0),u(1))+c(u(1),u(2))+...+c(u(|N|-1),f). Determinare la sequenza ottima di controlli u*(t) che definiscono il percorso minimo da p a f. L'applicazione di una procedura regressiva sarebbe stata altrettanto naturale, se si fossero considerati i seguenti sottoproblemi, per t=0,1,2,...,|N|-1: Sottoproblema(t) regressivo di percorso minimo: Trovare, quando possibile, i percorsi di lunghezza minima terminanti in f a partire da tutti gli altri nodi in N avente al più t archi. 5.2 Soluzione (procedura progressiva) Per determinare G(.,.) nel caso di Fig. 5.1 si deve osservare che le lunghezze degli archi sono j i 1 2 3 4 5 c(i,j) 1 2 0 8 8 0 1 6 5 1 6 1 3 4 5 1 5 6 6 1 1 0 1 6 1 0 8 6 8 0 e che al passo 0 la funzione G(.,.) assume i seguenti valori: G(p,0)=0; G(i,0)=∞ per i≠p, (5.3) quindi G(j,1)=c(p,j) (5.4) da cui j 1 2 3 4 5 G(j,1) 0 8 1 5 6 prec(j,1) 1 1 1 1 1 dove la terza riga della tabella contiene l'ultimo nodo visitato prima di giungere in j. Si osservi che lungo il percorso ottimo, al passo generico t, prec(j,t)=x*(t-1)=u*(t-2). Una volta determinati i valori di G(.,.) al passo 1, è possibile calcolare G(.,.) al passo 2: G(j,2)=mini{G(i,1)+c(i,j)}, (5.5a) 29 prec(j)=argmini{G(i,1)+c(i,j)}. (5.5b) In particolare la seguente tabella riporta i valori G(i,1)+c(i,j) per ogni coppia i,j: j i 1 2 3 4 5 G(i,1)+c(i,j) 1 2 3 4 0 8 1 5 16 8 14 9 2 7 1 2 10 6 6 5 12 7 12 14 5 6 9 7 13 6 eseguendo quindi il minimo su ogni colonna, si ottengono i valori di G(j,2): j G(j,2) prec(j,2) 1 2 3 4 5 0 6 1 2 6 1 4 1 3 1 Iterando la procedura, si ottengono i risultati del seguente schema: t=2 j i 1 2 3 4 5 j G(j,3) prec(j,3) t=3 j i 1 2 3 4 5 j G(j,4) prec(j,4) G(i,2)+c(i,j) 1 2 3 4 5 0 8 1 5 6 14 6 12 7 7 2 7 1 2 7 7 3 3 2 10 12 7 12 14 6 1 2 0 1 3 3 4 4 1 1 5 2 3 6 1 G(i,3)+c(i,j) 1 2 3 4 5 0 8 1 5 6 11 3 9 4 4 2 7 1 2 7 7 3 3 2 10 12 7 12 14 6 1 2 0 1 3 3 2 4 1 1 5 2 3 4 2 30 Dai calcoli riportati nelle tabelle si deduce che lunghezza del percorso ottimo da p=1 a f=5 è G(5,4)=4. Inoltre utilizzando i valori prec(j), procedendo all'indietro, si possono determinare i nodi visitati dal percorso ottimo. In particolare, poiché u*(3)=5, u*(2)=prec(5)=2, u*(1)=prec(2)=4, u*(0)=prec(4)=3, il percorso ottimo visita nell'ordine i nodi 1, 3, 4, 2 e 5. Gli altri valori G(i,4) indicano le lunghezze dei percorsi minimi da 1 a tutti i rimanenti nodi i. 5.3 Soluzione (procedura regressiva) Il problema del percorso minimo può essere risolto anche con una procedura regressiva che, costruendo i cammini all'indietro, determina tutti i percorsi minimi che giungono in f a partire da qualunque altro nodo del grafo, quindi anche da p. In questa procedura regressiva il tempo t rappresenta di nuovo il numero massimo di rami dei percorsi che si stanno costruendo. In particolare t=T-t’, (5.6) dove t’ è il tempo della procedura progressiva, dunque t è il tempo rimanente rispetto a t'. L'equazione regressiva generale (3.3) diventa per il problema di percorso minimo: F(i,t+1)=minj{c(i,j)+F(j,t)}. (5.7) Si osservi che in questo caso, poiché si considera il tempo rimanente, l'equazione procede per valori crescenti di t. I valori F(i,t+1) al passo 0 sono: F(f,0)=0; F(i,0)=∞, per i≠f (5.8) quindi F(i,1)=c(i,f) (5.9) da cui i F(i,1) 1 2 3 4 5 6 1 6 8 0 Una volta determinati i valori di F(.,.) al passo 1, è possibile calcolare F(.,.) al passo 2: F(i,2)=minj{c(i,j)+F(j,1)}. (5.10) In particolare la seguente tabella riporta i valori c(i,j)+F(j,1) per ogni coppia i,j: 31 j i 1 2 3 4 5 c(i,j)+F(j,1) 1 2 3 4 5 6 9 7 13 6 14 1 12 9 1 7 7 6 9 6 11 2 7 8 8 12 2 12 16 0 eseguendo quindi il minimo su ogni riga, si ottengono i valori di F(j,2): i F(j,2) 1 2 3 4 5 6 1 6 2 0 Iterando la procedura, si ottengono i risultati del seguente schema: t=2 j i 1 2 3 4 5 i F(i,3) t=3 1 i F(i,4) 2 6 j i c(i,j)+F(j,2) 1 2 3 4 5 6 9 7 7 6 14 1 12 3 1 7 7 6 3 6 11 2 7 2 8 12 2 12 10 0 1 2 3 4 5 3 1 4 3 5 2 0 c(i,j)+F(j,3) 1 2 3 4 5 6 9 4 7 6 14 1 9 3 1 7 7 3 3 6 11 2 4 2 8 12 2 9 10 0 1 2 4 3 1 4 3 5 2 0 La lunghezza del percorso ottimo da p=1 a f=5 risulta essere F(1,4)=4. Gli altri valori F(i,4) indicano le lunghezze dei percorsi minimi da tutti i rimanenti nodi i a 5. 32 5.4 L'algoritmo di Dijkstra L'algoritmo di Dijkstra è l’algoritmo classico per trovare il percorso più breve tra due nodi p ed f in un grafo. Esso è applicabile solo nel caso in cui non esistano archi negativi e consiste nel determinare iterativamente, per ciascun nodo, delle stime (per eccesso) della distanza minima dal nodo di partenza. Ciascuna stima è relativa al numero massimo di rami t presenti nel percorso minimo. Le stime vengono progressivamente migliorate fino a diventare esatte. Inizialmente solo la distanza del nodo di partenza da se stesso è nota con certezza, ma, ad ogni iterazione, un nuovo nodo è incluso tra quelli la cui distanza minima da f è certa: Algoritmo Dijkstra // inizializzazione d(1,0)=0, distanza definitiva; d(j,0)=∞, j≠1, distanze provvisorie; loop // iterazione q=argmin{d(j,t), provvisorio}; d(q,t) distanza definitiva; per tutti i j, con distanze provvisorie e j≠q, d(j,t+1)=min{d(j,t),d(q,t)+c(q,j)}, distanze provvisorie. end loop Se si applica l'algoritmo di Dijkstra all'esempio di Fig. 5.1, si ottiene: Algoritmo Dijkstra: k=0 k=1 q=1 q=3 j d(j,0) provvisori d(j,0) definitivi 1 2 3 4 5 q ∞ ∞ ∞ ∞ 0 d(q,0)+c(q,j) 8 1 5 6 d(j,1) provvisori d(j,1) definitivi 8 q 5 1 6 7 2 7 d(q,1)+c(q,j) 0 33 k=2 k=3 k=4 q=4 q=2 q=5 d(j,2) provvisori d(j,2) definitivi 7 q 6 1 2 d(q,2)+c(q,j) 3 10 d(j,3) provvisori d(j,3) definitivi q 3 6 0 0 1 2 d(q,3)+c(q,j) 4 d(j,4) provvisori d(j,4) definitivi q 4 0 3 1 2 I risultati sono ovviamente identici a quelli ottenuti con la procedura progressiva della Programmazione Dinamica. L'algoritmo di Programmazione Dinamica visto e quello di Dijkstra sono egualmente efficaci, producono entrambi la soluzione ottima, viceversa presentano efficienza diversa in termini di risorse adoperate: tempo e memoria. Si valuti, infatti, il numero di operazioni in funzione del numero di nodi |N| del grafo. Il metodo di Programmazione Dinamica visto richiede |N|2 somme ad ogni iterazione, quindi in totale |N|3 somme, diversamente l’algoritmo di Dijkstra richiede al più |N| somme ad ogni iterazione, quindi in totale |N|2 somme, dunque l’algoritmo di Dijkstra è più efficiente. L'algoritmo di Programmazione Dinamica è però più generale. Si consideri, infatti, un grafo asimmetrico, in cui la distanza tra una coppia di nodi i e j non è necessariamente la stessa che tra j e i, che possa avere archi con distanze negative, l’algoritmo di Dijkstra non funziona, invece la Programmazione Dinamica scopre anche gli eventuali circuiti negativi. In generale, nonostante la migliore efficienza dell'algoritmo di Dijkstra su grafi generici, può non convenire ricondurre un problema di Programmazione Dinamica ad un problema di percorso minimo su grafi. Il numero di operazioni svolte dalla Programmazione Dinamica è, infatti, limitato superiormente da |X|2T dove |X| è la dimensione dello stato del sistema. Tale limite coincide con il numero di operazioni da svolgere per calcolare il percorso minimo sul tipo di grafo (Fig. 4.2) associato al problema. Si osservi, infine, che un problema di percorso minimo può anche essere formulato e risolto come problema di programmazione lineare. Definite, per tutti gli archi (i,j) inclusi in A, le variabili x(i,j), che assumono valore 1 se l'arco corrispondente appartiene al percorso minimo, 0 in caso contrario, il problema di percorso minimo risulta essere: min ΣiΣ,jc(i,j)x(i,j) Σjx(p,j)=1 Σix(i,f)=1 Σix(i,j)=Σkx(j,k) 0≤x(i,j)≤1 (5.10) ∀j 34 Si possono risolvere problemi di programmazione lineare (non molto grandi) anche utilizzando i più comuni fogli elettronici. La programmazione lineare ha però alcuni svantaggi: può avere problemi di precisione, trova solo il percorso tra una coppia di nodi ed infine, essendo una metodologia sviluppata per risolvere problemi molto più generali, può risultare più difficile da utilizzare. 5.5 Percorso minimo tra tutte le coppie di nodi La Programmazione Dinamica, attraverso un'opportuna definizione del "tempo" t e dello stato x, permette di determinare anche i percorsi minimi tra tutte le coppie di nodi di un grafo. In generale, nella Programmazione Dinamica, la scelta di t e x è critica per la soluzione dei problemi, la formulazione dei quali non è, quindi, sempre intuitiva ed immediata: richiede spesso una discreta dose di creatività. Il problema di percorso minimo tra tutte le coppie è risolto dall'algoritmo di Programmazione Dinamica di Floyd-Warshall. In tale procedura la funzione di costo cumulativa è la lunghezza d(i,j,t) del minimo fra tutti i cammini tra i nodi i e j che visitano al più solo i nodi intermedi 1,2,...,t . In queste ipotesi l'equazione ricorsiva diventa d(i,j,t+1)=min{d(i,j,t),d(i,t+1,t)+d(t+1,j,t)}. (5.11) L'equazione (5.11) esprime semplicemente il fatto che il percorso minimo che coinvolge al più i nodi intermedi da 1 a t+1 può passare o meno per l'ultimo nodo t+1. Nel primo caso d(i,j,t+1)=d(i,t+1,t)+d(t+1,j,t), altrimenti d(i,j,t+1)=d(i,j,t). Si osservi come la prima di queste condizioni non è altro che il Principio di Ottimalità. L'algoritmo di Floyd-Warshall viene inizializzato imponendo che, per t=0, non ci siano nodi intermedi; rimane quindi solo l’eventuale collegamento diretto: d(i,j,0)=c(i,j). (5.12) Lo schema seguente riporta l'applicazione dell'algoritmo di Floyd-Warshall al grafo in Fig. 5.1. In particolare per ogni istante generico t sono riportate le tabelle con tutti i valori di d(i,j,t) e di d(i,t+1,t)+d(t+1,j,t). Si osservi che con i valori riportati nella prima tabella si determinano gli elementi della seconda e quindi, eseguendo il minimo tra elementi corrispondenti di queste due tabelle, si calcolano, in accordo con l'equazione (5.11), gli elementi della tabella d(i,j,t+1) dell'istante successivo. 35 Algoritmo Floyd - Warshall: t=0 1 2 3 4 5 d(i,j,0) 1 2 3 4 5 0 7 8 5 8 1 0 1 2 5 4 2 0 2 0 1 1 3 0 8 4 4 6 6 0 1 2 3 4 5 d(i,1,0)+d(1,j,0) 1 2 3 4 5 0 7 8 5 8 1 8 9 6 9 4 11 12 9 12 1 8 9 6 9 4 11 12 9 12 1 2 3 4 5 d(i,j,1) 1 2 3 4 5 0 7 8 5 8 1 0 1 2 5 4 2 0 2 0 1 1 3 0 8 4 4 6 6 0 1 2 3 4 5 d(i,2,1)+d(2,j,1) 1 2 3 4 5 8 7 8 9 12 1 0 1 2 5 3 2 3 4 7 2 1 2 3 6 5 4 5 6 9 j i j i t=1 j i j i t=2 j i 1 1 2 3 4 5 d(i,j,2) 2 3 4 5 0 7 8 5 8 1 0 1 2 5 3 2 0 2 0 1 1 2 0 6 4 4 5 6 0 1 2 3 4 5 prec(i,j,0) 1 2 3 4 5 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 1 2 3 4 5 prec(i,j,1) 1 2 3 4 5 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 j i j i j i 1 1 2 3 4 5 prec(i,j,2) 2 3 4 5 1 1 1 1 1 2 2 2 2 2 3 3 3 3 2 4 4 4 4 2 5 5 5 5 2 36 1 2 3 4 5 d(i,3,2)+d(3,j,2) 1 2 3 4 5 11 10 8 10 8 4 3 1 3 1 3 2 0 2 0 5 4 2 4 2 8 7 5 7 5 1 2 3 4 5 d(i,j,3) 1 2 3 4 5 0 7 8 5 8 1 0 1 2 1 3 2 0 2 0 1 1 2 0 2 4 4 5 6 0 1 2 3 4 5 d(i,4,3)+d(4,j,3) 1 2 31 4 5 6 6 7 5 7 3 3 4 2 4 3 3 4 2 4 1 1 2 0 2 7 7 8 6 8 1 2 3 4 5 d(i,j,4) 1 2 3 4 5 0 6 7 5 7 1 0 1 2 1 3 2 0 2 0 1 1 2 0 2 4 4 5 6 0 1 2 3 4 5 d(i,5,4)+d(5,j,4) 1 2 3 4 5 11 11 12 13 7 5 5 6 7 1 4 4 5 6 0 6 6 7 8 2 4 4 5 6 0 j i t=3 j i j i t=4 j i j i 1 2 3 4 5 prec(i,j,3) 1 2 3 4 5 1 1 1 1 1 2 2 2 2 3 2 3 3 3 3 4 4 4 4 3 5 5 2 5 5 1 2 3 4 5 prec(i,j,4) 1 2 3 4 5 1 1 4 4 4 2 2 2 2 3 2 3 3 3 3 4 4 4 4 3 5 5 2 5 5 j i j i 37 t=5 j i 1 2 3 4 5 d(i,j,5) 1 2 3 4 5 0 6 7 5 7 1 0 1 2 1 3 2 0 2 0 1 1 2 0 2 4 4 5 6 0 prec(i,j,5) 1 2 3 4 5 1 4 4 1 4 2 2 2 2 3 2 3 3 3 3 4 4 4 4 3 5 5 2 5 5 j i 1 2 3 4 5 I valori di d(i,j,5) forniscono le distanze minime tra tutte le coppie di nodi. Inoltre i dati delle tabelle prec(i,j,t) permettono di determinare i percorsi ottimi in modo del tutto analogo a quanto fatto nel paragrafo 5.2 per una sola coppia di nodi. Si osservi, infine, che il numero di operazioni dell'algoritmo di Floyd-Warshall è limitato superiormente da |N|3, dunque questo algoritmo risulta più veloce che applicare |N| volte l'algoritmo di Dijkstra solo nel caso di grafi densi (con molti archi), mentre non risulta conveniente nel caso di grafi sparsi. 5.6 Domande ed Esercizi 5.1 Determinare il percorso minimo dal nodo S al nodo T sul seguente grafo: 9 6 5 6 4 2 4 8 1 8 S 5 2 2 T 5 4 6 3 5.2 Determinare il percorso minimo dal nodo S al nodo T sul seguente grafo: 38 44 50 25 56 12 15 34 S 32 43 20 23 35 23 74 46 9 T 73 11 43 5.3 Formulare il problema presentato nell'Esercizio 2.2 come un problema di ricerca di percorso minimo e risolverlo. 5.4 Formulare il problema presentato nell'Esercizio 2.3 come un problema di ricerca di percorso minimo e risolverlo. 5.5 Formulare il problema presentato nell'Esercizio 3.4 come un problema di ricerca di percorso minimo e risolverlo 39 6 Attribuzione di risorse 6.1 Formulazione del problema 6.2 Soluzione (procedura progressiva) 6.3 Domande ed esercizi In questo capitolo viene presentato un altro esempio di applicazione della Programmazione Dinamica in cui il concetto di "tempo" t viene ridefinito in senso più ampio di quello intuitivo. 6.1 Formulazione del problema Problema di attribuzione di risorse (descrizione a parole) Si dispone di 5 risorse, ciascuna delle quali può essere attribuita ad una di 3 diverse attività: A, B, C. Il rendimento (valore) dell’attribuzione dipende in maniera complessa dal numero di risorse assegnate a ciascuna attività, come indicato nella tabella: rendimento dell'attribuzione risorse assegnate 0 1 2 3 A 0 45 70 90 attività B 0 20 45 75 C 0 50 70 80 4 105 110 100 5 120 150 130 Attribuire le risorse alle attività in modo da massimizzare il profitto complessivo. Apparentemente si deve compiere un’unica scelta e quindi il paradigma della Programmazione Dinamica non si applica in modo naturale. Si può però "serializzare" (decomporre) il problema decidendo per un’attività alla volta, in un ordine prefissato qualunque. In quest'ottica l'attività i, su cui si sta correntemente prendendo una decisione, deve essere interpretata come il valore della variabile "tempo" nella formulazione canonica, di conseguenza l’orizzonte coincide con il numero complessivo N di attività. Le variabili di controllo u(i) corrispondono alle risorse da attribuire ad ogni attività i. Lo stato x(i), che deve riassumere l’effetto delle scelte passate e definire i limiti entro cui si possono prendere le decisioni future, può corrispondere alle risorse rimanenti da attribuire alle attività i,i+1,...,N. L’equazione di stato, che quindi deve descrivere la dinamica delle risorse rimaste disponibili, risulta essere: x(i+1)=x(i)-u(i) (6.1) Il profitto g(u(i),i), i cui valori sono elencati nella tabella dei rendimenti, dipende solo da controllo u(i) e tempo i, non dallo stato x(i). In particolare si osservi la sua dipendenza esplicita dal tempo. Assegnare le stesse risorse ad attività diverse comporta, infatti, profitti differenti. 40 Problema di attribuzione di risorse (formulazione canonica): Dati: orizzonte: t=A,B,C, stato x(t): x(t)∈X(t) con X(A)={ 5} e X(t)={0,1,2,3,4,5} per t=B,C; controllo u(t): 0≤u(t)≤x(t), per t=A,B,C; variabili esogene z(t): non necessarie; funzione di transizione dello stato f(x,u,z,t): x(t+1)=x(t)-u(t), per t=A,B; - profitto: g(x(t),u(t),t)=g(u,i), per t=A,B,C; con: u : controllo attuale i : tempo attuale c : matrice dei rendimenti. profitto complessivo: c(u(A),A)+c(u(B),B)+c(u(C),C). Determinare la sequenza ottima di controlli u*(t). Dalla tabella dei rendimenti si deducono in modo ovvio i valori di g(u,i) che risultano essere: i u 0 1 2 3 4 5 g(u,i) A B 0 0 45 20 70 45 90 75 105 110 120 150 C 0 50 70 80 100 130 6.2 Soluzione (procedura regressiva) Il costo del problema in esame F(x,i), che rappresenta il massimo rendimento che si può ottenere distribuendo x risorse alle attività i,i+1,...,N, può essere espresso in forma ricorsiva regressiva: F(x,i)=maxu{g(u,i)+F(x-u,i+1)}. (6.2) Per determinare il valore di F(.,.) al passo N si osservi che conviene sempre assegnare tutte le risorse non attribuite in precedenza all'ultima attività, da cui u(N)=x(N), (6.3) F(x,N)=g(x,N), (6.4) ne consegue che 41 dove il primo argomento della funzione di costo g(.,.) è il valore del controllo, che, per la (6.3), coincide con il valore dello stato. Applicando la formula ricorsiva, si ottengono i risultati riportati nel seguente schema: Procedura regressiva: i=C x F(x,C) i=B x u 0 1 2 3 4 5 x F(x,B) i=A x u 0 1 2 3 4 5 x F(x,A) 0 0 1 50 2 70 3 4 5 80 100 130 g(u,B)+F(x-u,C) 0 1 2 3 0 50 70 80 20 70 90 45 95 75 0 0 1 50 2 70 0 1 50 5 130 120 125 145 160 150 3 4 5 95 125 160 g(u,A)+F(x-u,B) 0 1 2 3 0 50 70 95 45 95 115 70 120 90 0 4 100 100 115 125 110 4 125 140 140 140 105 5 160 170 165 160 155 120 2 3 4 5 95 120 140 170 La soluzione ottima indica che si ottiene un rendimento massimo pari a 170 assegnando una risorsa ad A, tre a B e una a C. 6.3 Domande ed esercizi 6.1 Problema dello Zaino. Siano dati uno zaino di capacità massima C = 25 e un insieme N={1,2,3,4} di tipologie di oggetti, ognuno dei quali ha il valore e il peso indicati nella tabella seguente. Determinare quali e quanti oggetti inserire nello zaino al fine di massimizzare il valore complessivo del suo contenuto. 42 oggetto i 1 2 3 4 peso valore vi ai 6 15 4 10 3 7 1 2 {Suggerimento: definire come stato/tempo la capacità residua. L'equazione ricorsiva risulta essere: F ( x ) = max{ vi + F ( x − ai )} (6.5) i :a i < x con F(0)=0; da cui F(1)=v4=1; F(2)=v4+F(1)=4 F(3)=max{v3+F(0),v4+F(2)}=7 ...... Oltre una certa capacità residua il valore di F(.) è esprimibile in modo molto semplice, perché?} 6.2 Un'azienda deve scegliere quali tra N commesse lanciare nel prossimo mese (30 giorni). Ogni commessa per dare profitto deve essere completata senza interruzione. Pianificare le attività al fine di massimizzare i profitti. {Suggerimento: simile al problema precedente anche se vi è un unica istanza per commessa, conviene ordinare le commesse secondo il rapporto profitto su durata} commessa durata profitto 1 9 18 2 2 7 3 7 25 4 4 8 5 10 21 6 6 12 7 12 27 8 6 10 9 13 35 10 2 4 11 4 12 12 5 14 6.3 Programmazione Lineare. Risolvere, tramite la Programmazione Dinamica, il seguente problema: 43 max z = 3 x1 + 7 x 2 x1 + 2 x 2 ≤ 350 3 x1 + x 2 ≤ 300 (6.6) x1 , x 2 ≥ 0 {Suggerimento: considerare come istante di "tempo" la decisione circa una variabile e come stato (bidimensionale) la quantità residua delle risorse descritte dai termini noti. Si ottengono di conseguenza le seguenti equazioni ricorsive: F (( v 2 , w2 ),2 ) = max { 7 x 2 } 0 ≤ 2 x2 ≤v2 (6.7) 0 ≤ x2 ≤ w2 F (( v1 , w1 ),1 ) = max { 3 x1 + F (( v1 − x1 , w1 − 3 x1 ),2 )} . 0 ≤ x1 ≤ v1 (6.8) 0 ≤ 3 x1 ≤ w1 Poiché il valore di F((v2,w2),1) è uguale a 7min{v2/2,w2}, la (6.8) può essere scritta in modo esplicito e il problema risolto calcolando F((350,300),1). Si osservi che, in generale, la Programmazione Dinamica non è il metodo migliore per risolvere problemi di programmazione lineare.} 6.4 Risolvere il seguente problema di programmazione lineare: max z = 2 x1 + 7 x 2 3 x1 + 4 x 2 ≤ 240 5 x1 + x 2 ≤ 280 (6.9) x1 , x 2 ≥ 0 6.5 Risolvere il seguente problema di programmazione intera: max z = 2 x12 + 7 x2 x1 + 4 x 22 ≤ 340 3 x1 + x2 ≤ 250 (6.9) x1 , x2 ∈ Z 44 7 Scorte 7.1 Ragioni delle scorte 7.2 Costi delle scorte 7.3 Dimensionamento delle scorte e tempificazione degli ordini 7.4 Problema delle scorte: formulazione 7.5 Problema delle scorte: soluzione 7.6 Esempio 7.7 Domande ed esercizi In questo capitolo viene introdotto il problema delle scorte ed è presentata la soluzione di un caso paradigmatico. Il lettore interessato può consultare uno dei seguenti due libri, entrambi di facile lettura anche se abbastanza avanzati, per un successivo approfondimento: - G. Urgeletti Tinarelli: La gestione delle scorte nelle imprese commerciali e di produzione, EtasLibri 1992; - E.A. Silver, R. Peterson: Decision systems for inventory management and production planning, Wiley 1985. 7.1 Ragioni delle scorte Le scorte sono materiali che aspettano di essere utilizzati (lavorati, assemblati, distribuiti, venduti, adoperati, consumati, ecc.). Esse possono posizionarsi in qualunque fase del processo produttivo a seconda che riguardino materie prime, semilavorati o prodotti finiti. Le scorte sono giustificate fondamentalmente per le tre seguenti ragioni: 1) motivo "transazionale": per ridurre i costi fissi (es. di trasporto). In ambiente produttivo, infatti, si possono spesso ottenere economie di scala: i costi meno che proporzionali alla quantità. Ordinare dei lotti grandi può, quindi, essere più conveniente che ordinare le stesse quantità in lotti di dimensioni minori; 2) motivo "precauzionale": per garantirsi contro le incertezze dei fornitori, dei trasporti, della produzione o del mercato per quanto riguarda i tempi di consegna, le quantità disponibili o la qualità dei materiali. Le scorte, infatti "disaccoppiano" processi contigui riducendone la mutua influenza; 3) motivo "speculativo": per garantirsi o per guadagnare in attesa o in previsione di aumenti di valore o di costo. Tenere delle scorte non è però indolore, comporta dei costi che vanno oltre quello di acquisto della merce. 45 7.2 Costi delle scorte In generale i costi associati ad un qualunque sistema sono suddivisi tra variabili, ovvero funzione di almeno una delle grandezze che caratterizzano la dinamica del sistema, e fissi, ovvero indipendenti dalla dinamica osservata e generalmente funzione della sola struttura fisica del sistema. Per quanto riguarda le scorte si possono ritenere sempre presenti sia costi variabili, almeno quelli legati alla quantità di materiale immagazzinato (livello delle scorte), sia i costi fissi, almeno quelli legati ad ogni nuovo ordine di rifornimento. In prima approssimazione il costo di mantenimento, che modella, ad esempio, i costi legati agli interessi da pagare alle banche per il capitale immobilizzato, i costi di gestione del magazzino per gli spazi, movimentazione e sicurezza, i costi di deterioramento e obsolescenza, è considerato proporzionale alla quantità e al tempo di permanenza dei materiali in magazzino. Il costo di rifornimento, che modella i costi legati al trasporto, ordine, ecc., è invece ritenuto un costo fisso e, quindi, ha un valore costante indipendente dalla quantità ordinata. Il costo di penuria, che modella il rischio di rottura di scorta, vale a dire della incapacità di rispondere ad una richiesta di materiali e, quindi, della possibilità di blocco della produzione, mancata vendita o disaffezione dei clienti, è, infine, spesso difficile da monetizzare in modo preciso, ma in generale è ritenuto proporzionale alla domanda non soddisfatta e alla durata della penuria. La presenza di costi di mantenimento non trascurabili ha determinato lo sviluppo del cosiddetto approccio Just-In-Time (JIT) alla gestione della produzione. Secondo tale linea di pensiero si devono tenere le scorte al minimo, o non tenerne addirittura (scorte zero). Si devono effettuare i rifornimenti solo quando il materiale deve essere adoperato in modo da annullare i tempi di attesa. La riduzione delle scorte però, se diminuisce il costo di mantenimento, può indurre un aumento degli altri costi: di rifornimento e di penuria. 7.3 Dimensionamento delle scorte e tempificazione degli ordini Nel paragrafo precedente si è osservato come livelli di scorta meno elevati diminuiscono i costi di mantenimento, ma aumentano quelli di rifornimento e di penuria, e viceversa. Per una corretta politica di gestione delle scorte si deve, quindi, trovare il punto di equilibrio più conveniente. Tenere delle scorte è, infatti, spesso inevitabile, conviene quindi farlo nel modo meno oneroso. In generale è difficile determinare una politica di gestione ottima, se non altro a causa delle inevitabili stocasticità che affliggono, ad esempio, la domanda, la produzione, i trasporti o i prezzi. In pratica esistono diverse politiche approssimate, tra le quali deve essere scelta quella più adatta alla situazione contingente. Tali politiche, per la cui descrizione si rimanda ai riferimenti all'inizio del capitolo, differiscono per: - modalità di gestione del magazzino, che può essere ad inventario periodico, in cui la valutazione dell’entità delle scorte disponibili viene fatta periodicamente, oppure a controllo continuo, in cui un sistema informativo aggiorna in tempo reale la situazione del magazzino, ad ogni ingresso ed ogni uscita di materiale; 46 - modalità di gestione delle scorte, che può essere a intervalli fissi, cioè con riordino periodico, oppure a punto d’ordine, in cui si riordina quando la scorta raggiunge un dato valore; - dimensione dell'ordine, che può essere a lotti fissi, in cui si riordina una quantità costante, oppure a ripristino, in cui si riordina la quantità necessaria a ricostituire la scorta massima. 7.4 Problema delle scorte: formulazione Problema delle scorte (descrizione a parole) Si consideri un sistema di gestione delle scorte a intervalli fissi di riordino in cui: la domanda su un dato orizzonte temporale è nota a priori senza incertezze, anche se non è costante nel tempo; non sono ammesse rotture di scorta, ovvero tutta la domanda deve essere soddisfatta quando viene espressa, senza alcun ritardo; il livello iniziale delle scorte è zero; gli ordini di rifornimento vengono eseguiti istantaneamente; il costo fisso k di rifornimento non dipende dalla quantità ordinata e viene imputato in ciascun periodo in cui si emette un ordine; il costo di mantenimento è proporzionale, tramite la costante h, sia alla quantità di merce presente in magazzino, sia al tempo di permanenza. Minimizzare il costo complessivo di gestione delle scorte. La caratteristica principale del problema oggetto di considerazione è la domanda nota con certezza, ma variabile nel tempo. Tale tipo di domanda si presenta in diversi casi reali: - assemblaggio di prodotti complessi, in cui si sa in anticipo quali componenti saranno necessari e quando; - contratti di fornitura, in cui si possono prevedere tempi di consegna differiti per quantità definite, oppure contratti riguardanti prodotti con domanda stagionale, in cui la stagionalità può essere indotta, ad esempio, anche da promozioni o sconti; - gestione di pezzi di ricambio per prodotti che escono di produzione, in cui per propria natura la domanda si riduce nel tempo, oppure gestione di prodotti con interventi di manutenzione programmata, in cui, quindi, anche le necessità sono programmate. In pratica, anche nei casi enunciati sopra, la domanda è tanto meno certa quanto è più lontana nel futuro. Può quindi essere conveniente applicare un approccio ad orizzonte mobile (rolling horizon). Con tale metodo si pianifica per un lungo periodo, si attua solo la parte iniziale del piano, quindi si ripianifica a partire dal punto cui si è arrivati. Un simile approccio ha il vantaggio di evitare una pianificazione "miope", che tenga conto solo dei dati assestati, avendo però la possibilità di modificare le decisioni, se varia il contesto in cui sono state prese. Il problema delle scorte considerato richiede di decidere la quantità da ordinare in ciascun periodo, dunque è un tipico problema di Programmazione Dinamica. Problema di scorte (formulazione canonica): - orizzonte: t = 1, 2, 3, ..., n+1, T=n+1; - stato x(t): livello delle scorte all’inizio del periodo t (ovvero alla fine del periodo t-1); 47 X(1)={0}, X(n+1)={0} e X(t)=R+, per t =1,2,3,...,n; infatti non sono ammesse rotture di scorta e all’inizio il magazzino è vuoto (altrimenti bisogna detrarre la scorta iniziale dai primi ordini); - controllo u(t): quantità ordinata all'istante t, supponendo che l’ordine sia emesso (ed eseguito) prima della domanda, U(t)=R+, per t=1,2,3,...,n; - variabili esogene z(t): domanda d(t), per t=1,2,3,...,n; - funzione di transizione dello stato f(x,u,z,t): x(t+1)=x(t)-u(t)+d(t), per t=1,2,...,n; - costo: g(x(t),u(t),t)=hx(t)+kδ(u(t)), per t=1,2,...,n; con: 1 δ ( u( t )) = 0 se u( t ) > 0 se u( t ) = 0 (7.1) Determinare la sequenza ottima di controlli u*(t) che definiscono il costo minimo da 1 a n+1. 7.5 Problema delle scorte: soluzione Il problema descritto nel paragrafo precedente è stato studiato da Wagner e Whitin nel 1958 e viene descritto in dettaglio in - E.A. Silver, R. Peterson: Decision systems for inventory management and production planning, Wiley 1985, Capitolo 6; - H.L. Lee, S. Nahmias: Single-Product, Single-Location Models, in: S.C. Graves, A.H.G. Rinnooy Kan, P.H. Zipkin (eds.): Handbook In Operations Research and Management Science Vol. 4: Logistics of Production and Inventory, Wiley 1993, Capitolo 1, pp. 18-25. Prima di tentare di risolvere secondo una qualunque metodologia il problema in questione, si deve osservare che vale la seguente proprietà: Proprietà fondamentale Non è conveniente emettere un ordine se il magazzino non è vuoto, formalmente: x(t)u(t)=0 per t=1,2,...,n. (7.2) Per assurdo si supponga che si sia emesso un ordine u(t)>0 quando anche x(t)=x'>0. Allora tale strategia può essere migliorata riducendo di x’ l’ordine precedente a u(t) e, viceversa, aumentando u(t) di x’. In tale modo la domanda è lo stesso soddisfatta, ma si risparmia il costo di mantenimento relativo alla quantità x’. Immediata conseguenza della proprietà fondamentale è che la quantità da ordinare u(t) può assumere solo determinati valori: u(t)=d(t) oppure =d(t)+d(t+1) (7.3) 48 oppure =d(t)+d(t+1)+d(t+2) oppure =d(t)+d(t+1)+d(t+2)+d(t+3) ....... In altre parole ha senso ordinare solo la quantità necessaria a soddisfare esattamente la domanda di prossimi m giorni. Ad ogni istante t si deve soltanto decidere il valore di m, poiché la quantità da ordinare ne è una conseguenza. Il problema delle scorte in considerazione può essere affrontato attraverso la Programmazione Dinamica, ma può anche essere formulato e risolto come un problema di ricerca del percorso minimo su un grafo orientato G=(N,A). In particolare il grafo G ha un nodo in N per ogni periodo t, t=1,2,...,n, più un nodo finale n+1, inoltre ha un arco orientato in A per ciascuna coppia di nodi (i,j) tali che l'istante j sia successivo a i, per i=1,2,...,n, e j=i+1,i+2,...,n+1. Ogni arco (i,j)∈A ha una lunghezza pari al costo c(i,j) pagato globalmente per un ordine emesso il periodo i e smaltito entro periodo j. Poiché in tal caso la quantità da ordinare è uguale al fabbisogno dei periodi da i a j-1: d(i)+d(i+1)+...+d(j-1), il costo c(i,j) è dato dal costo di rifornimento k più il costo di mantenimento hd(i+1)+2hd(i+2)+3hd(i+3)+.... In questo modo la lunghezza del cammino più breve da 1 a n+1 corrisponde al costo minimo di gestione delle scorte e i nodi inclusi nel percorso ottimo corrispondono agli istanti in cui si deve effettuare l'ordine. Il problema di gestione delle scorte può essere così risolto in un numero di passi proporzionale al quadrato del valore dell'orizzonte n. Per risolvere lo stesso problema tramite la Programmazione Dinamica conviene definire il costo cumulato come il costo ottimo F(t) del il sottoproblema di orizzonte [t,n] e di scorte iniziali nulle. Il valore di F(t), in conseguenza della proprietà fondamentale, dipende solo dal tempo t, non dallo stato x(t), e può essere calcolato ricorsivamente: F(i)=minj{c(i,j)+F(j)| j>i} (7.4) In (7.4) il minimo è relativo a solo n-i valori di j, quindi è possibile determinare il costo ottimo F(0) in un numero quadratico in n di operazioni. Il numero delle operazioni necessarie può essere anche minore, infatti la (7.4) implica F(i)≤k+F(i+1), dunque domande future molto elevate o molto remote nel tempo, che comportano costi di mantenimento superiori al costo fisso di rifornimento, devono essere escluse a priori dall'ordine attuale. Algoritmi di Programmazione Dinamica particolarmente efficienti possono addirittura permettere di risolvere questo problema in un numero di operazioni proporzionale a nlogn. 7.6 Esempio Nei prossimi quattro giorni lavorativi la domanda prevista per un dato componente è uguale a 51, 80, 24, 48. Il costo fisso di rifornimento è di 75, mentre il costo di mantenimento è unitario. 49 Assumendo di avere vuoto il proprio magazzino, si vuole determinare quando e quanto ordinare in modo da minimizzare i costi e non andare sotto scorta. Problema di scorte (formulazione canonica): - orizzonte: t=1,2,3,4,5, T=5; - stato x(t): livello delle scorte all’inizio del periodo t (e quindi alla fine del periodo t-1); X(1)={0}, X(t)=R+, per t=1,2,3,4, X(5)={0}; - controllo u(t): quantità ordinata all'istante t, supponendo che l’ordine sia emesso (ed eseguito) prima della domanda, U(t)=R+, per t=1,2,3,4; - variabili esogene z(t): domanda d(t), per t=1,2,3,4; - funzione di transizione dello stato f(x,u,z,t): x(t+1)=x(t)-u(t)+d(t), per t=0,1,2,3,4; - costo: g(x(t),u(t),t)=1x(t)+75δ(u(t)), per t=1,2,3,4; con: 1 δ ( u( t )) = 0 se u( t ) > 0 se u( t ) = 0 (7.5) Determinare la sequenza ottima di controlli u*(t) che definiscono il costo minimo da 1 a 5. Applicando l'equazione ricorsiva (7.4), si ottiene: - F(5)=0; F(4)=min{75+F(5)}=75, quindi u(4)=48; F(3)=min{75+F(4),75+48+F(5)}=123, quindi u(3)=24+48=72; F(2)=min{75+F(3),75+24+F(4),75+24+2•48+F(5)}=164, quindi u(2)=80+24=104; F(1)=min{75+F(2),75+80+F(3),75+80+2•24+F(4),75+80+2•24+3•48+F(5)}=239, u(1)=51; quindi I risultati derivanti dal computo dei valori dell'equazione ricorsiva indicano che la politica ottima consiste nell'ordinare il primo, il secondo e il quarto giorno. Il calcolo dei minimi corrisponde banalmente a tenere conto che, se si emette un ordine nella quarta giornata, tutta la merce deve essere consumata subito; viceversa, se si emette un ordine nelle giornate precedenti, si deve valutare se conviene fare arrivare merce anche per i giorni successivi. Si osservi, infine, che il calcolo di F(2) e F(1) è stato riportato per esteso solo per motivi didattici: il terzo argomento del minimo considerato nel calcolo di F(2) e gli argomenti dal secondo in poi del minimo considerato nel calcolo di F(1) possono essere a priori scartati. Nel caso di F(2), ad esempio, è certamente inutile ordinare merce anche per la quarta giornata, infatti il costo di mantenimento di tale merce per due giorni è superiore al costo che si paga ordinandola separatamente solo quando serve. 50 7.7 Domande ed esercizi 7.1 Si risolva il problema dell'esempio nel paragrafo 7.6 assumendo un orizzonte temporale di 10 giorni e la seguente domanda: t d(t) 1 37 2 29 3 52 4 54 5 63 6 42 7 32 8 21 9 10 25 34 7.2 Si risolva il problema dell'esempio nel paragrafo 7.6 assumendo un orizzonte temporale di 10 giorni, costo di rifornimento k=10 e la seguente domanda: t d(t) 1 7 2 19 3 12 4 14 5 6 6 12 7 12 8 11 9 10 15 14 Come conviene comportarsi quando i costi fissi sono molto bassi? E quando sono molto alti? 7.3 Si risolva il problema dell'esempio nel paragrafo 7.6 assumendo un orizzonte temporale di 10 giorni, costo di rifornimento variabile nel tempo e la seguente domanda: t d(t) k 1 17 30 2 29 30 3 23 30 4 14 20 5 34 20 6 32 20 7 22 15 8 10 15 9 10 15 14 15 15 7.4 Si risolva il problema dell'esempio nel paragrafo 7.6 assumendo che le consegne arrivino ritardate di due giorni dall'ordine, un orizzonte temporale di 10 giorni e la seguente domanda: t d(t) 1 14 2 29 3 22 4 25 5 33 6 46 7 22 8 11 9 10 15 14 Come deve essere modificata la procedure di soluzione? 7.5 Proporre una procedura di soluzione approssimata con cui affrontare l'esercizio 7.1 quando vi siano dei limiti superiori sulla dimensione massima del lotto d'ordine. Si supponga ad esempio che il lotto massimo non possa superare la dimensione di 60. 51