Problém batohu - metodami DP a větví a hranic

Zadání

  1. Naprogramujte řešení 0/1 problému batohu metodou větví a hranic tak, aby omezujícím faktorem byla hodnota optimalizačního kritéria.
  2. Naprogramujte řešení 0/1 problému batohu nebo alespoň 0/1 exaktního problému batohu bez cen metodou dynamického programování.
  3. Naprogramujte řešení 0/1 problému batohu heuristikou podle poměru cena/hmotnost s testem nejtěžší věci.

Použité algoritmy

V této úloze byly použity již dřívě implementované metody (hrubá síla, 3 heuristiky). Dále zde byli použity 3 metody dynamického programování (s/bez dopředné fáze a cenaXvěci). Dalšími třemi metodami jsou vylepšené heuristiky o test nejcenější věci. Apliakce obsahuje celkem 11 metoh.

Příklad

Nechť n=5, V=(2,6,5,3,4), C=(5,9,20,12,18), a M = 10. Začneme ve sloupci n=0 a postupně plníme tabulku doprava. Výsledné řešení je určeno polem v posledním sloupci, které obsahuje váhu menší než M a má maximální index. Jestliže pole (n-1,c) obsahuje váhu stejnou jako pole (n,c), pak n-tá věc není součástí optimálního řešení  Takto se dá rekonstruovat vektor X z tabulky.

Legenda:

 
výsledné řešení
 
rekonstrukce X
 
triviální instance
 
hodnoty větší než M není nutno zaznamenávat

prázdné pole má hodnotu nekonečno

W(n,c)

64
 




20
63
 





62
 





61
 





60
 





59
 




18
58
 





57
 





56
 





55
 




14
54
 





53
 





52
 




17
51
 





50
 




12
49
 





48
 





47
 




15
46
 



16
16
45
 





44
 




15
43
 




11
42
 





41
 



14
14
40
 





39
 




13
38
 




9
37
 



10
10
36
 





35
 




9
34
 


13
13
13
33
 





32
 



8
8
31
 





30
 




7
29
 


11
11
11
28
 





27
 




10
26
 



11
11
25
 


7
7
7
24
 





23
 




6
22
 





21
 



9
9
20
 


5
5
5
19
 





18
 




4
17
 



5
5
16
 





15
 





14
 

8
8
8
8
13
 





12
 



3
3
11
 





10
 





9
 

6
6
6
6
8
 





7
 





6
 





5
 
2
2
2
2
2
4
 





3
 





2
 





1
 





0
0
0
0
0
0
0
n
0
1
2
3
4
5
V

2
6
5
3
4
C

5
9
20
12
18

Dekompozice podle kapacity batohu

Nechť (Xn, Cn, m) = KNAP (V, C, M) je algoritmus řešící instanci problému batohu danou (V, C, M) a vracející vektor X, celkovou cenu Cn a celkovou váhu m. Pak můžeme KNAP napsat jako následující pseudokód, kde tečka je operátor zřetězení:

function KNAP (V, C, M)
    if isTrivial (V, C, M) return trivialKNAP (V, C, M);
    (X0, C0, m0) = KNAP (V-{vn}, C-{cn}, M);

    (X1, C1, m1) = KNAP (V-{vn}, C-{cn}, M-vn);
    if C1+cn > C0 return (X1.1,  C1+cn, m1+vn);
    return (X0.0, C0, m0);

function isTrivial (V, C, M)
    return (isEmpty (V) or M=0 or M<0);

Abychom stanovili optimální řešení pro n věcí, musíme znát
  • optimální řešení problému s vyjmutou n-tou věcí (v případě, že n-tá věc v optimálním řešení není), a
  • optimální řešení problému s vyjmutou n-tou věcí a kapacitou batohu sníženou o hmotnost té věci (v případě, že n-tá věc je součástí optimálního řešení).
Srovnáme-li oě varianty, zjistíme, zda n-tá věc má být v optimálním řešení. Tím jsme optimální řešení instance o n prvcích převedli na optimální řešení dvou instancí o n-1 prvcích. Rekurze se zastaví u instancí, které jsou řešitelné v konstantním čase. Funkci trivialKNAP přenecháme laskavému čtenáři jako cvičení.

