90 likes | 201 Views
Semestrálny projekt. Problém batohu (Knapsack problem) Monika Krausová. Obsah. Formulácia problému Návrh riešenia problému Iné prístupy k riešeniu (Greedy, Brute force). Formulácia problému.
E N D
Semestrálny projekt Problém batohu (Knapsack problem) Monika Krausová
Obsah • Formulácia problému • Návrh riešenia problému • Iné prístupy k riešeniu (Greedy, Brute force)
Formulácia problému • Zlodej, ktorý vylomil zámok na trezore, zistil, že je naplnený n vecami rôznych veľkostí a rôznej ceny. Na lup má ale len batoh kapacity k, problém batohu je práve nájsť takú kombináciu vecí z trezoru, aby sa mu zmestila do batoha a bola čo možno najcennejšia.
Riešenie problému • Kľúčové pozorovanie, ktoré vedie k peknému riešeniu: Ak máme maximálne dosiahnuteľné ceny lupu pre všetky celočíselné kapacity batohu pomocou prvých k predmetov, ľahko spočítame maximálne ceny pre prvých k+1 predmetov. A to tak, že skúsime pridať k + 1 - vý predmet do batohu s k predmetmi a kapacitou nižšou o hmotnosť tohto predmetu. Predmet nepridáme, pokiaľ cena takého lupu nie je vyššia od ceny lupu z prvých k predmetov v batohu s rovnakou kapacitou. Prvý predmet je možné vložiť do batohu s kapacitou rovnou aspoň hmotnosti predmetu a cena lupu je maximálna možná. Pre ďalšie predmety to plynie z indukcie.
Riešenie problému • Vytvoríme tabuľku, kde stĺpce budú popisovať cieľovú nosnosť (kapacitu) batohu, posledný stĺpec bude maximálna nosnosť. • Riadky budú označovať jednotlivé veci, ktoré môžeme do batohu vložiť. • Budeme potrebovať n + 1 riadkov, kde n je počet predmetov. Riadok navyše máme pre žiadny vložený predmet. Ďalej budeme potrebovať k + 1 stĺpcov, jeden stĺpec navyše je pre kapacitu batoha o veľkosti 0.
Riešenie problému • Prvý stĺpec naplníme samými nulami, pretože to zodpovedá batohu s nulovou kapacitou. • Prvý riadok je taktiež naplnený nulami, zodpovedá to totiž batohu so žiadnym vloženým predmetom. • Tabuľku vypĺňame zľava doprava a zhora nadol. Do jednotlivých buniek vpisujeme hodnotu tak, že sa pozrieme na aktuálnu nosnosť batohu, potom na hmotnosť predmetu a jeho cenu a tiež sa musíme pozrieť na aktuálnu hodnotu vecí v batohu.
Riešenie problému • Označme T[i][j] maximálnu cenu batohu s i predmetmi a nosnosťou o veľkosti j. Pri dynamickom programovaní teda využijeme tento vzorec: ak j – váhy[i-1] < 0, potom T[i][j] = T [i - 1][j], inak T[i][j] = max (T[i-1,j], hodnoty[i-1] + T[i-1, j - váhy[i-1] ), pričom hodnoty je pole hodnôt jednotlivých predmetov a váhy je pole váh jednotlivých predmetov.
Iné prístupy k riešeniu • Greedy algoritmus: tento prístup spočíva v tom, že keďže zlodej je veľmi chamtivý (greedy), tak berie predmety v klesajúcom poradí podľa ich ceny. Skončí s batohom, ktorý nie je úplne zaplnený. To, že batoh nie je úplne zaplnený ešte neznamená, že riešenie nie je správne, ale v mnohých prípadoch je to hlavnou príčinou. • Brute force: iný zlodej skúsil vypočítať všetky možnosti výberu vecí. Všetkých možností je ale 2n, takže zložitosť tohto algoritmu by bola exponenciálna.