X36PAA, Úloha #4 - Experimentální hodnocení algoritmů pro řešení problému batohu

Vypracoval Michal Turek, cvičení Po 12:45-14:15 (Petr Fišer)


Zadání


Úvod

Pro řešení problému batohu existuje mnoho algoritmů jak exaktních, tak přibližných. O jejich vlastnostech toho není mnoho známo, pouze pro kombinované heuristiky byla dokázána maximální chyba. Chceme-li vědět více, musíme vyhodnocovat experimentálně.

Budeme sledovat dva podstatné parametry - kvalitu řešení a výpočetní náročnost. Uvedeme-li obě tyto veličiny do vztahu, dozvíme se, pro které kombinace nároků na čas a kvalitu je ten který algoritmus nejvýhodnější.

Kvalita řešení

Pro instance, kde známe exaktní řešení, se kvalita dá měřit absolutně. Tam, kde srovnáváme heuristiky mezi sebou, můžeme srovnávat pouze relativně. Tyto dva způsoby hodnocení je potřeba rozlišovat a konzistentně mezi nimi volit.

Výpočetní náročnost

Výpočetní náročnost se měří ještě hůře. Celkový čas výpočtu zahrnuje všechny vlivy, selhává však při porovnání výsledků z různých strojů. Zahrnuje také vlivy, které nejsou důležité - například způsob implementace datových struktur. Proto jako měřítko výpočetní složitosti volíme počet testovaných stavů. Poněvadž celkové počty stavů instancí lze snadno odvodit, máme měřítko účinnosti dané výpočetní metody.


Kvalita řešení

Problém batohu jsme řešili pouze dvěma heuristikami - heuristikou podle poměru cena/hmotnost a heuristikou podle poměru cena/hmotnost s testem nejcennější věci. Chování obou heuristik byla podrobně rozebrána už při minulých úlohách, a proto na tomto místě budou pouze ve stručnosti okomentovány výsledky.

Heuristika podle poměru cena/váha má polynomiální časovou složitost, a proto přináší obrovské časové úspory. Na druhou stranu je patrné, že pro malé počty věcí se dopouští relativně velké chyby, s jejich rostoucím počtem však tato chyba postupně klesá. Chyba je v principu způsobena postupným vkládáním jednotlivých věcí podle nejvyššího poměru cena/váha, kdy se už netestuje, zda by některá kombinace odstatních věcí byla výhodnější.

Druhá z heuristik je kombinací předchozí metody a testu na vložení pouze nejcennější věci. Jelikož vybírá lepší z obou řešení, bude její kvalita, vzhledem k první metodě, vždy lepší, náročnost výpočtu se však nijak výrazně nezvýší a stále bude polynomiální. Je dokonce dokázáno, že odchylka od optimálního řešení může být maximálně 50%.

Metody hrubé síly, dynamického programování i metoda větví a hranic vracejí vždy optimální řešení, a proto je zbytečné, o kvalitě jimi vrácených řešení, jakkoli diskutovat.


Výpočetní náročnost

Základní konfigurace generátoru instancí

Metoda hrubé síly prochází všechny možné kombinace jednotlivých věcí v batohu, a proto je její složitost vždy exponenciální (2n) a nezávisí na žádném z parametrů uvedených v tabulce. Podobně se chovají obě heuristiky, pracují však s polynomiální složitostí. Vzhledem k výše uvedeným důvodům nebudou tyto tři metody z hlediska výpočetní složitosti dále uvažovány.

Následující tabulka definuje implicitní nastavení generátoru instancí, při jednotlivých testech se bude hýbat vždy pouze s jedním parametrem. Pokud by se hýbalo více parametry najednou, daly by se možná najít i jiné závislosti, nicméně by to bylo časově velice náročné.

Parametr Hodnota
Velikost instance 20
Počet instancí  50
Maximální váha věci 100
Maximální cena věci 250
Poměr kapacity batohu k sumární váze 0.6
Charakter granularity Nerozlišovat
Exponent závislosti granularity 1

Aby byly výsledky více vypovídající, je pro každé nastavení konfigurace generováno vždy padesát různých instancí problému (viz parametr Počet instancí), získané hodnoty jsou průměrovány a následně zanášeny do grafu.

Pro měření byly použity implementace jednotlivých metod ze třetí úlohy. Byly upraveny, aby nevypisovaly jednotlivá řešení, ale pouze hodnoty počtu navštívených stavů. (branch_bound.cpp, dynprog.cpp, Makefile, run.sh)

Závislost počtu stavů na velikosti instance

Jak bylo zjištěno už v úloze číslo tři, dynamické programování vychází při vyšších hodnotách počtu instancí mnohem lépe než metoda B&B. Ta se může v nejhorším případě chovat téměř jako metoda hrubou silou, nicméně v praxi se nejhorší konfigurace vyskytují spíše zřídka. Dynamické programování, na druhou stranu, závisí nejen na počtu věcí, ale také na velikosti batohu (pseudopolynomiální složitost).

Počet stavů
n Dynamické programování B&B
05 924 24
10 3324 253
15 7161 1429
20 12392 9890
25 19853 69985
30 28052 638518
35 37512 5009287
40 48343 26312804
Graf závislosti počtu navštívených stavů na velikosti instance

Závislost počtu stavů na poměru kapacity batohu k sumární váze věcí

Optimální řešení se může skládat z několika málo věcí nebo z téměř všech věcí. Podle toho, "z které strany" řešení hledáme, můžeme prozkoumat větší nebo menší část stavů. Pro poměr větší než jedna je pochopitelně řešením soubor všech věcí. Zadáme-li maximální váhu věci a rozložení (granularitu), je tím (statisticky) určena i sumární váha. Proto kapacitu batohu určujeme nepřímo, poměrem k sumární váze.