Až dosud uvbedený algoritmus je hledáním do šířky. Protože pokaždé voláme funkci dvakrát a hloubka rekurze je n, je složitost 2n. Nicméně, některé instance řešíme vícekrát a můžeme tedy uschovávat řešení. Protože podúlohy pracují vždy s i prvými věcmi a množiny V and C lze považovat za globální, každá podúloha je charakterizována hodnotami n a M. Proto pamět mezivýsledků můžeme uspořádat do dvourozměrného pole indexovaného hodnotami n a M. Pole má  nM prvků a taková je i složitost algoritmu. Je polynomiální ve velikosti instance, nicméně obsahuje parametr, který s velikostí instance nesouvisí. Takové algoritmy se nazývají pseudopolynomiální.

Dynamické programování mmůžebýt buď složeno z dopředné a zpětné fáze nebo může obsahovat jen zpětnou fázi. V dopředné fázi začínáme od původní úlohy v prvku (n, M) pole a rekurzivně označujeme podúlohy, které potřebujeme řešit, až narazíme na triviální podúlohy. Ve zpětné fázi vyřešíme nejprve označené triviální podúlohy (resp. všechny triviální podúlohy, nemáme-li dopřednou fázi). Pak řešíme takové označené (resp. všechny takové) úlohy, které lze řešit pomocí úloh již vyřešených a v tabulce uložených, až dospějeme k celkovému řešení.

Příklad

 Nechť n=5, V=(2,6,5,3,4), C=(5,9,20,12,18), a M = 10. Dopředná fáze začíná s prvkem (5, 10). Abychom tuto úlohu vyřešili, potřebujeme řešení (4,10), pokud pátá věc není v optimálním řešení, a (4,6) v opačném případě.Tento postup se opakuje, až dostaneme triviální podúlohy pro n=0 nebo nekladné M. Pro názornost jsou zachyceny potřebné instance se zápornými kapacitami, ačkoliv jejich řešení je konstantní a nezávislé na parametrech.

Legenda:

 
výsledné řešení
 
netriviální podúloha k řešení
 
triviální podúloha k řešení
 
triviální podúloha, jejíž řešení nepotřebujeme
 
rekonstrukce X


10
 
 
 
 
 
 
9
 





8
 





7
 
 
 
 


6
 
 
 
 
  

5
 
 
 



4
 
 




3
 
 
 
 


2
 
 
 



1
 
 
 



0
 
 
 
 
 
 
-1
 
 
 
 
 
 
-2
 
 
 
 
 
 
-3
 
 
 
 
 
 
-4
 
 
 
 
 
 
n
0
1
2
3
4
5
V

2
6
5
3
4
C

5
9
20
12
18
Zpětná fáze začíná řešením triviálních podúloh a pak dalších ve směru rostoucího n. Dvojice(m, Cn) reprezentuje řešení každé podúlohy.

10
0, 0
2, 5
8, 14
7, 25
10, 37
9, 38
9
0, 0





8
0, 0





7
0, 0
2, 5
6, 9
7, 25


6
0, 0
2, 5
6, 9
5, 20
5, 20

5
0, 0
2, 5
2, 5



4
0, 0
2, 5




3
0, 0
2, 5
2, 5
2, 5


2
0, 0
2, 5
2, 5



1
0, 0
0, 0
0, 0



0
0, 0
0, 0
 
 
 
 
-1
0, -inf
0, -inf
 
 
 
 
-2
 
 
0, -inf
 
 
 
-3
 
0, -inf
 
 
 
 
-4
 
0, -inf
 
 
 
 
-5
 
0, -inf
 
 
 
 
n
0
1
2
3
4
5
V

2
6
5
3
4
C

5
9
20
12
18

Pokud není dopředná fáze, je třeba vyřešit podúlohy ve všech prvcích pole. Na závěr rekonstruujeme vektor X. Jestliže hodnoty v prvku (n, m) jsosu stejné jako v prvku (n-1, m), pak n-tá věc není ve výsledném řešení podúlohy charakterizované (n, m). Tento postup dá optimální řešení i v případě, že obě varianty (s n-tou věcí a bez ní) dávají týž výsledek.

10
0, 0
2, 5
8, 14
7, 25
10, 37
9, 38
9
0, 0
2, 5
8, 14
7, 25
8, 32
9, 35
8
0, 0
2, 5
8, 14
7, 25
8, 32
8, 32
7
0, 0
2, 5
6, 9
7, 25
7, 25
7, 25
6
0, 0
2, 5
6, 9
5, 20
5, 20
5, 23
5
0, 0
2, 5
2, 5
5, 20
5, 17
4, 18
4
0, 0
2, 5
2, 5
2, 5
3, 12
4, 18
3
0, 0
2, 5
2, 5
2, 5
3, 12
2, 5
2
0, 0
2, 5
2, 5
2, 5
2, 5
2, 5
1
0, 0
0, 0
0, 0
0, 0
0, 0
0, 0
0
0, 0
0, 0
0, 0
0, 0
0, 0
0, 0
<0
0, -inf
0, -inf
0, -inf
0, -inf
0, -inf
0, -inf
n
0
1
2
3
4
5
V

