optimalizációs módszerek Titkos utazás Réges-régen egy messzi-messzi galaxisban Készítette: Gelencsér Tamás xdthsq
1. Bevezetés: Nehéz idők járnak a Lázadókra. Habár a Halálcsillagot elpusztították, a Birodalmi erők kiűzték őket titkos támaszpontjukról és végigüldözték őket a Galaxis-on.A rettegett Birodalmi Csillagflotta elől menekülve a szabadságért küzdők maroknyi csapata, Luke Skywalker vezetésével új, titkos bázist létesített a távoli Hoth jégvilágában. A gonosz Vader nagyúr parancsára, távkutászok ezrei rajzottak ki az űrbe, hogy az ifjú Skywalker nyomára leljenek Menekülés közben, Luke Skywalker egy volt Birodalmi kommandóst (Kyle Katarn) küld a Vjun rendszerbe, Vader nagyúr erődjébe, hogy az ősi jedi holokronok lehetséges lelőhelyéről térképeket és információkat gyűjtsön. A pontosan megtervezett visszaút, nagyban hozzájárul a küldetés sikeréhez 2. Információk az utazásról: A visszaútról a következő ábra áll a rendelkezésre, ahol a piros a birodalmi, a kék a semleges, a zöld pedig a Szövetséges bolygókat jelöli. A nyilak a lehetséges útvonalakat jelölik (fekete-barna között nincs különbség): Továbbá minden bolygóról rendelkezünk egy menetrenddel, ami tartalmazza az utazásidőt és a várakozásidőt is: Honnan Hova: Taris Chazwa Taanab Nar Shaddaa Vjun 10 5 4 7 Honnan Hova: Vortex Carnatos Balmora Manaan Taris 12 8 7 N/A Chazwa 7 5 4 5 Taanab N/A 6 7 6 Nar Shaddaa N/A 8 9 7
Honnan Hova: Galantos Coruscant Corellia Vortex 12 10 N/A Carnatos 8 5 7 Balmora 9 7 5 Manaan 13 8 10 Honnan Hova: Codian Moon Byss Devaron Tyana Galantos 15 10 N/A N/A Coruscant N/A 8 9 10 Corellia N/A 12 9 7 Honnan Hova: Cerea Ghorman Umgul Codian Moon 5 N/A N/A Byss N/A 8 N/A Devaron N/A 10 N/A Tyana N/A 9 12 Honnan Hova Lorta Nkllon Hoth Cerea 8 5 N/A Ghorman 7 5 N/A Umgul N/A N/A 6 Lorta N/A N/A 4 Nkllon N/A N/A 5
A rendszer magja felé egyre nagyobb a veszélye a lebukásnak (egyre több az ellenőrző pont), illetve a Birodalmi bolygókon drágábban lehet csak megfelelően biztonságos szállást találni. Ezeket az adatokat az alábbi táblázat foglalja össze: Bolygó neve: Szállás: Ellenőrzőpontok száma: Taris 100 1 Chazwa 220 3 Taanab 220 3 Nar Shaddaa 100 1 Vortex 220 1 Carnatos 220 5 Balmora 220 5 Manaan 220 3 Galantos 220 5 Coruscant 220 10 Corellia 220 5 Codian Moon 100 1 Byss 220 5 Devaron 220 5 Tyana 220 3 Cerea 0 0 Ghorman 0 0 Umgul 100 1 Lorta 100 1 Nkllon 0 0 A visszaútra 800 kredit áll rendelkezésre, és az ügynök maximum 15 ellenőrzőponton tud észrevétlenül átjutni. Az indulásig még 3 nap van hátra, így még kaphatunk plusz információkat a Bothán Kémhálózattól, ami megváltoztathatja a visszaút megtervezését.
3. A visszaút megtervezése: A csillagtérképet a legegyszerűbb módon egy gráfként tudjuk értelmezni, ahol a bolygók a csúcsok és a lehetséges útvonalak az őket összekötő éleknek felnek meg. Számunkra az utazás a fontos (tehát az élekre koncentrálunk), nem pedig az, hogy melyik bolygókat érintettük, így a bolygókhoz egy sorszámot rendelünk, ezzel leegyszerűsítve a kezelésüket: 1. Vjun 2. Taris 3. Chazwa 4. Taanab 5. Nar Shaddaa 6. Vortex 7. Carnatos 8. Balmora 9. Manaan 10. Galantos 11. Coruscant 12. Corellia 13. Codian Moon 14. Byss 15. Devaron 16. Tyana 17. Cerea 18. Ghorman 19. Umgul 20. Lorta 21. Nkllon 22. Hoth A következő lépésben a fent meghatározott táblázatokból kinyerjük a szükséges információkat és egy mátrixba rendezzük őket (bolygók számozással): Honnan-Hova : út szállás: ellenőrzőpont: 1 2 10 100 1 1 3 5 220 3 1 4 4 220 3 1 5 7 100 1 2 6 12 100 1 2 7 8 220 5 2 8 7 220 5 3 6 7 100 1 3 7 5 220 5 3 8 4 220 5 3 9 5 220 3 4 7 6 220 5 4 8 7 220 5 4 9 6 220 3 5 7 8 220 5 5 8 9 220 5 5 9 7 220 3 6 10 12 220 5 6 11 10 220 10 7 10 8 220 5 7 11 5 220 10 7 12 7 220 5 8 10 9 220 5 8 11 7 220 10 8 12 5 220 5 9 10 13 220 5 9 11 8 220 10 9 12 10 220 5 10 13 15 100 1 10 14 10 220 5 11 14 8 220 5 11 15 9 220 5 11 16 10 220 3 12 14 12 220 5 12 15 9 220 5 12 16 7 220 3 13 17 5 0 0 14 18 8 0 0 15 18 10 0 0 16 18 9 0 0 16 19 12 100 1 17 20 8 100 1 17 21 5 0 0 18 20 7 100 1 18 21 5 0 0 19 22 6 0 0 20 22 4 0 0 21 22 5 0 0
Feltételek meghatározása: a.) A legfontosabb feltétel, aminek mindenképpen eleget kell tennünk, hogy utat tervezzünk: tehát, ha egy csúcsba bemegyünk, onnan ki is kell jönnünk. A legegyszerűbb megoldás, ha kezdő ponthoz egy bemenő élt a végponthoz egy kimenő élt rendelünk, így biztos, hogy az algoritmus a két pont között keresi az utat. b.) Továbbá, felső korlátunk van az elkölthető kreditre illetve az ellenőrző pontok maximális számára, amit figyelembe kell vennünk az algoritmus tervezésekor. Ha az előbb említett feltételeknek eleget teszünk, akkor már csak a cél függvényt kell minimalizálni, azaz meg kell keresni a legrövidebb utat. 4. GLPK A feladat megoldását két fájlban oldottam meg (Windows-t használok, így hazi.m.txt illetve hazi.d.txt a kiterjesztés). Hazi.m.txt: param koltseg{(i,j) in HonnanHova}; /*Bolygon tartozkodas koltsege*/ param danger{(i,j) in HonnanHova}; /*Bolygon tartozkodas veszelyessege*/ param start, integer > 0; /*Kezdo bolygo*/ param cel, integer > 0; /*Cel bolygo*/ param penz, integer > 0; /*Rendelkezesre allo kredit*/ param veszely, integer > 0; /*Rejtezkodes*/ var x{(i,j) in HonnanHova}, binary; /*Változó ami az éleket jelöli ki, utaztunk vagy nem*/ s.t. beelkiel{i in 1..Bolygokszama}: sum{(j,i) in HonnanHova} x[j,i] + (if i = start then 1) = sum{(i,j) in HonnanHova} x[i,j] + (if i = cel then 1); /*Azt vizsgaljuk, ha bolygora elmentunk onnan el is kell jonnunk*/ s.t. szallas: sum{(i,j) in HonnanHova} (x[i,j] *koltseg[i,j]) <= penz; /*Szallast kitudjuk-e fizetni*/ s.t. lebukas: sum{(i,j) in HonnanHova} (x[i,j] *danger[i,j]) <= veszely; /*Elkerulheto-e a lebukas*/ minimize utazas: sum{(i,j) in HonnanHova} ut[i,j] * x[i,j];
A program megírás közben arra törekedtem, hogy minél kevésbé legyen bedrótozva, ezért amit csak lehetett paraméterként definiáltam: param start, cel, veszely, penz s.t. beelkiel{i in 1..Bolygokszama}: sum{(j,i) in HonnanHova} x[j,i] + (if i = start then 1) = sum{(i,j) in HonnanHova} x[i,j] + (if i = cel then 1); Minden csúcsra ellenőrzi, hogy a belépő élek száma megegyezik-e a kilépő élek számával (esetünkben 1 ki 1 be). s.t. szallas: sum{(i,j) in HonnanHova} (x[i,j] *koltseg[i,j]) <= penz; A kiválasztott élekhez tartozó szállás költség szummája belefér-e a keretbe. s.t. lebukas: sum{(i,j) in HonnanHova} (x[i,j] *danger[i,j]) <= veszely; A kiválasztott élekhez tartozó ellenőrzőpontok száma kisebb-e, mint a megadott összeg. minimize utazas: sum{(i,j) in HonnanHova} ut[i,j] * x[i,j]; A fenti feltételekkel minimalizáljuk a utazás időtartalmát. Az adatokat a Hazi.d.txt fájlba töltöttem fel és futtattam a Hazi.m.txt modellre. A jelenlegi adatokkal a következő megoldást kaptam: 1-5 5-8 8-12 12-16 16-18 18-21 21-22, ami azt jelenti, hogy a legrövidebb út: Vjun Nar Shaddaa Balmora Corellia Tyana Ghorman Nkllon Hoth. Idő: 47 nap, Költség: 760 kredit, Ellenőrzőpont: 14. MAY THE Force Be with You!!!
Függelék: Hazi.m.txt: param Bolygokszama, integer > 0; /*Grafcsucsai*/ set HonnanHova, within {i in 1..Bolygokszama, j in 1..Bolygokszama}; /*Grafelei*/ param ut{(i,j) in HonnanHova}; /*Grafeleinek a sulya*/ param koltseg{(i,j) in HonnanHova}; /*Bolygon tartozkodas koltsege*/ param danger{(i,j) in HonnanHova}; /*Bolygon tartozkodas veszelyessege*/ param start, integer > 0; /*Kezdo bolygo*/ param cel, integer > 0; /*Cel bolygo*/ param penz, integer > 0; /*Rendelkezesre allo kredit*/ param veszely, integer > 0; /*Rejtezkodes*/ var x{(i,j) in HonnanHova}, binary; /*Változó ami az éleket jelöli ki, utaztunk vagy nem*/ s.t. beelkiel{i in 1..Bolygokszama}: sum{(j,i) in HonnanHova} x[j,i] + (if i = start then 1) = sum{(i,j) in HonnanHova} x[i,j] + (if i = cel then 1); /*Azt vizsgaljuk, ha bolygora elmentunk onnan el is kell jonnunk*/ s.t. szallas: sum{(i,j) in HonnanHova} (x[i,j] *koltseg[i,j]) <= penz; /*Szallast kitudjuk-e fizetni*/ s.t. lebukas: sum{(i,j) in HonnanHova} (x[i,j] *danger[i,j]) <= veszely; /*Elkerulheto-e a lebukas*/ minimize utazas: sum{(i,j) in HonnanHova} ut[i,j] * x[i,j]; /*A fenti feltetelek mellett a legrovidebb utat keressuk*/
Data.m.txt: /*Az adott parameterek tarolasara*/ param Bolygokszama:= 22; param start := 1; param cel := 22; param penz := 800; param veszely := 15; param : HonnanHova : ut koltseg danger:= 1 2 10 100 1 1 3 5 220 3 1 4 4 220 3 1 5 7 100 1 2 6 12 100 1 2 7 8 220 5 2 8 7 220 5 3 6 7 100 1 3 7 5 220 5 3 8 4 220 5 3 9 5 220 3 4 7 6 220 5 4 8 7 220 5 4 9 6 220 3 5 7 8 220 5 5 8 9 220 5 5 9 7 220 3 6 10 12 220 5 6 11 10 220 10 7 10 8 220 5 7 11 5 220 10 7 12 7 220 5 8 10 9 220 5 8 11 7 220 10 8 12 5 220 5 9 10 13 220 5 9 11 8 220 10 9 12 10 220 5 10 13 15 100 1 10 14 10 220 5 11 14 8 220 5 11 15 9 220 5 11 16 10 220 3 12 14 12 220 5 12 15 9 220 5 12 16 7 220 3 13 17 5 0 0 14 18 8 0 0 15 18 10 0 0 16 18 9 0 0 16 19 12 100 1 17 20 8 100 1 17 21 5 0 0 18 20 7 100 1 18 21 5 0 0 19 22 6 0 0 20 22 4 0 0 21 22 5 0 0;
Eredmény: Problem: hazi Rows: 25 Columns: 48 (48 integer, 48 binary) Non-zeros: 222 Status: INTEGER OPTIMAL Objective: utazas = 47 (MINimum) No. Row name Activity Lower bound Upper bound ------ ------------ ------------- ------------- ------------- 1 beelkiel[1] -1-1 = 2 beelkiel[2] 0-0 = 3 beelkiel[3] 0-0 = 4 beelkiel[4] 0-0 = 5 beelkiel[5] 0-0 = 6 beelkiel[6] 0-0 = 7 beelkiel[7] 0-0 = 8 beelkiel[8] 0-0 = 9 beelkiel[9] 0-0 = 10 beelkiel[10] 0-0 = 11 beelkiel[11] 0-0 = 12 beelkiel[12] 0-0 = 13 beelkiel[13] 0-0 = 14 beelkiel[14] 0-0 = 15 beelkiel[15] 0-0 = 16 beelkiel[16] 0-0 = 17 beelkiel[17] 0-0 = 18 beelkiel[18] 0-0 = 19 beelkiel[19] 0-0 = 20 beelkiel[20] 0-0 = 21 beelkiel[21] 0-0 = 22 beelkiel[22] 1 1 = 23 szallas 760 800 24 lebukas 14 15 25 utazas 47 No. Column name Activity Lower bound Upper bound ------ ------------ ------------- ------------- ------------- 1 x[1,2] * 0 0 1 2 x[1,3] * 0 0 1 3 x[1,4] * 0 0 1 4 x[1,5] * 1 0 1 5 x[2,6] * 0 0 1 6 x[2,7] * 0 0 1 7 x[2,8] * 0 0 1 8 x[3,6] * 0 0 1 9 x[3,7] * 0 0 1 10 x[3,8] * 0 0 1 11 x[3,9] * 0 0 1 12 x[4,7] * 0 0 1 13 x[4,8] * 0 0 1 14 x[4,9] * 0 0 1
15 x[5,7] * 0 0 1 16 x[5,8] * 1 0 1 17 x[5,9] * 0 0 1 18 x[6,10] * 0 0 1 19 x[6,11] * 0 0 1 20 x[7,10] * 0 0 1 21 x[7,11] * 0 0 1 22 x[7,12] * 0 0 1 23 x[8,10] * 0 0 1 24 x[8,11] * 0 0 1 25 x[8,12] * 1 0 1 26 x[9,10] * 0 0 1 27 x[9,11] * 0 0 1 28 x[9,12] * 0 0 1 29 x[10,13] * 0 0 1 30 x[10,14] * 0 0 1 31 x[11,14] * 0 0 1 32 x[11,15] * 0 0 1 33 x[11,16] * 0 0 1 34 x[12,14] * 0 0 1 35 x[12,15] * 0 0 1 36 x[12,16] * 1 0 1 37 x[13,17] * 0 0 1 38 x[14,18] * 0 0 1 39 x[15,18] * 0 0 1 40 x[16,18] * 1 0 1 41 x[16,19] * 0 0 1 42 x[17,20] * 0 0 1 43 x[17,21] * 0 0 1 44 x[18,20] * 0 0 1 45 x[18,21] * 1 0 1 46 x[19,22] * 0 0 1 47 x[20,22] * 0 0 1 48 x[21,22] * 1 0 1 Integer feasibility conditions: KKT.PE: max.abs.err = 0.00e+000 on row 0 max.rel.err = 0.00e+000 on row 0 High quality KKT.PB: max.abs.err = 0.00e+000 on row 0 max.rel.err = 0.00e+000 on row 0 High quality End of output