PM-06 p. 1/28 Programozási módszertan Dinamikus programozás: szerelőszalag ütemezése Mátrixok véges sorozatainak szorzása Werner Ágnes Villamosmérnöki és Információs Rendszerek Tanszék e-mail: werner.agnes@virt.uni-pannon.hu
PM-06 p. 2/28 Dinamikus programozás jellemzői Egy dinamikus programozási algoritmus kifejlesztése 4 lépésre bontható fel: 1. Jellemezzük az optimális megoldás szerkezetét. 2. Rekurzív módon definiáljuk az optimális megoldás értékét. 3. Kiszámítjuk az optimális megoldás értékét alulról felfelé történő módon. 4. A kiszámított információk alapján megszerkesztünk egy optimális megoldást. A 1-3. lépések jelentik az alapját annak, ahogy a dinamikus programozás meg tud oldani egy feladatot.
Szerelőszalag ütemezése PM-06 p. 3/28
PM-06 p. 4/28 Feladat Egy autógyár autókat állít elő az egyik gyárában, amelynek két szerelőszalagja van. Mindkét szerelőszalag elején egy alváz jelenik meg, melyhez adott számú állomáson hozzászerelik az alkatrészeket, majd a szalag végén távozik a kész autó. Mindegyik szalagnak n állomása van, melyek indexei j = 1, 2,..., n. S ij jelöli az i-edik (i = 1 vagy 2) szalag j-edik állomását. Az első szalag j-edik állomása (S 1j ) ugyanazt a funkciót látja el, mint a második szalag j-edik állomása (S 2j ). A szalagokat különböző időpontokban különböző technológiával építették, ezért előfordulhat, hogy a két szalag azonos állomásán a terméknek különböző időt kell eltöltenie. Az S ij állomáson a műveleti időt a ij jelöli.
PM-06 p. 5/28 Szerelőszalag ütemezése -Példa A teljes leszámlálás számítási ideje Ω(2n). Ez nagy n mellett elfogadhatatlan.
PM-06 p. 6/28 1. lépés: a legrövidebb gyártási út szerkezete Tekintsük a lehetséges legrövidebb utat, ahogy egy alváz a kiindulási helyzetből túljut az S 1j állomáson. Ha j = 1, akkor csak egy lehetőség van, és így könnyű meghatározni a szükséges időt. j = 2,...,n esetén két lehetőség van: Az alváz érkezhet közvetlenül az S 1,j 1 állomásról, amikor ugyanannak a szalagnak a (j 1)-edik állomásáról a j-edik állomására való átszállítás ideje elhanyagolható. Az alváz S 2,j 1 felől érkezik, az átszállítás ideje t 2,j 1. Tegyük fel, hogy az S 1 j állomáson való túljutás leggyorsabb módja az, hogy oda az S 1,j 1 felől érkezünk. Az alváznak a legrövidebb módon kell túljutnia az S 1,j 1 állomáson, mert ha volna egy gyorsabb mód, hogy az alváz túljusson a S 1,j 1 állomáson, akkor ezt használva magán S 1,j -n is hamarabb jutna túl, ami ellentmondás.
PM-06 p. 7/28 1. lépés: a legrövidebb gyártási út szerkezete Általánosabban fogalmazva azt mondhatjuk, hogy a szerelőszalag ütemezésének (hogy megtaláljuk a legrövidebb módot az S ij állomáson való túljutásra) optimális megoldása tartalmazza egy részfeladat (vagy az S 1,j 1 vagy az S 2,j 1 állomáson való leggyorsabb áthaladás) optimális megoldását. Erre a tulajdonságra optimális részstruktúraként fogunk hivatkozni. Azaz részfeladatok optimális megoldásaiból megszerkeszthető a feladat optimális megoldása.
PM-06 p. 8/28 2. lépés: a rekurzív megoldás Az optimális megoldás értékét a részfeladatok optimális értékeiből rekurzívan fejezzük ki. A részfeladatok legyenek mindkét szalag j-edik állomásán való leggyorsabb áthaladás megkeresésének a feladatai j = 1,...,n mellett. Jelölje f i [j] azt a legrövidebb időt, ami alatt az alváz túl tud jutni az S ij állomáson. Célunk annak a legrövidebb időnek a meghatározása, ami alatt az alváz az egész üzemen keresztül tud haladni. Ezt az időt f jelöli. f = min{f 1 [n] + x 1,f 2 [n] + x 2 } f 1 [1] = e 1 + a 11 f 2 [1] = e 2 + a 21
PM-06 p. 9/28 2. lépés: a rekurzív megoldás Hogyan kell kiszámolni az f i [j]-t j = 2,...,n és i = 1,2 esetén? f 1 [j] = min{f 1 [j 1]+a 1j,f 2 [j 1]+t 2,j 1 +a 1j }, ha j = 2,...,n. f 2 [j] = min{f 2 [j 1]+a 2j,f 1 [j 1]+t 1,j 1 +a 2j }, ha j = 2,...,n. A következő rekurzív egyenletet kapjuk: f 1 [j] = f 2 [j] = { { e 1 + a 11, ha j = 1, min{f 1 [j 1] + a 1j,f 2 [j 1] + t 2,j 1 + a 1j }, ha j 2 e 2 + a 21, ha j = 1, min{f 2 [j 1] + a 2j,f 1 [j 1] + t 1,j 1 + a 2j }, ha j 2
PM-06 p. 10/28 2. lépés: a rekurzív megoldás Az f i [j] mennyiségek a részfeladatok optimális érékei. Annak érdekében, hogy vissza tudjuk keresni a legrövidebb utat, definiáljuk l i [j]-t mint azt a szerelőszalagot, amelyiknek a j 1-edik állomását használtuk az S ij -n való leggyorsabb keresztülhaladáskor. Itt i = 1,2 és j = 2,...,n. (Nem definiáljuk l i [1]-et, mert S i1 -t egyik szalagon sem előzi meg másik állomás.) Az l szalag definíció szerint az, amelyiknek az utolsó állomását használjuk az egész üzemen való áthaladáskor. Az l i [j] értékek segítségével lehet nyomon követni a legrövidebb utat.
PM-06 p. 11/28 3. lépés: a legrövidebb átfutási idő kiszámítása Sokkal jobban járunk, ha az f i [j] értékeket más sorrend szerint számoljuk, mint az a rekurzív módszerből adódik. Vegyük észre, hogy j 2 esetén f i [j] csak f 1 [j 1] -től és f 2 [j 1] -től függ. Ha az f i [j] értékeket az állomások j indexének növekvő sorrendjében számoljuk, akkor a legrövidebb átfutási idő meghatározása Θ(n) ideig tart.
PM-06 p. 12/28 3. lépés: a legrövidebb átfutási idő kiszámítása ALGORITMUS1(a,t,e,x,n) 1. f 1 [1] := e 1 + a 11 f 2 [1] := e 2 + a 21 2. for j := 2 to n 3. do if f 1 [j 1] + a 1j f 2 [j 1] + t 2,j 1 + a 1j 4. then f 1 [j] := f 1 [j 1] + a 1j l 1 [j] := 1 5. else f 1 [j] := f 2 [j 1] + t 2,j 1 + a 1j l 1 [j] := 2 6. if f 2 [j 1] + a 2j f 1 [j 1] + t 1,j 1 + a 2j 7. then f 2 [j] := f 2 [j 1] + a 2j l 2 [j] := 2 8. else f 2 [j] := f 1 [j 1] + t 1,j 1 + a 2j l 2 [j] := 1 9. if f 1 [n] + x 1 f 2 [n] + x 2 10. then f = f 1 [n] + x 1 l = 1 11. else f = f 2 [n] + x 2 l = 2
PM-06 p. 13/28 4. lépés: a legrövidebb átfutási idejű út f i [j], f, l i [j] és l kiszámítását követően meg kell szerkeszteni az üzemen való legrövidebb áthaladást biztosító utat. Az eljárás az út állomásait az indexek csökkenő sorrendjében nyomtatja ki. ALGORITMUS2(l,n) 1. i := l 2. print i"-edik szalag" n"-edik állomás" 3. for j := n downto 2 4. do i := l i [j] 5. print i"-edik szalag (" j 1")-edik állomás"
Mátrixok véges sorozatainak szorzása PM-06 p. 14/28
PM-06 p. 15/28 Feladat Feladat: Legyenek A 1,A 2,...,A n adott mátrixok. Számítsuk ki a mátrixok A 1 A 2...A n szorzatát. Definíció: Mátrixok egy szorzata teljesen zárójelezett, ha vagy egyetlen mátrix, vagy két zárójelbe tett teljesen zárójelezett mátrixszorzat szorzata. Megjegyzés: A mátrixok szorzása asszociatív művelet.
PM-06 p. 16/28 Algoritmus-Kód Két mátrix összeszorzásának algoritmusa (pszeudokód): MÁTRIXSZORZÁS(A,B) 1. if oszlop[a] sor[b] 2. then error "nem összeillő dimenzió" 3. else for i 1 to sor[a] 4. do for j 1tooszlop[B] 5. do C[i, j] 0 6. for k 1 to oszlop[a] 7. do C[i, j] C[i, j] + A[i, kb[k, j] 8. return C Szorzatmátrix mérete: Számítási idő: pqr A pxq B qxr = C pxr
PM-06 p. 17/28 Véges sok mátrix összeszorzásának problémája Legyen (A 1,...,A n ) mátrixok egy adott véges sorozata, ahol az A i mátrix mérete p i 1 p i (i = 1,...,n). Keressük az A 1 A 2...A n sorozat azon teljes zárójelezését, mely minimalizálja a szorzat kiszámításához szükséges skalár szorzások számát. Cél: a szorzás optimális sorrendjének megállapítása, a szorzást nem végezzük el.
PM-06 p. 18/28 Zárójelezések vizsgálata Zárójelezések száma: Legyen P(n) az n mátrix zárójelezéseinek száma. P(1) = 1 Tegyük fel, hogy ha n 2, akkor a sorozatot a k-dik és a k + 1-dik eleme között szétvágva a két részsorozatra a zárójelezések száma egymástól függetlenül meghatározható (k = 1,...,n 1) Rekurzív formula: { P(n) = 1, ha n = 1, n 1 k=1 P(k)P(n k), ha n 2 A megoldás nagyságrendje: Ω(2 n ) Az összes lehetséges zárójelezés megvizsgálása ("nyers erő" módszerrel) nem hatékony!
PM-06 p. 19/28 1. Az optimális zárójelezés szerkezete Optimális megoldás a részfeladatok optimális megoldásából: Keressük azt az alkalmas optimális részstruktúrát, mely felhasználható a probléma optimális megoldásának létrehozásához a részproblémák optimális megoldásaiból. Az optimális zárójelezés szerkezete: Jelölje A i j az A i A i+1...a j szorzat eredményét. Ha i < j, akkor az optimális zárójelezés két részre vágja a sorozatot valamely A k és A k+1 mátrix között (i k < j) Az A i..j mátrixot megkapjuk, ha összeszorozzuk az A i..k és A k+1..j mátrixokat; koltseg(a i..j ) = koltseg(a i..k ) + koltseg(a k+1..j ) + koltseg(a i..k A k+1..j ) Megjegyzés: Az optimális zárójelezésben az A i..k és A k+1..j részsorozatok zárójelezésének is optimálisnak kell lennie!
PM-06 p. 20/28 2. Rekurzív megoldás Részprobléma: A i A i+1...a j szorzat optimális zárójelezése, ahol 1 i j n. Legyen m[i,j] az A i..j mátrix számításához szükséges skalár szorzások minimális száma. Az A i..k A k+1..j szorzat számításának költsége a korábbiak alapján: p i 1 p k p j m[i, j] számítása: m[i, j] = { 0, ha i = j, min i k<j {m[i,k] + m[k + 1,j] + p i 1 p k p j }, ha i < j Megjegyzés: A k értékét ugyan nem ismerjük, de csak j i féle lehet: k = i,i + 1,...,j 1, ezekből választjuk a legjobbat.
PM-06 p. 21/28 Optimális költség számítása A rekurzív algoritmus időigénye exponenciális, nem jobb, mint az összes zárójelezés vizsgálata, viszont a részfeladatok száma alacsony: ahány i,j pár kielégíti az 1 i j n feltételt: n(n + 1)/2 = Θ(n2) (az algoritmus egy-egy részfeladattal többször is foglalkozhat a rekurziós fa különböző ágaiban)
PM-06 p. 22/28 3. Alulról felfelé történö megközelítés: A táblázat kitöltésénél fontos a sorrend: j i + 1 db mátrix m[i,j] összeszorzási költségének számításához csak j i + 1-nél rövidebb szorzatokat használunk: k = i,i + 1,...,j 1 esetén A i..k mátrix k i + 1 < j i + 1 mátrix szorzata, A k+1..j mátrix j k < j i + 1 mátrix szorzata. az m tömböt a szorzatok növekvő hossza szerint kell kitölteni. Legyen s[i,j] az a k index, melynél az optimális zárójelezés az A i..j szorzatot kettévágja.
Algoritmus (pszeudokód) MÁTRIX-SZORZÁS-SORREND(p) 1. n hossz[p] 1 2. for i 1 to n 3. do m[i, i] 0 4. for l 2 to n 5. do for i 1 to n l + 1 6. do j i + l 1 7. m[i, j] 8. for k i to j 1 9. do q m[i, k] + m[k + 1, j] + p i 1 p k p j 10. if q < m[i, j] 11. then m[i, j] q 12. s[i, j] k 13. return m és s Input: p =< p 0, p 1,..., p n >, rendre a p i 1 p i dimenziójú A i mátrixok méretei (i = 1,2,..., n) hossz[p] = n + 1 PM-06 p. 23/28
PM-06 p. 24/28 Végrehatás először az m[i,i] = 0 (i = 1,2,...,n) hozzárendelés végrehajtása, azaz az 1 hosszú sorozatok számítása, majd az m[i, j] -re vonatkozó rekurzív egyenlet segítségével az m[i,i + 1] (i = 1,2,...,n 1) értékek meghatározása, azaz az l = 2 hosszú sorozatok számítása, az m[i,i + 2] (i = 1,2,...,n 2) értékek meghatározása, azaz az l = 3 hosszú sorozatok számítása, stb. m[i,j] csak a korábban már meghatározott m[i,k] és m[k + 1,j] elemektől függ. Futásidő: O(n 3 ), mert l,i,k ciklusváltozók mindegyike legfeljebb n értéket vehet fel. (valójában Ω(n 3 ))
PM-06 p. 25/28 Az optimális megoldás előállítása Az s tömb felhasználásával: s[i,j] az a k index, amely után az A i..j sorozatot vágjuk. Algoritmus (pszeudokód): OPTIMÁLIS-ZÁRÓJELEZÉS-NYOMTATÁSA(s, i, j) 1. if j = i 2. then print A i 3. else print ( 4. OPTIMÁLIS-ZÁRÓJELEZÉS-NYOMTATÁSA(s, i, s[i, j]) 5. OPTIMÁLIS-ZÁRÓJELEZÉS- NYOMTATÁSA(s,s[i,j] + 1,j) 6. print ) Kezdeti hívás: OPTIMÁLIS-ZÁRÓJELEZÉS-NYOMTATÁSA(s, 1, n)
PM-06 p. 26/28 Példa Pl.: A 2..5 részsorozat optimális összeszorzása: p 0 = 30, p 1 = 35, p 2 = 15, p 3 = 5, p 4 = 10, p 5 = 20, p 6 = 25 m[2, 5] = min m[2,2] + m[3,5] + p 1 p 2 p 5 = 0 + 2500 + 35 15 20 = 13000 m[2,3] + m[4,5] + p 1 p 3 p 5 = 2625 + 1000 + 35 5 20 = 7125 m[2,4] + m[4,5] + p 1 p 4 p 5 = 4375 + 0 + 35 10 20 = 11375 A hat mátrix összeszorzásához minimálisan m[1, 6] = 15125 skalár szorzás kell.
PM-06 p. 27/28 A zárójelezés meghatározása rekurzívan A zárójelezés meghatározása rekurzívan az s tömb segítségével
PM-06 p. 28/28 Az A 1..n szorzat optimális kiszámítása Az utolsó mátrixszorzás: A 1..s[1,n] A s[1,n]+1..n A korábbi mátrixszorzások számítása rekurzívan: A 1..s[1,n] számításakor vágás s[1,s[1,n]] mögött A s[1,n]+1..n számításakor vágás s[s[1,n] + 1,n] előtt Rekurzív hívások sorrendje: [1,6] ([1,3]([1,1] A1 [2,3]([2,2] A2 [3,3] A3 )) [4,6]([4,5]([4,4] A4 [5,5] A5 )[6,6] A6 )) Optimális zárójelezés: ((A1(A2A3))((A4A5)A6))