Úloha 3

Autor: Petr Chytil


Zadání

Zpráva by měla obsahovat:

Popis řešení

Řešení metodou větví a hranic

Tato metoda používá brute force algoritmus, ale snaží se jej omezovat, abychom dosahovali lepších výsledků (bohužel při stejné asymptotické složitosti). První omezení jsem již v brute force algoritmu z úlohy 1 měl zakomponováno. Bylo jím omezení dané maximální vahou věcí v batohu. Stavy, jejichž konfigurace předmětů přesahovala kapacitu batohu jsme vůbec neřešili. V této metodě přidáváme omezení cenou. Původní rekurzivní funkci jsem přidal parametr, který určuje součet cen všech předmětů, které ještě v této větvi stavového prostoru můžeme přidat. Před přidáním dalšího předmětu zjišťuji, zda-li součet cen předmětů aktuálně obsažených v batohu se sumou cen všech nevložených předmětů přesahuje doposud nejlepší dosaženou celkovou cenu věcí v batohu. Pokud ano, tak jedeme dál a pokud ne, tak řežeme větev a dál v ní nepokračujeme, protože nám neumožní dosáhnout lepšího řešení než jsme už doteď našli.

Řešení pomocí dynamického programování

Aplikuji jednoprůchodovou verzi dynamického programování s dekompozicí dle ceny batohu. Pracuji s tabulkou, ve které řádky specifikují podúlohy, které mají nastavenu nosnost batohu od max do 0, kde max je nosnost batohu aktuálně řešeně instance. Sloupce zase určují předměty (0 až n). Jednotlivé buňky tabulky pak obsahují dvojici cena, váha. Začínám prvním sloupcem pro první předmět a řeším triviální podúlohu – pokud se tento předmět vejde do batohu (max. váha je specifikována řádkem), tak jej vložím, v opačném případě nevkládám nic. Pro další sloupce pokračuji jinak. Porovnávám vždy cenu buňky v předchozím sloupci na stejném řádku (stejná kapacita batohu) se součtem ceny aktuálního předmětu a ceny buňky v předchozím sloupci a řádku sníženém o váhu aktuálního předmětu. Z těchto dvou cen vybírám tu lepší. Po vyplnění celé tabulky nastupuje rekonstrukce konfigurace nejlepšího řešení. Začínám posledním předmětem v řádku pro max váhu. Porovnávám jej se sloupcem vlevo. Pokud jsou shodné, tak aktuální předmět v řešení není a pokračuji dalším předmětem na stejném řádku. V opačném případě předmět v řešení je a pokračuji na řádku, který dostanu odečtením hmotnosti předmětu předchozího od hmotnosti předchozí buňky. Takto dojdu až k prvnímu předmětu, u kterého pouze kontroluji, zda se vejde do batohu o kapacitě specifikované řádkem, na kterém se zrovna nacházíme.

Řešení heuristikou podle poměru cena/hmotnost s testem nejcennější věci

U tohoto řešení jsem použil hotovou jednoduchou heuristiku z první úlohy. Po jejím proběhnutí pouze zjistím, který předmět je nejcennější ze všech. Cenu tohoto předmětu porovnám s celkovou cenou všech věcí v batohu, na kterou prišla heuristika. Z těchto dvou cen vybírám tu vyšší a prohlašuji jí za na naše konečné řešení.

Zdrojový kód všech tří řešení



Změřená závislost výpočetního času na n




Měření byla provedena pomocí knihovní funkce System.nanoTime(), kterou jazyk Java poskytuje.
A to na stroji s procesorem Core Duo 1.66GHz a operačním systémem Windows XP 32bit.
Nebylo započítáváno načítaní dat ze souboru ani jejich zapisování na výstup.
U heuristiky byl započítán i čas potřebný k seřazení pole prvků dle zvoleného poměru cena/váha.

Změřené časy v nanosekundách jsou k nahlednutí v adresáři data.

Zhoršení

Průměrné zhoršení pro daný počet věcí v batohu jsem vypočítal jako aritmetický průměr relativnich chyb všech instancí.
Hodnota relatviní chyby v mém pojetí vyjadřuje o kolik procent je řešení metodou brute force lepši než řešení heuristikou.

n

10

15

20

22

25

27

30

32

prům. rel. ch. herustika [%]

3,173311

1,244791

1,657391

1,41706

1,322055

1,504715

0,847584

1,083805

prům. rel. ch.

heuristika max [%]

2,991493

1,073937

1,488716

1,272482

1,248476

1,504715

0,737309

1,01699



Graf




Zhodnocení a závěr

Metoda B&B vylepšuje brute force algoritmus tak, že dává o poznání lepší výsledky, ale bohužel stejně rychle roste. Tím je pro velké instance stejně nepoužitelná. Pro menší instance nám však pomůže, protože dokáže být rychlejší než brute force i dynamické programování.

Přidáním testu na nejtěžší předmět do heuristiky jí sice nepatrně zpomalíme, ale dostaneme díky tomu nižší průměrnou relativní chybu.

Dynamické programování je pro nízký počet předmětu nejpomalejší kvůli velkému množství pomocných výpočtů, které pro jeho běh potřebujeme. Tato režie není závislá na velikosti instance. Jedná se tedy o pseudopolynomiální algoritmus. Nedosahuje sice rychlosti heuristiky, ale najde vždy optimální řešení. Je to zatím nejlepší algoritmus pro řešení problému batohu, který jsem implementoval – pokud však potřebujeme optimální řešení a velké instance (kolem 20ti a více předmětů).