2
6
5
3
4
C

5
9
20
12
18

Naměřené hodnoty

Uvedené metody byly měřeny na náhodně generovaných datech s nízskými hodnotamy (cena a váha řádově jako max. váha). Při větším počtu měření a při proložení byl získan tento graf časové složitosti:
Protože doba, za kterou daný algoritmus vypočte výsledek, měřil jsem i počet operací.

Všechny metody

Při měření se všemi metodami je zřejmé, že hrubá síla je příliž náročná a že by pro měření s větším počtem věcí představovala problém:

Bez hrubé síly

Pro výše zmíněné komplikace bylo další měření provedeno bez hrubé síly. Výsledky naznačují, že metoda větví a hran roste také exponenciálně, jen se její náročnost projevuje později.

Bez hrubé síly a metody větví a hranic

V posledním z měření jsem zkoumal pouze heuristiky a dynamické programování.
Na těchto grafech je zřejmé (pominu-li DP s dopřednou fází), že DP má vyšší složitost než heuristiky, ale na měřených datech se chovali lineárně.
U DP s dopřednou fází je počet operací zvýšen tím, že se měří všechny použité iterace a tak roste rychleji než ostatní DP.

Chyby

Další měřenou veličinou byla chyba (odchylka od optimálního řešení) a to jak relativní tak absolutní.
Pro tento účel jsem použil připravené úlohy z předchozího zadání, na kterých jsem testoval všechny metody. Pro časovou náročnost BF a BB jsou zde výsledky do instance 9165.
metoda průměrná relativní průměrná absolutní maximální relativní maximální absolutní
Brutální síla 0% 0 0% 0
Heuristika podle klesající ceny 1% 11 24% 196
Heuristika podle rostoucí hmotnosti 7% 75 65% 366
Heuristika podle cena/hmotnost 1% 8 36% 121
Heuristika podle klesající ceny (s testem) 1% 11 24% 196
Heuristika podle rostoucí hmotnosti (s testem) 6% 71 46% 366
Heuristika podle cena/hmotnost (s testem) 0% 8 24% 121
Metoda větví a hranic 0% 0 0% 0
Dynamické programování: s dopřednou fází 0% 0 0% 0
Dynamické programování: bez dopředné fáze 0% 0 0% 0
Dynamické programování: cena x věci 0% 0 0% 0
Z dané tabulky a teorie je patrné, že posloužila i k samotnému testování, protože DP, BF a BB musí naleznou optimální řešení.

Data

Data byla změřena aplikací a zpracována v MS Excel.
sešit [.xls]

Program

Aplikace je psaná v Javě 1.5 (JBuilder 2006). Pro spuštění bude možná nutné upravit cestu k interpretu v souboru run.bat.
stáhnout

Závěr

Po implementaci všech výše zméíněných metod bylo provedeno měření, z kterého plyne že všechny 3 metody DP, hrubá sílá a metoda větví a hranic vždy nalezne optimální řešení. Heuristiky najdou řešení z max. odchylkou 50% (viz. 1. úloha).
Vylepšené heuristiky o test nejcenější věci je časově náročnější (hledání a porovnávání nejcenější věci), zlepšuje výsledné řešení, ale jen u malé skupiny instancí.
Nejlepší časovou složitost mají heuristiky, dále DP (z nichž DP s dopřednou fází je náročnější pro 2x procházení pole) a nejhorší hrubá síla a metoda větví a hranic.
Metoda větví a hranic je mnohem výhodnější než hrubá síla, ale její průběh také není polynomiální.
Tato měření se prováděla na "rozumných" vstupních zadáních. Proto se zde neprojevila jejich pseudopolynomialita. Rozdíl mezi DP využivající pole hmotnostXvěci a cenaXvěci není výrazný. To je opět proto, že vstupní dana nejsou rozmanitá. Pokud by řád hodnot cen byl mnohem vyšší než hmotnost, resp. naopak, byl by rozdíl značný.