Počet stavů
kapacita / ∑ váha Dynamické programování B&B
0.1 2174 1463
0.2 4263 9806
0.3 6602 27432
0.4 8364 32352
0.5 10728 16280
0.6 12582 10549
0.7 14601 4446
0.8 17023 2151
0.9 18402 1514
1.0 20907 1272
Graf závislosti počtu navštívených stavů na poměru kapacity batohu k sumární váze

Z grafu je jasně patrné, že u dynamického programování je křivka rovnoměrně rostoucí. Zajímavější je však metoda větví a hranic, přibližně do hodnoty poměru 0.4 je křivka rostoucí a poté postupně klesá.

Pokud je sumární váha věcí výrazně vyšší, než je kapacita batohu (hodnotou poměru je nízké číslo), zafunguje ořezávání shora, protože se již velice brzy detekuje překročení kapacity batohu. V opačném případě dochází zase spíše k ořezávání zdola - některé z již nalezených řešení je lepší než aktuálně prověřované. Při poměru jedna a vyšší se do batohu vejdou úplně všechny věci. Zdá se, že nejhorší možný poměr je okolo hodnoty 0.4, kdy pořádně nepracuje ani jedno z prořezávání, a kvůli tomu se prověřuje mnohem více stavů, než v ostatních případech.

Například v ukázce konfigurace níže jsou hodnoty hmotností takové, že se batoh hned ze začátku nepřetíží a cena poslední věci způsobí, že prořezávání nezafunguje ani podle ceny. Z tohoto příkladu je vidět, že metoda B&B může být výrazně závislá na složení vstupních dat problému a v nejhorším případě může dosahovat původní exponenciální složitosti metody hrubé síly. V dalším textu bude pro toto používáno označení "vhodnost instance".

9405 32 450 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14
14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14
14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 450 449

Závislost počtu stavů na velikosti batohu (dynamické programování)

Program s dynamickým programováním byl napsán nerekurzivně, tj. počítá se celá tabulka se všemi stavy a poté se vybírá hodnota v pravém horním rohu, a proto by měl být průběh v minulé kapitole (Závislost počtu stavů na poměru kapacity batohu k sumární váze) přímkou rovnoběžnou s osou x. Nicméně při inspekci jednotlivých instancí problému, začínají kapacity cca. u hodnoty 100 (~0.1) a poté postupně rostou až do 1000 (~1.0). Tímto způsobem tedy generátor nastavoval požadovaný poměr.

Kdyby byl program napsán rekurzivně, nepočítaly by se vždy všechny stavy a nejednalo by se o přímku - křivka by se s většími kapacitami batohu postupně zakřivovala do vodorovnějšího stavu.

Graf závislosti počtu navštívených stavů na kapacitě batohu (dynamické programování)

Závislost počtu stavů na charakteru granularity

Podle vyneseného grafu se zdá, že granularita (převaha malých či velkých věcí) na počet kroků k řešení má v případě dynamického programování vliv. Je to zejména patrné u vyššího počtu věcí, trojce křivek se zřetelně rozbíhá.

Počet stavů
Dynamické programování B&B
n malé nerozl. velké malé nerozl. velké
05 393 924 1501 23 24 24
10 1251 3324 5388 224 253 286
15 2652 7161 11783 1496 1429 17561
20 4968 12392 20576 4760 9890 17561
25 7719 19853 31561 21305 69985 137054
30 10866 28052 45479 122636 638518 982906
35 15370 37512 61134 396766 5009287 6875663
40 19546 48343 79869 2271841 26312804 23822808
Graf závislosti počtu navštívených stavů na charakteru granularity (dynamické programování)

U metody větví a hranic tak jasný vliv granularity vidět není. Do počtu věcí 35 je situace podobná, jako u dynamického programování, ale celou situaci nabourává hodnota 40. Toto chování si vysvětluji nevhodným složením jednotlivých věcí v batohu, pravděpodobně byly vygenerovány instance, pro které není tato metoda až tak vhodná. Odhadoval bych, že výkonnost algoritmu bude spíše záviset na "vhodnosti instance" pro tuto metodu, než na granularitě.

Graf závislosti počtu navštívených stavů na charakteru granularity (B&B)

Závislost počtu stavů na maximální ceně věci

Zdá se, že ani jedna z metod není závislá na maximální ceně věcí, měření bylo pro obě metody provedeno dvakrát s různými instancemi. U dynamického programování je kolísání pravděpodobně způsobeno ne vždy stejnými kapacitami batohu. Metodu větví a hranic spíše ovlivňuje "vhodnost instance" než maximální cena věci. Pokud by mezi těmito parametry i byly nějaké závislosti, nemáme moc velkou šanci je z testovacích dat zjistit.

Počet stavů
Dynamické programování B&B
max. cena #1 #2 #1 #2
250 12481 12647 8279 11777
500 12816 12561 11479 12281
750 12874 13064 10329 15424
1000 13001 12540 10464 8343
1250 13058 12973 13633 9234
1500 12690 12301 12232 11484
1750 12398 12780 9837 9693
2000 12778 12341 10629 10250
2250 12742 12906 10491 11619
2500 12914 12453 9428 12088
2750 12698 12875 10853 11449
3000 12874 12747 11509 12085
Graf závislosti počtu navštívených stavů na maximální ceně

Závěr

V této úloze bylo prakticky ověřeno chování jednotlivých algoritmů pro řešení problému batohu. Výsledky - ve formě tabulek, grafů a komentářů - lze najít přímo u textů zabývajících se daným parametrem.