]> mj.ucw.cz Git - ads2.git/commitdiff
Aproximace problemu batohu uvedena na pravou miru.
authorMartin Mares <mj@ucw.cz>
Tue, 18 Dec 2007 20:44:10 +0000 (21:44 +0100)
committerMartin Mares <mj@ucw.cz>
Tue, 18 Dec 2007 20:44:10 +0000 (21:44 +0100)
12-apx/12-apx.tex [new file with mode: 0644]
12-apx/Makefile [new file with mode: 0644]
all/Makefile

diff --git a/12-apx/12-apx.tex b/12-apx/12-apx.tex
new file mode 100644 (file)
index 0000000..3625a40
--- /dev/null
@@ -0,0 +1,140 @@
+\input lecnotes.tex
+\prednaska{12}{Aproximaèní algoritmy}{(???)}
+
+\h{Pseudopolynomiální algoritmus pro problém batohu}
+
+\s{POZOR:} Na~pøedná¹ce byla jen verze bez cen, nauète se, prosím, obì. --M.M.
+
+\s{Problém batohu:} Je dána mno¾ina $n$~pøedmìtù s~hmotnostmi $h_1,\ldots,h_n$
+a cenami $c_1,\ldots,c_n$ a batoh, který unese hmotnost~$H$. Naleznìte takovou
+podmno¾inu pøedmìtù, jejich¾ celková hmotnost je nejvý¹e~$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$.
+
+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, jeji¾ 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
+$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 pøedmìt $k$ 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:
+$$
+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 jednu mno¾ínu, v~èase $\O(nC)$ pak v¹echny.
+
+Podle $A_n$ snadno nalezneme maximální cenu mno¾iny, která se vejde do batohu. To bude
+nejvìt¹í~$c^*$, pro které je $A_n(c^*) < \infty$. To nás stojí èas $\O(C)$.
+
+A~jak 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¾ je index posledního pøedmìtu,
+který do~pøíslu¹né mno¾iny pøidal. 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. To není polynom ve~velikosti vstupu ($C$~mu¾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í.}
+
+\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$, které obsahují v¹echny hmotnosti men¹í ne¾~$H$, kterých nabývá
+nìjaká podmno¾ina prvních~$k$ prvkù batohu. Pøitom $Z_0=\{0\}$, $Z_k$
+spoèteme z~$Z_{k-1}$ 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)$.
+
+\h{Aproximaèní schéma pro problém batohu}
+
+\s{POZOR:} Verze algoritmu, kterou jsem øíkal na~pøedná¹ce, obsahovala jednu
+pomìrnì zásadní chybu, které jsem si nev¹iml: Verze se zaokrouhlováním dolù
+mohla produkovat nepøípustná (pøíli¹ tì¾ká) øe¹ení, verze se zaokrouhlováním nahoru pro zmìnu
+nìkdy spoèítala øe¹ení pøíli¹ daleká od~optima. Algoritmus lze opravit (budeme-li
+zvlá¹» zpracovávat lehké a tì¾ké pøedmìty), ale radìji budeme místo hmotností
+kvantovat ceny. Tak dojdeme k~následujícímu aproximaènímu algoritmu. --M.M.
+
+Ji¾ víme, jak optimalizaèní verzi problému batohu vyøe¹it v~èase $\O(nC)$,
+pokud jsou hmotnosti i ceny na~vstupu pøirozená èísla a $C$ je souèet v¹ech cen.
+Jak si poradit, pokud je~$C$ obrovské? Kdybychom mìli ¹tìstí a v¹echny
+ceny byly dìlitelné nìjakým èíslem~$p$, mohli bychom je tímto èíslem
+vydìlit. Tím bychom dostali zadání s~men¹ími èísly, jeho¾ øe¹ením by byla
+stejná mno¾ina pøedmìtù jako u~zadání pùvodního.
+
+Kdy¾ nám ¹tìstí pøát nebude, mù¾eme pøesto zkusit ceny vydìlit a výsledky
+nìjak zaokrouhlit. Øe¹ení nové úlohy pak sice nebude pøesnì odpovídat optimálnímu
+øe¹ení té pùvodní, ale kdy¾ nastavíme parametry správnì, bude alespoò dobrou aproximací
+optima.
+
+\s{Základní my¹lenka:}
+
+Oznaèíme si $c_{max}$ maximum z~cen~$c_i$. Zvolíme si nìjaké pøirozené èíslo~$M$
+a zobrazme interval cen $[0, c_{max}]$ na $[0,M]$.
+Jak jsme tím zkreslili výsledek? V¹imnìme si, ¾e efekt je stejný, jako kdybychom jednotlivé
+ceny zaokrouhlili na~násobky èísla $c_{max}/M$. Ka¾dé $c_i$ jsme tím
+zmìnili o~nejvý¹e $c_{max}/M$, celkovou cenu libovolné podmno¾iny pøedmìtù tedy
+nejvý¹e o~$n\cdot c_{max}/M$. Teï si je¹tì v¹imneme, ¾e pokud ze~zadání odstraníme
+pøedmìty, které se samy nevejdou do~batohu, má optimální øe¹ení pùvodní úlohy ceny $OPT\ge c_{max}$,
+tak¾e chyba v~souètu je nejvý¹e $n\cdot OPT/M$. Má-li tato chyba být shora omezena
+$\varepsilon\cdot OPT$, musíme zvolit $M\approx n/\varepsilon$.
+
+\s{Algoritmus:}
+\algo
+\:Odstraníme ze~vstupu v¹echny pøedmìty tì¾¹í ne¾~$H$.
+\:Spoèítáme $c_{max}=\max_i c_i$ a zvolíme $M=\lfloor n/\varepsilon\rfloor$.
+\:Kvantujeme ceny: $\hat{c}_i = \lfloor c_i \cdot M/c_{max} \rfloor$.
+\:Vyøe¹íme dynamickým programováním problém batohu pro upravené ceny $\hat{c}_1, \ldots, \hat{c}_n$
+a pùvodní hmotnosti i kapacitu batohu.
+\:Vybereme stejné pøedmìty, jaké pou¾ilo optimální øe¹ení kvantovaného zadání.
+\endalgo
+
+\>Kroky 1--3 a 5 jistì zvládneme v~èase $\O(n)$. Krok~4 øe¹í problém batohu
+se souètem cen $\hat{C}\le nM \le n^2/\varepsilon$, co¾ stihne v~èase $\O(n\hat{C})=\O(n^3/\varepsilon)$.
+Zbývá dokázat, ¾e výsledek na¹eho algoritmu má opravdu relativní chybu nejvý¹e~$\varepsilon$.
+
+Nejprve si rozmyslíme, jak dopadne optimální øe¹ení $OPT$ pùvodního zadání,
+kdy¾ ceny v~nìm pou¾itých pøedmìtù nakvantujeme (mno¾inu indexù tìchto pøedmìtù si oznaèíme~$Y$):
+$$
+\eqalign{
+\widehat{OPT} &= \sum_{i\in Y} \hat{c}_i =
+\sum_i \left\lfloor c_i\cdot {M\over c_{max}} \right\rfloor \ge
+\sum_i \left( c_i\cdot {M\over c_{max}} - 1 \right) \ge \cr
+&\ge
+\biggl(\sum_i c_i \cdot {M\over c_{max}}\biggr) - n =
+OPT \cdot {M\over c_{max}} - n.
+}
+$$
+Nyní naopak spoèítejme, jak dopadne øe¹ení~$Q$ nakvantovaného problému pøi pøepoètu
+na~pùvodní ceny (to je výsledek na¹eho algoritmu):
+$$
+\eqalign{
+ALG &= \sum_{i\in Q} c_i \ge
+\sum_i \hat{c}_i \cdot {c_{max}\over M} =
+\biggl(\sum_i \hat{c}_i\biggr) \cdot {c_{max}\over M} \ge^*
+\widehat{OPT} \cdot {c_{max}\over M}.
+}
+$$
+Nerovnost $\ge^*$ platí proto, ¾e $\sum_{i\in Q} \hat{c}_i$ je optimální øe¹ení
+kvantované úlohy, zatímco $\sum_{i\in Y} \hat{c}_i$ je nìjaké dal¹í øe¹ení té¾e úlohy,
+které nemù¾e být lep¹í. Teï u¾ staèí slo¾it obì nerovnosti a dosadit za~$M$:
+$$
+\eqalign{
+ALG &\ge \biggl( { OPT \cdot M\over c_{max}} - n\biggr) \cdot {c_{max}\over M} =
+OPT - {n\cdot c_{max}\over n / \varepsilon} \ge OPT - \varepsilon c_{max} \ge \cr
+&\ge OPT - \varepsilon OPT = (1-\varepsilon)\cdot OPT.
+}
+$$
+Algoritmus tedy v¾dy vydá øe¹ení, které je nejvý¹e $(1-\varepsilon)$-krát hor¹í ne¾ optimum,
+a~doká¾e to pro libovolné~$\varepsilon$ v~èase polynomiálním v~$n$. Takovému algoritmu øíkáme
+{\I polynomiální aproximaèní schéma} (jinak té¾ PTAS\foot{Polynomial-Time Approximation Scheme}).
+V~na¹em pøípadì je dokonce slo¾itost polynomiální i v~zavislosti na~$1/\varepsilon$, tak¾e
+schéma je {\I plnì polynomiální} (øeèené té¾ FPTAS\foot{Fully Polynomial-Time Approximation Scheme}).
+
+\bye
diff --git a/12-apx/Makefile b/12-apx/Makefile
new file mode 100644 (file)
index 0000000..11f9d14
--- /dev/null
@@ -0,0 +1,3 @@
+P=12-apx
+
+include ../Makerules
index 90bc7ce85132ec4dc3e4944b19b0fb08ece67a33..e9643156c8ef8a6565866db172e498b5767aa8ab 100644 (file)
@@ -1,5 +1,5 @@
 P=ads2
-X:=$(shell for a in 1 2 3 4 5 6 7 ; do echo ../$$a-*/$$a-*.tex ; done)
+X:=$(shell for a in 1 2 3 4 5 6 7 8 10 12 ; do echo ../$$a-*/$$a-*.tex ; done)
 
 %universe: all ChangeLog