From: Martin Mares Date: Sun, 15 Jan 2012 13:22:04 +0000 (+0100) Subject: APX: Batoh X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=ef8da2b26dc4d764d69868d54647d0cf60cebcba;p=ads2.git APX: Batoh --- diff --git a/9-apx/9-apx.tex b/9-apx/9-apx.tex index d8f3f49..c23cb22 100644 --- a/9-apx/9-apx.tex +++ b/9-apx/9-apx.tex @@ -126,60 +126,62 @@ pot \h{Problém batohu s~malými èísly} -Je daná mno¾ina $n$~pøedmìtù s~hmotnostmi $h_1,\ldots,h_n$ -a cenami $c_1,\ldots,c_n$ a~batoh, který unese hmostnost~$H$. Najdìte takovou -podmno¾inu pøedmìtù, jejich¾ celková hmotnost je maximálnì $H$ a celková cena -je maximální mo¾ná. - -Tento problém je zobecnìním problému batohu z~minulé pøedná¹ky dvìma smìry: -Jednak místo rozhodovacího problému øe¹íme optimalizaèní, jednak pøedmìty -mají ceny (pøedchozí verze odpovídala tomu, ¾e ceny jsou rovny hmotnostem). -Uká¾eme si algoritmus pro øe¹ení tohoto obecného problému, jeho¾ èasová -slo¾itost bude polynomiální v~poètu pøedmìtù~$n$ a souètu v¹ech cen~$C=\sum_i -c_i$. +Pøipomeòme si problém batohu. Jeho optimalizaèní verze vypadá takto: +Je daná mno¾ina $n$~pøedmìtù s~hmotnostmi $h_1,\ldots,h_n$ a cenami $c_1,\ldots,c_n$ +a nosnost batohu~$H$. Hledáme podmno¾inu pøedmìtù~$P \subseteq \{1,\ldots,n\}$, +která se vejde do batohu (tedy $h(P)=\sum_{i\in P} h_i \le H$) a její cena +$c(P) = \sum_{i\in P} c_i$ je nejvìt¹í mo¾ná. + +Uká¾eme algoritmus, jeho¾ èasová slo¾itost bude polynomiální v~poètu +pøedmìtù~$n$ a souètu v¹ech cen $C=\sum_i c_i$. Pou¾ijeme dynamické programování. Pøedstavme si problém omezený na~prvních~$k$ -pøedmìtù. Oznaème si $A_k(c)$ (kde $0\le c\le C$) minimální hmotnost -podmno¾iny, její¾ cena je právì~$c$. Tato $A_k$ spoèteme indukcí podle~$k$: -Pro $k=0$ je urèitì $A_0(0)=0$, $A_0(c)=infty$ pro $c>0$. Pokud ji¾ známe +pøedmìtù. Oznaème $A_k(c)$ (kde $0\le c\le C$) minimum z~hmotností tìch podmno¾in +jejich¾ cena je právì~$c$; pokud ¾ádná taková podmno¾ina neexistuje, polo¾íme $A_k(c)=\infty$. + +Tato $A_k$ spoèteme indukcí podle~$k$: Pro $k=0$ je +urèitì $A_0(0)=0$ a $A_0(c)=\infty$ pro $c>0$. Pokud ji¾ známe $A_{k-1}$, spoèítáme $A_k$ následovnì: $A_k(c)$ odpovídá nìjaké podmno¾inì pøedmìtù z~$1,\ldots,k$. V~této podmno¾inì jsme buïto $k$-tý pøedmìt nepou¾ili (a pak je $A_k(c)=A_{k-1}(c)$), nebo pou¾ili a tehdy bude $A_k(c) = A_{k-1}(c-c_k) + h_k$ (to samozøejmì jen pokud $c\ge c_k$). Z~tìchto dvou -mo¾ností si vybereme tu, která dává mno¾inu s~men¹í hmotností. Tedy: +mo¾ností si vybereme tu, která dává mno¾inu s~men¹í hmotností: $$ A_k(c) = \min (A_{k-1}(c), A_{k-1}(c-c_k) + h_k). $$ -Tímto zpùsobem v~èase $\O(C)$ spoèteme $A_k(c)$ pro fixní $k$ a v¹echna $c$, -v~èase $\O(nC)$ pak v¹echny $A_k(c)$. +Pøechod od $A_{k-1}$ k~$A_k$ tedy trvá $\O(C)$, pro v¹echna~$k$ pak $\O(Cn)$. -Podle $A_n$ snadno nalezneme maximální cenu mno¾iny, která se vejde do~batohu. -To bude nejvìt¹í~$c^*$, pro nì¾ je $A_n(c^*) \le H$. Jeho nalezení nás stojí -èas $\O(C)$. +Jakmile spoèteme~$A_n$, známe pro ka¾dou cenu nejlehèí podmno¾inu s~touto cenou. +Maximální cena mno¾iny, která se vejde do batohu, je tedy nejvìt¹í~$c^*$, pro nì¾ +je $A_n(c^*) \le H$. Jeho nalezení nás stojí èas $\O(C)$. -A~jak zjistit, které pøedmìty do~nalezené mno¾iny patøí? Upravíme algoritmus, +Zbývá zjistit, které pøedmìty do~nalezené mno¾iny patøí. Upravíme algoritmus, aby si pro ka¾dé $A_k(c)$ pamatoval $B_k(c)$, co¾ bude index posledního pøedmìtu, který jsme do~pøíslu¹né mno¾iny pøidali. Pro nalezené $c^*$ tedy bude $i=B_n(c^*)$ poslední pøedmìt v~nalezené mno¾inì, $i'=B_{i-1}(c^*-c_i)$ ten pøedposlední a tak dále. Takto v~èase $\O(n)$ rekonstruujeme celou mno¾inu od~posledního prvku k~prvnímu. -Ukázali jsme tedy algoritmus s~èasovou slo¾itostí $\O(nC)$, který vyøe¹í -problém batohu. Jeho slo¾itost není polynomem ve~velikosti vstupu ($C$~mù¾e -být a¾ exponenciálnì velké vzhledem k~velikosti vstupu), ale pouze ve~velikosti -èísel na~vstupu. Takovým algoritmùm se øíká {\I pseudopolynomiální.} Ani takové -algoritmy ale nejsou k dispozici pro v¹echny problémy (napø. u problému obchodního -cestujícího nám vùbec nepomù¾e, ¾e váhy hran budou malá èísla). - -\s{Verze bez cen:} Na verzi s~cenami rovnými hmotnostem se dá pou¾ít -i jiný algoritmus zalo¾ený na~dynamickém programování: poèítáme mno¾iny -$Z_k$ obsahující v¹echny hmotnosti men¹í ne¾~$H$, kterých nabývá -nìjaká podmno¾ina prvních~$k$ prvkù. Pøitom $Z_0=\{0\}$, $Z_k$ -spoèteme ze~$Z_{k-1}$ --- udr¾ujme si $Z_{k-1}$ jako setøídìný spojový seznam, -výpoèet dal¹ího seznamu udìláme slitím dvou seznamù $Z_{k-1}$ a $Z_{k-1}$ se -v¹emi prvky zvý¹enými o hmotnost $k$ zahazujíce duplicitní a pøíli¹ velké hodnoty --- -a ze~$Z_n$ vyèteme výsledek. V¹echny tyto mno¾iny -mají nejvý¹e $H$ prvkù, tak¾e celková èasová slo¾itost algoritmu je~$\O(nH)$. +Máme tedy algoritmus, který vyøe¹í problém batohu v~èase $\O(nC)$. Tato funkce +ov¹em není polynomem ve~velikosti vstupu, jeliko¾ reprezentujeme-li vstup binárnì, +$C$~mù¾e být a¾ exponenciálnì velké vzhledem k~velikosti jeho zápisu. To je pìkný +pøíklad tzv. {\I pseudopolynomiálního} algoritmu, tedy algoritmu, jeho¾ slo¾itost +je polynomem v~poètu èísel na vstupu a jejich velikosti. Pro nìkteré \NP-úplné +problémy takové algoritmy existují, pro jiné (napø. pro nezávislou mno¾inu) nikoliv. + +\s{Verze bez cen:} Jednodu¹¹í verzi problému batohu, která nerozli¹uje mezi +hmotnostmi a cenami, zvládneme i jiným algoritmem, opìt zalo¾eným na dynamickém +programování. + +Indukcí podle~$k$ vytváøíme mno¾iny~$Z_k$ obsahující v¹echny hmotnosti +men¹í ne¾~$H$, kterých nabývá nìjaká podmno¾ina prvních~$k$ prvkù. Jistì je $Z_0=\{0\}$. +Podobnou úvahou jako v~pøedchozím algoritmu dostaneme, ¾e ka¾dou dal¹í~$Z_k$ mù¾eme +zapsat jako sjednocení $Z_{k-1}$ s~kopií $Z_{k-1}$ posunutou o~$h_k$, pøièem¾ hodnoty +vìt¹í ne¾~$H$ zahodíme. Nakonec ze~$Z_n$ vyèteme výsledek. + +V¹echny mno¾iny pøitom mají nejvý¹e~$H+1$ prvkù, tak¾e pokud si je budeme udr¾ovat +jako setøídìné seznamy, spoèítáme sjednocení sléváním v~èase $\O(H)$ a celý algoritmus +dobìhne v~èase $\O(Hn)$. \h{Aproximace problému obchodního cestujícího}