Vypracoval Michal Turek, cvičení Po 12:45-14:15 (Petr Fišer)
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ší.
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 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.
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.
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)
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 |
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 |
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
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.
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 |
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ě.
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 |
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.