Domovská stránka Jiřího Kalvody

Bakalářka: Binární paint shop problém

Also available as: PDF Markdown Pictures (ZIP)

\def\progline#1#2#3{\hbox{#1}\hskip 1cm\relax #2 \hskip 1cm\relax #3} \protected\def\P{{\rm P}} \protected\def\NP{{\rm NP}} \protected\def\APX{{\rm APX}} \protected\def\opt{{\rm opt}} \protected\def\algo#1{{\bf #1}} \protected\def\alg{\algo{alg}}

Obsah

Úvod

V této práci představíme binární paint shop problem. Jedná se o úlohu, kterou neumíme efektivně řešit (protože je NP\NP úplná) a ani aproximovat (za předpokladu Unique games conjecture je konstantní aproximace také NP\NP těžká), takže mimo jiné probíhá aktivní výzkum snažící se najít algoritmus, který je dobrý v průměrném případě (pro náhodný vstup).

Zadání

Zadání binárního paint shop problému (dále těž BPS) je následující:

Úloha (Binární paint shop): V řadě je 2n2n​ aut nn různých typů – od každého typu dvě. Chtěli bychom od každého typu nabarvit jedno auto červeně a druhé modře. Auta však na barvicí linku vjíždí v pořadí, v jakém jsou v řadě. Barvicí linka je optimalizovaná na barvení velkého počtu aut jednou barvou. Tedy měnit barvu, kterou se barví, je složitá a drahá záležitost. Chceme tedy najít obarvení aut tak, aby od každého typu bylo jedno červené a jedno modré, přitom počet změn barev v řadě byl co nejmenší.

Počet změn barev řešení považujeme za skóre algoritmu. Relativní skóre pak je poměr skóre a počtu typů aut.

Problém můžeme chápat buď jako optimalizační problém, kde účelová funkce je počet změn v řešení a snažíme se ji minimalizovat, nebo jako rozhodovací problém, kde se ptáme, jestli existuje řešení s nejvýše nějakým zadaným počtem změn.

Cíle práce

Naším cílem bude najít co nejlepší algoritmus řešící BPS a odhadnout u něj střední hodnotu skóre pro náhodný vstup. Dále se pokusíme porovnat již známé algoritmy.

Struktura práce

Nejprve zavedeme notaci potřebnou pro pohodlnou práci s BPS a definujeme aproximační algoritmy. Kapitola 2 obsahuje shrnutí doposud známých algoritmů a jiných výsledků ohledně BPS. V kapitole 3 je představen princip semidefinitního programování, které má uplatnění v algoritmu představeném o kapitole 4. Kapitola 5 se věnuje praktické implementacím algoritmů a naměřeným datům o nich.

Notace

Auta budeme indexovat od 00 do 2n12n-1 a typy od 00 do n1n-1.

Pomocí ai,0a_{i,0} budeme značit pozici prvního auta typu ii a pomocí ai,1a_{i,1} pozici druhého.

Opačně tit_i bude značit typ auta na pozici ii a pip_i bude značit, jestli se jedná o první nebo druhé auto daného typu (tedy bude nabývat hodnoty 00 nebo 11).

Protože někdy bude výhodnější zacházet se znaménky, zavedeme Pi=1+2piP_i = -1+2 p_i, které bude nabývat hodnot 1-1 a 11. Také rozšíříme notaci o ai,1=ai,0a_{i, -1} = a_{i,0}.

Nakonec ještě zavedeme zkratku indexu druhého auta stejného typu jako je auto na pozici ii: oi=ati,Pio_i = a_{t_i,-P_i}.

Barvy pro nás budou 00 a 11. Pokud budeme uvažovat nějaké konkrétní obarvení cc, tak c(i)c(i) bude značit barvu auta na pozici ii.

Pro algoritmus alg\alg označíme skóre na vstupu α\alpha pomocí γalg(α)\gamma_{\alg}(\alpha). Dále označme všechny vstupy délky nn jako WnW_n. Průměrné skóre algoritmu na všech vstupech délky nn tedy bude γalg(n)=αWnγalg(α)Wn.\gamma_{\alg}(n) = {\sum_{\alpha \in W_n} \gamma_{\alg} (\alpha) \over |W_n|}. Tuto hodnotu mimo jiné můžeme chápat jako střední hodnotu skóre pro uniformně náhodný vstup délky nn. K tomu ještě zavedeme notaci pro relativní skóre δalg(α)=γalg(α)/nα\delta_{\alg}(\alpha) = \gamma_{\alg}(\alpha)/n_{\alpha} a analogicky průměrné relativní skóre δalg(n)=γalg(n)/n\delta_{\alg}(n) = \gamma_{\alg}(n)/n. Nakonec označme δalg=limnδalg(n)=limnγalg(n)/n\delta_{\alg} = \lim_{n\to\infty} \delta_{\alg}(n) = \lim_{n\to\infty} \gamma_{\alg}(n)/n. Protože limita nemusí vždy existovat, zavedeme ještě limes superior a limes inferior: δalg+=lim supnδalg(n)\delta^+_{\alg} = \limsup_{n\to\infty} \delta_{\alg}(n) a δalg=lim infnδalg(n)\delta^-_{\alg} = \liminf_{n\to\infty} \delta_{\alg}(n). Význam těchto definic bude vysvětlen v následující kapitole.

Dále označme γ(α)\gamma(\alpha) optimální skóre na vstupu α\alpha. A následně analogicky definujeme γ(n),δ(α),δ(n)\gamma(n), \delta(\alpha), \delta(n), δ\delta, δ+\delta^+ a δ\delta^- stejně jako u variant s algoritmem, jen skóre daného algoritmu nahradíme za optimální skóre.

Definice aproximačních algoritmů

Protože ne pro všechny problémy známe polynomiální algoritmus, který je schopný je vyřešit, zajímavý výsledek může být, i když se k řešení zvládneme jen v nějakém smyslu alespoň přiblížit. Na to nejprve musíme říct, co pro nás znamená, že nějaké řešení je několikrát horší než jiné. To nám poskytne obecná definice optimalizačního problému.

Definice (Optimalizační problém): Problém je optimalizační, pokud pro každý vstup II, existuje množina přípustných řešení F(I)F(I). Dále existuje účelová funkce ff, která pro každý vstup a jeho přípustné řešení určuje reálné nezáporné číslo – jeho hodnotu.

Pokud se jedná o minimalizační problém, tak pod pojmem optimum daného vstupu (značíme opt(I)\opt(I)) myslíme infimum hodnot účelové funkce přes všechna přípustná řešení, tedy inff[F(i)]\inf f[F(i)]. Pro maximalizační problém analogicky použijeme supremum.

A nyní již přejdeme k samotným definicím algoritmů blížících se optimu.

Definice (Aproximační algoritmus): Algoritmus alg\alg je g(n)g(n)-aproximační na minimalizačním problému, pokud pro každý vstup II algoritmus vrátí přípustné řešení alg(I)\alg(I), pro které platí, že f(alg(I))g(I)opt(I)f(\alg(I)) \le g(|I|) \cdot \opt(I).

Předešlá definice záleží na tom, co považujeme za velikost vstupu, což se pro různé problémy a jejich interpretace liší. Naštěstí nás většinou budou zajímat cc-aproximace, tedy aproximace, kde g(n)g(n) je konstantní funkce rovna cc.

U maximalizačních problémů je drobný problém v terminologii, protože není shoda na tom, jestli má platit f(alg(I))g(I)opt(I)f(\alg(I)) \ge g(|I|) \cdot \opt(I) nebo f(alg(I))1g(I)opt(I)f(\alg(I)) \ge {1\over g(|I|)} \cdot \opt(I). Naštěstí podle kontextu jde snadno rozhodnout, která definice se používá, protože je potřeba násobit optimum číslem menším rovno jedné (jinak by pro kladné hodnoty účelové funkce nemohl existovat žádný vyhovující algoritmus).

Bohužel někdy asi ani s aproximačními algoritmy nevystačíme a proto zavedeme pravděpodobnostní relaxaci.

Definice (Pravděpodobnostní aproximační algoritmus): Náhodný algoritmus alg\alg je pravděpodobnostně g(n)g(n)-aproximační na minimalizačním problému, pokud pro každý vstup II algoritmus vždy vrátí přípustné řešení alg(I)\alg(I), pro které platí, že E[f(alg(I))]g(I)opt(I)\E[f(\alg(I))] \le g(|I|) \cdot \opt(I).

Snadným důsledkem definice (a Markovovy nerovnosti) je, že pro každé λ>1\lambda > 1 pravděpodobnostně g(n)g(n)-aproximační algoritmus vrátí s pravděpodobností zdola omezenou konstantou 11λ(0,1)1- {1\over \lambda} \in (0,1) řešení s hodnotou nejvýše λg(n)opt(I)\lambda \cdot g(n)\cdot \opt(I).

Všimněme si, že na hodnotě 11λ1-{1\over\lambda} příliš nezáleží. Opakovaným spouštěním algoritmu a pak vybráním nejlepšího z dodaných řešení zvládneme pravděpodobnost libovolně těsně přiblížit k jedné.

Pokud řešíme složitost algoritmů a úloh, většinou vyžadujeme, aby účelová funkce i rozhodování přípustnosti řešení byly vyčíslitelné v polynomiálním čase. Navíc chceme, aby všechna přípustná řešení měla délku omezenou nějakým polynomem v délce vstupu. Snadno nahlédneme, že za takovýchto podmínek je rozhodovací verze, jestli je optimum alespoň zadané číslo, v NP\NP. Pro takovou úlohu většinou hledáme polynomiální aproximační algoritmus. Binární paint shop vyhovuje všem těmto podmínkám.

Pokud existuje (1+ε)(1+\varepsilon)-aproximační algoritmus pro každé ε>0\varepsilon > 0, říkáme, že máme aproximační schéma.

Doposud známé výsledky

Bonsmaa, Epping a Hochstättler [1] dokázali, že optimalizační verze BPS je APX\APX-těžký problém, což je silnější tvrzení, než že rozhodovací verze je NP\NP-těžká. Za předpokladu PNP\P \neq \NP víme, že kromě polynomiálního algoritmu na rozhodovací verzi nemůže existovat ani polynomiální aproximační schéma na optimalizační verzi.

Snadno nahlédneme, že rozhodovací problém patří do NP\NP. Když nám někdo dá přiřazení barev autům, v lineárním čase jsme schopni ověřit, že počet změn je dostatečně malý a od každého typu a barvy auta je právě jeden výskyt. Tedy rozhodovací problém je NP\NP-úplný.

Dále pak Gupta a spol. [2] ukázali, že za předpokladu Unique games conjecture je NP-těžké i problém libovolně konstantně aproximovat. K tomu využili převod na problém minimálního ne-řezu. To je problém podobný maximálnímu řezu, který bude představen později. Ovšem místo maximalizace počtu hran v řezu minimalizujeme počet hran mimo něj (tedy v rámci partit). Tyto dva problémy mají stejné optimum, ovšem aproximovatelnost se na nich chová drasticky jinak. V momentě, kdy jsou skoro všechny hrany v řezu, tak přidání další hrany do řezu skoro nezmění počet hran v něm. Ovšem odebrání hrany z ne-řezu bude mít velký vliv (procentuálně) na počet hran v ne-řezu.

Vzhledem k předešlým výsledkům je na místě zkoumat různé heuristiky a obecně algoritmy, co jsou nás schopny k optimálnímu řešení alespoň částečně přiblížit.

Jedním z takových algoritmů je hladový algoritmus popsaný Andresem and Hoch-stättlerem [3]:

Algoritmus (Hladový algoritmus, g): Autům budeme přiřazovat barvy v pořadí, v jakém jsou na vstupu. První auto v řadě obarvíme řekněme červeně. Dále budeme vždy první auto daného typu barvit stejně jako předcházející auto a druhé auto daného typu obarvíme vždy zbývající barvou.

V daném článku autoři o tomto algoritmu dokázali, když vezmeme uniformně náhodný vstup délky nn, tak střední hodnota počtu změn ve vygenerovaném řešení je 0k<n2k214k21\sum_{0\le k < n} {2k^2-1 \over 4k^2-1}.

Hladový algoritmus budeme značit g\algo g, tedy předešlou hodnotu značíme γg(n)\gamma_{\algo g}(n). Připomeňme, že pomocí δg(n)\delta_{\algo g}(n) značíme tuto hodnotu vydělenou velikostí vstupu, tedy γg(n)/n\gamma_{\algo g}(n) / n.

Pro dostatečně velká nn se γg(n)\gamma_{\algo g}(n) pohybuje zhruba okolo (1/2)n(1 / 2) n (formálně řečeno: platí, že δg=limnγg(n)/n=1/2\delta_{\algo g} = \lim_{n\to\infty} {\gamma_{\algo g}(n) / n} = {1 / 2}) (viz obrázek ).

Graf střední hodnoty rel. skóre hladového řešení δg(n)\delta_{\algo g}(n) v závislosti na nn.

U hladového řešení je tedy střední hodnota skóre přes uniformně náhodný vstup přesně vyčíslená. Pro nás je zejména důležité, že jsme ji schopni shora odhadnout. Střední hodnotu totiž můžeme považovat za ukazatel kvality algoritmu (čím menší je, tím se jedná o lepší algoritmus) a tedy horní odhad nám dává záruku kvality algoritmu.

Zajímavé je pro nás zkoumat chování algoritmů na velkých vstupech, tedy dává smysl uvažovat limitu střední hodnoty do nekonečna. Ovšem s narůstajícím počtem aut narůstá i počet potřebných změn, takže samotná limita střední hodnoty moc nedává smysl, protože by byla nekonečná. Místo ní budeme uvažovat limnγalg(n)/n=limnδalg(n)\lim_{n\to\infty} {\gamma_{\alg}(n) / n} = \lim_{n\to\infty}\delta_{\alg}(n). O ní víme, že pro libovolný algoritmus (pokud existuje) bude v intervalu [0,2][0, 2], protože maximální počet změn musí být mezi 00 a 2n12n-1.

I když nejsme schopní hledat optimum efektivně, pro každý vstup je určitě optimum dobře definovaná hodnota. Můžeme se tedy ptát na otázku, kolik vyjde limita, kde místo skóre algoritmu vložíme optimum pro daný vstup, tedy limnδ(n)=limnγ(n)/n\lim_{n\to\infty} \delta(n) = \lim_{n\to\infty} \gamma(n)/n. Označme hodnotu této limity δ\delta.

Bohužel není zřejmé, že limita skutečně existuje, proto místo limity budeme často uvažovat limes supervisor a inferior. Ty budeme značit přidáním ±\pm jako horního indexu. Stejnou notaci budeme používat i u limit algoritmů.

Jelikož optimum musí být alespoň tak dobré jako výstup hladového řešení, dostáváme konstruktivní horní odhad δ+0.5\delta^+ \le 0.5. Hledáním lepších algoritmů můžeme horní odhad zlepšovat.

Překvapivě však je, že Hančl a kol. [4] ukázali dolní odhad δ0.214\delta^- \ge 0.214 pomocí počítání pravděpodobností pro náhodné obarvení. Samotný fakt, že δ>0\delta^- > 0 je již poměrně zajímavé tvrzení. To nám říká, že každý algoritmus na průměrném vstupu musí použít aspoň Ω(n)\Omega(n) změn barev. Nemůže tedy například existovat algoritmus, kterému by stačilo jen O(n/logn)\O(n / \log n) změn. To také říká, že odhadovat algoritmy pomocí limnγalg/n\lim_{n\to\infty} \gamma_{\alg}/n, je alespoň co se týče asymptotiky dostačující, protože vystihuje konstantu nejvýznačnějšího členu polynomiální aproximace.

Dále si představíme několik algoritmů, které se snaží konstruktivně zlepšit horní odhad na δ+\delta^+.

Algoritmus (Rekurzivní hladové řešení, rg): Z řady aut odstraníme první auto v řadě a druhé auto příslušného typu. Zbytek aut rekurzivně obarvíme a pak do řady přidáme odebranou dvojici tak, aby byl počet změn co možná nejmenší možný.

Autoři algoritmu, Andres and Hochstättler [3], o něm dokázali, že 25n815γrg(n)25n+710{2\over 5}\,n - {8\over 15} \le \gamma_{\algo{rg}}(n) \le {2\over 5}\,n + {7\over 10}, tedy δrg=2/5=0.4\delta_{\algo{rg}} = 2/5 = 0.4.

Dále se o zlepšení tohoto algoritmu pokusili Hančl a kol. [4]. Ti si všimli, že ve výstupu rekurzivního řešení se občas stane, že přebarvením dvojic typů aut se zlepší skóre. Ukázali, že takových dvojic je vždy ve výstupu lineárně mnoho a z toho pak ukázali horní odhad δ+0.4ε<0.4\delta^+ \le 0.4 - \varepsilon < 0.4 (pro ε\varepsilon zhruba 21062\cdot 10^{-6}).

Hančl a kol. [4] přišli ještě s dalším způsobem, jak vylepšit rekurzivní hladové řešení. Při běhu hladového řešení se občas stane, že některá dvojice aut stejného typu si může prohodit barvy bez změny skóre řešení. Když přidáváme auto do okolí takovéto dvojice, v některých případech můžeme provést toto prohození a tím snížit počet nově vytvořených změn barev. Budeme si tedy udržovat některé z takovýchto dvojic a pokud budeme přidávat auto do okolí evidované dvojice tak, že prohození barev dané dvojice by pomohlo, prohodíme její barvy.

Budeme pracovat nad rozšířenou abecedou barev o znak „*“ reprezentující neurčenou barvu. Při rekurzi budeme udržovat invariant, že pro každý typ obě auta buď budou označena * a nebo ani jedno z nich nebude označeno * a pak nutně budou mít různé barvy. Navíc bude platit, že * nikdy není na okrajích a nejsou dvě vedle sebe. Specificky tedy na * budeme přebarvovat dvojici aut v momentě, kdy získá všechny sousedy.

Pro popis algoritmu zavedeme notaci N(i)N(i), což bude reprezentovat multimnožinu barev aut sousedících s autem na pozici 0<i<2n10<i<2n-1, tedy {c(i1),c(i+1)}\{c(i-1), c(i+1)\}.

Algoritmus (Hvězdičkové rekurzivní řešení, rsg): Budeme pracovat nad rozšířenou škálou barev {0,1,}\{0,1,*\}. Ze vstupu odebereme auta typu t0t_0 a zarekurzíme se na zbytek. Tím získáme nějaké obarvení, které může použít na původní vstup s tím, že auta typu t0t_0 zatím nebudou obarvená, ty dobarvíme dle následujících pravidel:

  1. Když o0=1o_0 = 1 a n>1n>1 nastavíme c(1)=c(2)c(1)=c(2).
  2. Když o0=2n1o_0=2n-1 nastavíme c(0)=1c(0) = 1.
  3. Když N(o0)={t,t}N(o_0) = \{t,t\} pro nějaké t{0,1}t\in\{0,1\}, nastavíme i c(o0)=tc(o_0) = t.
  4. Když N(o0)={0,1}N(o_0) = \{0,1\}, nastavíme c(0)=c(1)c(0) = c(1).
  5. Když N(o0)={1c(1),}N(o_0) = \{1-c(1), *\}, nastavíme c(0)=c(1)c(0) = c(1).
  6. Když N(o0)={c(1),}N(o_0) = \{c(1), *\}, nastavíme c(0)=c(1)c(0) = c(1) a přenastavíme * v okolí o0o_0 na 1c(1)1-c(1) a druhé auto daného typu na opačnou barvu.

A druhé auto typu t0t_0 obarvíme zbývající barvou.

Pokud auta typu t1t_{1} spolu nesousedí, ∉N(1)N(o1)* \not\in N(1) \cup N(o_1) a prohození barev aut typu t1t_1 by zachovalo počet změn, přenastavíme jejich barvy na *.

Po návratu ze všech rekurzí zbylé dvojice aut * přebarvíme na dvě různé barvy.

Graf skóre 10001\,000 běhů hvězdičkového rekurzivního řešení pro n=200n=200.

Autoři algoritmu o něm vyslovili domněnku, že δrsg=113613130.370\delta_{\algo{rsg}} = {1\over 13} \cdot \sqrt{61} - {3\over 13} \doteq 0.370. Na obrázku je zobrazen histogram skóre tohoto algoritmu spuštěného na náhodných vstupech a hodnota z předešlé hypotézy.

Zobecněné verze a související problémy

Zobecněním binárního paint shopu je obecný paint shop problém, zavedený Eppingem a spol. [5]. Z něj pochází motivace k binární verzi.

Úloha (Obecný paint shop problém): V řadě je mm​ aut nn různých typů – nyní však již od každého typu libovolný počet. Dále máme definováno pro každou kombinaci typu a barvy (kterých také může být více než dvě), kolik aut daného typu má být nabarveno na danou barvu. Chceme tedy najít obarvení aut tak, aby počet změn barev v řadě byl co nejmenší.

Binární verze problému je tedy speciální případ obecného paint shop problému, kde od každého typu máme dvě auta, máme jen dvě požadované barvy a navíc platí, že pro každou kombinaci typu a barvy chceme právě jedno auto.

Souvisejícím problémem je dělení náhrdelníku zavedený v Alonově článku [6]:

Úloha (Dělení náhrdelníku): Skupina kk loupežníků uloupí náhrdelník skládající se z knkn drahokamů tt různých typů. Pro každý typ ii platí, že náhrdelník obsahuje právě kaika_i drahokamů daného typu (pro nějaké celé aia_i). Loupežníci si jej chtějí férově rozdělit. Náhrdelník tedy rozdělí na několik navzájem nepřekrývajících se intervalů, jejichž sjednocení je celý náhrdelník. Každý z intervalů pak přiřadí nějakému loupežníkovi tak, aby každý loupežník získat od každého typu ii právě aia_i drahokamů (což znamená, že všichni budou mít od každého typu stejný počet drahokamů). Chceme minimalizovat počet intervalů, na které je nutné náhrdelník rozdělit.

Nejprve si všimněme, že dělení náhrdelníku je speciálním případem obecného paint shop problému. Auta pro nás budou drahokamy. Barva auta bude označovat, který loupežník získá daný drahokam. Minimalizovat počet intervalů je to stejné jako minimalizovat počet hranic mezi nimi (kterých je o jedna méně něž intervalů). Ve vstupu problému dělení náhrdelníku navíc musí platit, pro každý typ má být stejný počet aut obarvený jednotlivými barvami (a tedy počet aut daného typu musí být násobkem kk). Naopak binární paint shop problém je speciálním případem dělení náhrdelníku pro dva lupiče, kde navíc platí, že všechna aia_i jsou 1 (tedy od každého typu jsou na náhrdelníku právě dva drahokamy).

Semidefinitní programování

V této kapitole si představíme princip semidefinitního programování (dále též SDP), jak jej popisují Gärtner a Matoušek [7], a jeho použití na problém maximálního řezu, z něhož vychází algoritmus na binární paint shop.

Nejprve zavedeme a připomeneme notaci důležitou v této kapitole. Nechť Rn×m\R^{n\times m} značí množinu nn-řádkových mm-sloupcových matic složených z reálných čísel. Řádky i sloupce indexujeme od 00, tedy matice ARn×mA\in \R^{n\times m} obsahuje prvky Ai,jA_{i,j} pro všechna 0i<n0\le i < n a 0j<m0 \le j < m. Nechť SYMn={XRn×nxi,j=xj,i pro vsˇechna 0i,j<n}\SYM_n = \{X \in \R^{n\times n} \mid x_{i,j} = x_{j,i} \hbox{\ pro všechna\ } 0 \le i,j < n\} je třída všech symetrických matic a nechť XY=0i<n0j<mxi,jyi,jX \circ Y = \sum_{0\le i<n} \sum_{0\le j<m} x_{i,j} y_{i,j} značí součet součinu matic po složkách. Nakonec X0X \succeq 0 bude značit skutečnost, že matice XX je pozitivně semidefinitní (bude vysvětleno později).

Úloha semidefinitního programování je optimalizační úloha (podobně jako lineární programování) následujícího formátu: maximalizujCX\progline{maximalizuj}{C \circ X}{} za podmıˊnekAiX=bi0i<m1\progline{za podmínek}{A_i \circ X = b_i}{0 \le i < m-1} X0.\progline{}{X \succeq 0.}{}

Vstupem programu tedy je velikost matice nn, počet podmínek mNm \in \N a pak pro každou podmínku matice AiSYMnA_i \in \SYM_n a číslo biRb_i \in \R. Výstupem je pak XSYMnX\in \SYM_n splňující výše uvedené podmínky.

Pro nás bude důležitý následující fakt z lineární algebry:

Fakt: Nechť XSYMnX \in \SYM_n. Následující tvrzení jsou ekvivalentní definice pozitivně semidefinitní matice:

  • Všechna vlastní čísla matice XX jsou nezáporná.
  • Pro každý vektor xRn\vec{x} \in \R^n platí xTXx0\vec{x}^{\rm T} X\vec{x}\ge 0.
  • Existuje matice YRn×nY \in \R^{n\times n} taková, že X=YTYX = Y^{\rm T} Y.

Pro nás bude důležitá zejména třetí podmínka, protože navíc platí, že ze semidefinitní matice XX zvládneme zkonstruovat YY v čase O(n3)\O(n^3) pomocí tzv. Choleského dekompozice.

Navíc pro libovolnou reálnou matici YY je YTYY^{\rm T} Y symetrická. Tedy semidefinitní programování můžeme chápat jako optimalizační úlohu na YRn×nY\in \R^{n\times n}. Pojďme se zamyslet nad tím, co v takovémto pohledu znamenají podmínky a účelová funkce. Matici YY můžeme považovat za nn sloupcových vektorů y0,,yn1\vec{y_0}, \dots, \vec{y_{n-1}} vedle sebe. Matice YTY^{\rm T} pak odpovídá těmto vektorům zapsaných v řádcích pod sebou. Matice X=YTYX = Y^{\rm T} Y tedy na pozici i,ji,j obsahuje skalární součin vektorů yi\vec{y_i} a yj\vec{y_j}. Účelová funkce tedy je lineární kombinací skalárních součinů a podmínky odpovídají vynucení rovnosti lineární kombinace skalárních součinů vektorů a konstanty. Speciálně tedy můžeme mít podmínku na délku vektoru: yi2=yiTyi=C|\vec{y_i}|^2 = \vec{y_i}^{\rm T}\vec{y_i} = C. Semidefinitní programování v tomto tvaru budeme nazývat semidefinitní programování v dekomponovaném tvaru.

Maximální řez

Představíme si pravděpodobnostní aproximační algoritmus založený na semidefinitním programování na následující problém:

Úloha: Nechť G=(V,E)G=(V, E) je graf s hranami ohodnocenými nezápornými čísly dle h:ER0+h: E \rightarrow \R^+_0. Řezem grafu rozumíme rozdělení vrcholů na dvě disjunktní množiny AB=VA \cup B = V. Hodnotou daného řezu je pak součet cen hran vedoucích mezi AA a BB. Tedy: H(A,B)={u,v}EuA,vBh(u,v) H(A,B) = \sum_{\{u,v\}\in E\atop u\in A, v\in B} h({u,v}) Cílem je maximalizovat hodnotu řezu.

Problém maximálního řezu (resp. rozhodovací verze, kde se ptáme na existenci řezu alespoň dané velikosti) je NP-úplný [8], proto se u něj zkoumají aproximační algoritmy a pravděpodobnostní aproximační algoritmy.

Nejprve si ukážeme triviální pravděpodobnostní 0.50.5-aproximační algoritmus:

Algoritmus: Každý vrchol uniformně náhodně přiřaď do množiny AA nebo BB.

Věta: Triviální algoritmus je pravděpodobnostní 0.50.5-aproximační algoritmus.

Důkaz: Každá hrana bude v řezu s pravděpodobností 1/21/2 – při umisťování druhého vrcholu dané hrany máme pravděpodobnost 1/21/2, že ho umístíme do stejné množiny a tedy hrana nebude součásti řezu a pravděpodobnost 1/21/2 že do opačné a tedy bude součástí řezu. Součet hran v řezu je součtem indikátorů jevů přítomnosti jednotlivých hran v řezu vynásobený jejich hodnotou. Z linearity střední hodnoty tedy střední hodnota součtu vah hran v řezu je 1/21/2 celkového součtu vah hran, což je alespoň 1/21/2 optima. QED

Povšimněme si, že triviální algoritmus dosáhl poměrně zajímavého aproximačního poměru a to se ani nedíval na vstup.

Předešlý algoritmus lze derandomizovat, jak popisuje Dimitrakakis [9]. Výsledný algoritmus pak vždy najde řešení obsahující alespoň 1/21/2 hran, tedy alespoň 1/21/2 optima.

Lepšího aproximačního poměru dosáhneme Goemansovým-Williamsonovým algoritmem, založeným na semidefinitním programování a proto popsaným mimo jiné v již dříve zmíněném úvodu do semidefinitního programování [7].

Naivní implementace je, že si pro každý vrchol uu vyrobíme proměnnou xux_u, která může nabývat hodnot ±1\pm 1, která bude říkat, do jaké množiny máme vrchol umístit. Do účelové funkce pak zakódujeme graf. Účelová funkce bude uvEh(u,v)(xuxv2+12)=F2+12uvEh(u,v)xuxv, \sum_{uv \in E} h(u,v)\cdot\left(- \frac{x_u x_v}{2} + \frac{1}{2}\right) = \frac{F}{2} + \frac{1}{2} \sum_{uv \in E} -h(u,v)x_u x_v , kde F=uvEh(u,v)F=\sum_{uv\in E} h(u,v) značí součet hodnot všech hran. Pro každou hranu tedy přičte h(u,v)h(u,v), pokud xux_u a xvx_v mají různá znaménka, a 00, pokud stejná.

Takovýto optimalizační problém bohužel ani pomocí semidefinitního programování neumíme řešit. Na to, abychom uměli vyjádřit nějaký součin, musíme použít semidefinitního programování v dekomponovaném tvaru. Pak ale místo toho, abychom měli pro každý vektor jen jednu proměnnou, budeme mít pro každý vrchol celý vektor proměnných a místo součinu proměnných budeme mít skalární součin těchto vektorů. Již ale současně neumíme zařídit, aby tyto vektory byly buď (1,0,,0)(1,0,\dots,0) nebo (1,0,,0)(-1,0,\dots,0). Můžeme ale přidat podmínku na to, aby délka každého vektoru byla 11. Tím jsme vyrobili relaxaci výše uvedeného programu, protože za těchto podmínek může vektor nabývat i jiných poloh než (±1,0,,0)(\pm 1,0,\dots,0). Celý algoritmus pak vypadá následovně:

Algoritmus (Goemansův-Williamsonův): Vyřešíme následující semidefinitní program v dekomponovaném tvaru: maximalizujuvEh(u,v)yuTyv\progline{maximalizuj}{\sum_{uv \in E} -h(u,v)\vec{y_u}^{\rm T} \vec{y_v}}{} za podmıˊnekyi=10i<V\progline{za podmínek}{|y_i| = 1}{0 \le i < |V|} Dále uniformně náhodně zvolíme jednotkový vektor vektor zRnz\in \R^n a do jedné množiny vybereme právě ty vrcholy vv, pro které yvTz0y_v^{\rm T} z \ge 0.

Semidefinitní program v algoritmu si lze představit jako umísťování nn bodů na n1n-1 dimenzionální sféru v Rn\R^n. Účelová funkce se snaží umístit body vrcholů spojených hranou co nejdále od sebe.

V případě, kdy jsme povolovali pouze hodnoty ±1\pm 1, bylo jasné, které vrcholy patří do které množiny. Nyní však výstupem optimalizace jsou vektory a tedy přiřazení množinám není tak jednoznačné. Rádi bychom umístili od sebe vzdálené body do různých množin. Na to můžeme rovnoměrně náhodně zvolit nadrovinu procházející počátkem a rozdělit body do množin podle toho, do které z polorovin určených danou nadrovinou patří. (Předpokládejme, že žádný z bodů neleží na nadrovině. Pravděpodobnost náležení nadrovině je 00. Pokud se tak stane, je vcelku jedno, do jaké množiny ho vložíme.)

To nám zaručí, že dvojice bodů daleko od sebe budou mít velkou pravděpodobnost toho, že budou v různých poloprostorech. Semidefinitní programování se tedy snaží dostat dvojice bodů odpovídající vrcholům spojených hranou daleko od sebe a podle toho se zvyšuje pravděpodobnost toho, že vrcholy budou v jiných množinách a tedy hrana bude v řezu.

Výběr nadroviny a rozdělování bodů jde implementovat pomocí výběru vektoru z\vec{z} kolmého na nadrovinu. Pro každý bod pak stačí spočítat skalární součin se z\vec{z} a podle znaménka víme, do kterého poloprostoru patří. Pokud vybereme uniformně náhodný jednotkový vektor, tak jsme uniformně náhodně vybrali nadrovinu. Jednotkový vektor můžeme generovat tak, že vygenerujeme náhodný vektor nezávisle po složkách z normálního rozdělení, a pak ho znormujeme. Povšimněme si, že normalizace ani není potřeba, protože to na znaménku součinů nic nemění.

Nyní pojďme precizněji spočítat pravděpodobnost toho, že se dvojice bodů (vektorů) yu\vec{y_u}, yv\vec{y_v} rozdělí náhodnou nadrovinou ρ\rho v závislosti na hodnotě skalárního součinu mezi nimi. Můžeme se podívat na rovinu, ve které leží počátek a oba vektory yu\vec{y_u}, yv\vec{y_v} (viz obrázek ). Průnik náhodné nadroviny s touto rovinou tvoří rovnoměrně náhodně vybranou přímku procházející počátkem.

Znázornění řezu rovinou obsahující yu\vec{y_u} i yv\vec{y_v}.

Zajímá nás tedy, jaká je pravděpodobnost toho, že jedno z ramen nadroviny bude uvnitř konvexního úhlu mezi yu\vec{y_u} a yv\vec{y_v}. Velikost tohoto úhlu označme α\alpha. Víme, že yuTyv=11cosα\vec{y_u}^{\rm\, T}\vec{y_v} = 1 \cdot 1 \cdot \cos \alpha. Náhodnou přímku můžeme vygenerovat jako náhodný úhel β\beta mezi 00 a 2π2\pi s tím, že přímka pak povede směrem β\beta a (β+π)mod2π(\beta + \pi) \mod 2\pi. Nikdy však uvnitř konvexního úhlu nebudou obě ramena přímky, tedy pravděpodobnost, že alespoň jedno bude uvnitř a tedy body budou oddělené je:

2α2π=απ=arccosyuTyvπ \frac{2 \cdot \alpha}{2\pi} = \frac{\alpha}{\pi} = \frac{\arccos \vec{y_u}^{\rm\,T}\vec{y_v}}{\pi}

U každé hrany uvuv optimalizujeme h(u,v)yuTyv-h(u,v) \vec{y_u}^{\rm T}\vec{y_v}, což je ekvivalentní optimalizování h(u,v)(12yuTyv2)h(u,v)\cdot\left(\frac{1}{2} - \frac{\vec{y_u}^{\rm T}\vec{y_v}}{2}\right).

Graf funkcí pravděpodobnosti řezu a účelové funkce.

Nyní se podívejme na poměr mezi pravděpodobností toho, že hrana bude v řezu, a účelovou funkcí před vynásobením hodnotou hrany jakožto funkci proměnné x=yuTyvx = \vec{y_u}^{\rm\,T} \vec{y_v} v intervalu [1,1]\left[ -1, 1 \right]:

arccosyuTyvπ/1yuTyv2=arccosxπ/1x2 \frac{\arccos \vec{y_u}^{\rm\,T} \vec{y_v}}{\pi} / \frac{1 - \vec{y_u}^{\rm T}\vec{y_v}}{2} = \frac{\arccos x}{\pi} / \frac{1 - x}{2}

Graf poměru pravděpodobnosti řezu a účelové funkce.

Fakt: Pro každé x[1,1]x\in\left[-1,1\right] platí: arccosxπ/1x2>0.8785\frac{\arccos x}{\pi} / \frac{1-x}{2} > 0.8785

Označme tuto hodnotu c=0.8785c = 0.8785.

Tedy když je účelová funkce dané hrany h(u,v)rh(u,v)r, tak pravděpodobnost výběru hrany do řezu bude alespoň crcr. Sečtením přes všechny hrany (z linearity středních hodnot) tedy získáme, že střední hodnota součtu hran v řešení je alespoň cRcR, kde R=uvEh(u,v)(12yuTyv2)R = \sum_{uv \in E} h(u,v)\cdot\left(\frac 12 - \frac{\vec{y_u}^{\rm T}\vec{y_v}}2\right), tedy jedno z ekvivalentních vyjádření účelové funkce.

Pokud tedy najdeme dobré řešení semidefinitního programu, ve střední hodnotě pak najdeme i dobré řešení maximálního řezu. Dále však musí platit, že optimální řešení semidefinitního programu je alespoň součet hran optimálního řešení maximálního řezu, když za účelovou funkci považujeme uvEh(u,v)(12yuTyv2)\sum_{uv \in E} h(u,v)\cdot\left(\frac 12 - \frac{\vec{y_u}^{\rm T}\vec{y_v}}2\right). Jedno z možných řešení totiž snadno sestrojíme z maximálního řezu: Vrcholům jedné množiny přidělíme vektory (1,0,,0)(1,0,\dots,0) a druhé (1,0,,0)(-1,0,\dots,0). Účelová funkce pak přičte h(u,v)h(u,v) za každou hranu v řezu a 00 jinak.

Bohužel na rozdíl od lineárního programování, u semidefinitního programování nejsme schopní v polynomiálním čase najít optimální řešení. Naštěstí však platí, že v polynomiálním čase za určitých podmínek jsme schopní se mu libovolně přiblížit. Přesněji řečeno, pro každé ε>0\varepsilon > 0 jsme schopní najít řešení s účelovou funkcí nejdále ε\varepsilon od optima. Ovšem musí platit, že všechna přípustná řešení jsou dostatečně malá. Přesněji řečeno, musí platit, že Frobeniova norma všech přípustných matic je omezena konstantou s polynomiální délkou zápisu. Tohoto výsledku jde dosáhnout pomocí elipsoidové metody, která má nejlepší teoretické výsledky. V praxi se však často používají jiné algoritmy. Všechny naše programy budou splňovat podmínky na řešení, protože každá z hodnot hledané matice nutně bude ležet v intervalu [1,1][-1, 1].

Věta: Goemansův-Williamsonův algoritmus je pravděpodobnostní 0.8780.878-aproxi-mační algoritmus.

Důkaz: Využitím předešlých pozorování a elipsoidové metody získáme (MC značí max cut, tedy maximální řez): E[Rˇesˇenıˊ MC]cRˇesˇenıˊ SDPc(1ε)Optim. SDPc(1ε)Optim. MC. \E[\hbox{Řešení MC}] \ge c\cdot\,\hbox{Řešení SDP} \ge c(1-\varepsilon)\cdot\,\hbox{Optim. SDP} \ge c(1-\varepsilon)\cdot\,\hbox{Optim. MC}. Pro dostatečně malé ε\varepsilon se tedy jedná o pravděpodobnostní 0.8780.878-aproximační algoritmus. QED

Řešení semidefinitním programováním

Řešení vychází z Goemansova-Williamsonova algoritmu na maximální řez. Pro každé auto nám bude semidefinitní program umísťovat bod (někdy také chápán jako vektor) na jednotkovou sféru. Poté náhodně rozřízneme nadrovinou sféru na dvě poloviny a podle toho, do které poloviny auto patří, zvolíme jeho barvu.

Rozdílné barvy aut i,ji, j stejného typu zařídíme tak, že vynutíme yi=yj\vec{y_i} = -\vec{y_j}. Na to nám stačí jediná podmínka – říct, že jejich skalární součin je 1-1.

Účelovou funkcí pak řekneme, že sousední auta mají preferovat stejnou barvu, tedy jejich body na sféře mají být blízko sebe, což znamená, že skalární součin má být co největší.

Algoritmus (Řešení pomocí semidefinitního programování, sdp): Vyřešíme následující semidefinitní program v dekomponovaném tvaru: maximalizuj0i<2n1yiTyi+1\progline{maximalizuj}{\sum_{0\le i<2n-1} \vec{y_i}^{\rm T} \vec{y_{i+1}}}{} za podmıˊnekyai,0=yai,10i<n\progline{za podmínek}{\vec{y_{a_{i,0}}} = -\vec{y_{a_{i,1}}}}{0\le i < n} yi=10i<2n\progline{}{|y_i| = 1}{0\le i < 2n} Dále uniformně náhodně zvolíme jednotkový vektor zR2nz\in \R^{2n} a červeně obarvíme právě ty auta ii, pro která yiTz0y_i^{\rm T} z \ge 0. Náhodných výběrů vektoru je možné provést vícero a pak vybrat nejlepší nalezené řešení.

Pro každou dvojici do účelové funkce přičteme číslo mezi 1-1 a 11, kde 11 značí, že vektory jsou stejné, a 1-1, že jsou protilehlé. Účelovou funkci můžeme ekvivalentně zapsat jako minimalizuj0i<2n112yiTyi+12=2n12120i<2n1yiTyi+1 \hbox{minimalizuj}\qquad \sum_{0\le i < 2n-1} \frac{1}{2} - \frac{\vec{y_i}^{\rm T} \vec{y_{i+1}}}{2} = \frac{2n-1}2 - \frac12 \sum_{0 \le i < 2n-1} \vec{y_i}^{\rm T} \vec{y_{i+1}}

Nyní tedy pro každou dvojici sousedních aut přičítáme číslo mezi 00 a 11, kde 00 přičteme pro stejné vektory, mezi nimiž nikdy nebude změna barvy a 11 přičteme v případě opačných vektorů, mezi nimiž se nutně barva změní. Účelovou funkci se snažíme minimalizovat.

Věta: Optimum semidefinitního programu, který minimalizuje účelovou funkci 2n12120i<2n1yiTyi+1\frac{2n-1}2 - \frac12 \sum_{0 \le i < 2n-1} \vec{y_i}^{\rm T} \vec{y_{i+1}} je menší rovno počtu změn v optimálním obarvení aut.

Důkaz: Podíváme se na optimální obarvení aut a každému červenému autu přiřadíme vektor (1,0,,0)(1,0,\dots,0) a modrému (1,0,,0)(-1,0,\dots,0). Toto je validní řešení semidefinitního programu. Účelová funkce za každou změnu barev přičte 11 a zbytek součtu je 00, takže její hodnota je přesně počet změn barev. QED

Nyní by se hodilo odhadnout střední hodnotu počtu změn barev stejně jako u maximálního řezu. Jeho důkaz vycházel z pozorování ohledně poměru pravděpodobností výběru a účelové funkce, přesněji řečeno z toho, že tento poměr umíme zdola odhadnout. Ovšem v našem případě místo maximalizace děláme minimalizaci účelové funkce a pravděpodobnosti. Tedy abychom mohli tvrdit, že pravděpodobnost je menší než nějaký násobek účelové funkce, potřebovali bychom horní odhad poměru. Ovšem tento poměr je neomezený (viz obrázky a ). V okolí x=1x=1 jsou obě funkce poblíž 00, ovšem pravděpodobnost se k nule blíží mnohem strměji. Tedy pro dvojici vektorů poblíž sebe je skalární součin skoro 1, ovšem pravděpodobnost oddělení je libovolně krát větší než vzdálenost součinu od jedné.

O binárním paint shop problému je navíc známé, že je za předpokladu Unique game conjecture a PNP\P\neq \NP je polynomiálně neaproximovatelný s konstantním faktorem [2], takže nemožnost výše uvedeného postupu by nás ani neměla zaskočit, protože v případě, že by šlo udělat odhad tímto způsobem, získali bychom pravděpodobnostní aproximační algoritmus.

Místo toho se podíváme na rozdíl pravděpodobnosti a účelové funkce.

Graf rozdílu pravděpodobnosti řezu a účelové funkce.

Lemma: Pro každé x[1,1]x\in\left[-1,1\right] platí: 0.1053arccosxπ(12x2)0.1053 -0.1053 \le \frac{\arccos x}{\pi} - \left(\frac{1}{2} - \frac{x}{2}\right) \le 0.1053

Důkaz: Jedná se o spojitou funkci na kompaktním intervalu, takže maximum a minimum může nabývat jen v krajních bodech a v místech s nulovou derivací. V obou krajních bodech je však její hodnota 00, zbývá tedy prověřit nulové derivace. Zderivováním získáme: f(x)=1πx2+1+12,f'(x) = - \frac{1}{\pi \sqrt{-x^2 +1}} + \frac12 ,

Derivace funkce ff.

což má dva kořeny x=±π24/πx = \pm \sqrt{\pi^2 - 4}/\pi, a hodnota hh v nich je přibližně ±0.105256\pm 0.105256. QED

Označme konstantu z předchozího lemmatu jako d=0.1053d = 0.1053.

Věta: Střední hodnota (vzhledem k náhodným bitům generovaným algoritmem) počtu změn v sdp\algo{sdp} řešení je nejvýše o 0.212n0.212n horší než optimum.

Důkaz: Když účelová funkce pro sousední dvojici aut je rr, tak pravděpodobnost změny barev je nejvýše d+rd + r. Sečtením přes všechny hrany (z linearity středních hodnot) tedy získáme, že střední hodnota součtu změn je nejvýše d(2n1)+Rd(2n-1) + R, kde R=i2n112yiTyi+12R = \sum_i^{2n-1} \frac{1}{2} - \frac{\vec{y_i}^{\rm T} \vec{y_{i+1}}}{2}, tedy jedno z ekvivalentních vyjádření účelové funkce.

Celkově tedy víme: E[γsdp(α)]2dn+Rˇesˇ. SDP2dn+Opt. SDP+ε2dn+γ(α)+ε \hskip -2pt \E[\gamma_{\algo{sdp}}(\alpha)] \le 2dn + \hbox{Řeš. SDP} \le 2dn + \hbox{Opt. SDP} + \varepsilon \le 2dn + \gamma(\alpha) + \varepsilon

Pro vhodně zvolené ε\varepsilon jsme tedy dokázali požadovanou vzdálenost od optima. QED

Na rozdíl od jiných řešení binárního paint shop problému, zde se jedná o střední hodnotu přes náhodné rozhodnutí algoritmu, nikoliv přes náhodnou distribuci na vstupech. Tedy když spustíme algoritmus na konkrétní instanci, dostaneme řešení a také dolní odhad na optimalní řešení dané instance (ten jednak můžeme odvodit z hodnoty řešení ale také přímo z účelové funkce semidefinitního programu).

Implementační zjednodušení

Předchozí semidefinitni program ještě lze nepatrně zjednodušit se zachováním všech potřebných vlastností. Místo toho, abychom měli vektor pro každé auto, uděláme si jen vektor pro každou dvojici aut stejného typu. Ten bude odpovídat řekněme prvnímu autu z dvojice. Všimneme si, že účelovou funkci zvládneme stále vyjádřit. Kdykoliv jsme používali vektor druhého auta, stačí použít mínus vektor prvního auta. Tedy stačí některé členy jednou až dvakrát vynásobit hodnotou 1-1.

Výsledný program vypadá takto:

maximalizuj0i<2n1ytiTyti+1PiPi+1\progline{maximalizuj}{\sum_{0\le i < 2n-1} \vec{y_{t_i}}^{\rm T} \vec{y_{t_{i+1}}} P_{i} P_{i+1}}{} za podmıˊnekyi=10i<n\progline{za podmínek}{|y_i| = 1}{0 \le i < n}

Výhodou je, že je potřeba poloviční počet proměnných, matice je čtvrtinová a odebrali jsme nn podmínek, proto v implementační části práce využijeme této formy programu.

Měření řešení BPS

Součástí práce je implementace algoritmů řešících Binární paint shop problém. Každý z nich byl následně spuštěn pro různé velikosti, pokaždé na 10001\,000 nezávisle náhodně vybraných vstupech s počtem typů aut 10, 20, 50, 100, 200, 400, 566, 800, 1131, 1600, 2263 a 3200. (Hodnoty, co nejsou hezká čísla jsou zhruba 2\sqrt{2}-násobky předešlé hodnoty, tedy v polovině mezi okolními hodnotami na logaritmické stupnici.) Jedna z implementací sdp\algo{sdp} – pomocí sage vyžaduje velké množství paměti a proto byla spuštěna jen na vstupech do velikosti 566566. Celý test běžel několik dní na čtveřici stojů, na každém dva programy současně, každý z nich běžel jednovlákonvě a využíval nejvýše 16 GB operační paměti. U sdp\algo{sdp} řešení bylo použito 10 náhodných řezů a vždy byl vybraný nejlepší z nich. Gitový repozitář s implementací i naměřenými daty je k dispozici na https://gitlab.kam.mff.cuni.cz/jirikalvoda/binary-paint-shop-problem. Na následujících stranách jsou zpracovaná různá naměřená data.

Pro reprodukovatelnost byly vstupy generovány deterministicky ze seedů. Se stejným seedem se tedy vždy vygeneruje stejný vstup a ideálně i stejné řešení. Pro různé algoritmy a velikosti vstupů byly použité různé seedy.

Praktické řešení semidef. programů

U většiny algoritmů byla implementace poměrně přímočará. Ovšem u řešení semidefinitního programování je většina složitosti algoritmu schovaná právě v řešení semidefinitních programů, což už svojí složitostí nepatří mezi algoritmy, které bychom chtěli (re)implementovat. Proto je žádoucí se spolehnout na funkčnost již existujících implementací. Bohužel kvalita dostupných řešičů semidefinitních programů je poměrně nízká.

SDPA-C

Jedním z použitých programů byl SDPA-C [10]. Jedná se o knihovnu v C++ založenou na metodě vnitřních bodů v primárním a duálním problému. Dle autorů projektu [10]:

SDPA (SemiDefinite Programming Algorithm) is one of the most efficient and stable software packages for solving SDPs based on the primal-dual interior-point method. It fully exploits the sparsity of given problems.

Pro účely práce byla použita verze SDPA-C ze dne 2023-06-21 (soubor sdpa-c.7.3.8.src.20180125.tar.gz). Kompilace je poměrně komplikovaná. Jednak vyžaduje velké množství nainstalovaného software (například překladač Fortranu), ale také poskytnutý Makefile není plně kompatibilní s moderními verzemi překladačů.

Bohužel i po úspěšné kompilaci stále není vyhráno. Dodaný program přeložený aktuálním kompilátorem bohužel nefunguje.

Při spuštění i na malých vstupech program rychle spadne s chybou Segmentation Fault ve funkci Newton::compute_bMatgVec_dense_threads_SDP.

Při následujícím ladění programu bylo zjištěno, že se program zacyklí v dané funkci ve smyčce, při které inkrementuje hodnotu proměnné Column_Number až do doby, kdy přeteče, což už přímo vede k pádu programu. Pohledem na kód to vypadá, že toto by se nemělo dít. Program už mnohokrát měl ukončit smyčku a doběhnout na konec funkce, ovšem po přidání dostatečného počtu debugovacích výpisů je vidět, že program cyklus opustí, provede příkazy mezi cyklem a koncem funkce a pak se zase objeví uprostřed cyklu.

Problém byl v tom, že funkce vracející void* dle normy [11] bodu 6.6.3 musí skončit pomocí return a nemůže jen tak opustit funkci dojitím na její konec. Pokud se tak stane, jedná se o nedefinované chování, nikoliv jen o nedefinovanou hodnotu navrácenou z funkce. Kdyby se jednalo jen o nedefinovanou hodnotu, tak se nic zásadního neděje. Funkce může vrátit cokoliv, ale to je nám jedno, protože výsledek se ignoruje.

Ovšem jelikož se jedná o nedefinované chování, překladač může program přeložit tak, že v takovémto případě udělá prakticky cokoliv. A v tomto případě optimalizace překladače přeložili program tak, že v případě opuštění funkce se vykonávání programu vrátí zpět dovnitř a pokračuje se v iterování smyčky. To je důsledkem toho, jakým způsobem se snaží překladač optimalizovat kód. Překladače nemusí dodržovat naprogramovanou strukturu programu. Tedy není problém přesunout část za smyčkou do ní na místo, kde se smyčka opouští. Když překladač ví, že v korektním programu by se tudy nemělo opouštět funkci, nemusí se překladač obtěžovat umísťováním explicitního návratu z funkce na dané místo.

Naštěstí oprava tohoto problému je přímočará – stačí do takovýchto funkcí explicitně dopsat return NULL;.

Toto bohužel není jediný problém s SDPA-C. Na některých vstupech knihovna dojde do stavu, kdy nemá semidefinitní matici a výpočet spadne s následující chybou:

CHOLMOD warning: matrix not positive definite.
file: ../Supernodal/t_cholmod_super_numeric.c line: 911
getMinEigenValue:: cannot decomposition ::
line 193 in sdpa_linear.cpp

Tedy během výpočtu program něco spočte špatně a jako mezivýsledek mu vyjde matice, co není pozitivně semidefinitní, se kterou již dále nejde pokračovat. Příčinu této chyby se bohužel nepodařilo odhalit, protože na rozdíl od předchozího problému vůbec není jasné, kde začít hledat. Detekce nesemidefinitnosti matice totiž může být v úplně jiné části kódu, než kde nastane chyba.

Problém se projevuje například na vstupu s n=5n=5 a seedem 1919.

Další problém (nebo ten stejný) se projevuje zejména u větších vstupů. Uprostřed algoritmu se také objeví chybová hláška o nesemidefinitnosti matice. Následně program udělá mnoho iterací s nekonečnou účelovou funkcí, dokud se nepřekročí maximální počet iterací, a pak je vrácena matice ze samých ±\pm \infty, což dokonce porušuje zadané podmínky. Toto se stává například na seedu 1818 pro n=150n = 150.

Vzhledem k výše uvedeným problémům dává smysl se porozhlédnout po alternativách.

Sage

SageMath je dle oficiálních stránek [12] open-source software pro matematické výpočty založený na rozšířené syntaxi pythonu, takže je poměrně snadné ho využívat i jako programovací jazyk. Pro účely práce byla použita verze sage 10.1 ze dne 2023-08-20. Sage mimo jiné obsahuje rozhraní pro řešení semidefinitních programů. Rozhraní je navrženo tak, aby bylo schopné pracovat s více různými backendy pro řešení semidefinitních programů. Bohužel z dokumentace [13] nebylo zřejmé, jaké backendy sage podporuje. Při zavolání default_sdp_solver("") se objeví chybová hláška, která tvrdí, že backend by mělo jít nastavit na CVXOPT (což je výchozí hodnota) nebo Matrix, případně uživatelem dodanou třídu. Ovšem při přepnutí na Matrix spuštění řešení spadne na NotImplementedError, tedy zdá se, že ani tento backend není implementovaný (alespoň ve verzi, co mám k dispozici) a tedy jediná možnost je CVXOPT.

Drobným problémem je, že dle dokumentace [13] rozhraní sage vyžaduje formulování vstupu jako primárního semidefinitního programu, ovšem náš algoritmus je založený na řešení duálního semidefinitního programu. Mezi nimi však lze snadno přecházet pomocí triviální úpravy, ovšem výsledný kód pak vypadá velice neintuitivně.

Hodnoty skalárních součinů

V odhadu střední hodnoty počtu změn barev v sdp\algo{sdp} řešení jsme využívali toho, že funkce rozdílu pravděpodobnosti řezu a účelové funkce (funkce ff) je nejvýše d=0.1053d = 0.1053. Ovšem tato funkce nenabývá takto vysokých hodnot zdaleka všude, na polovině definičního oboru je dokonce záporná (viz obrázek ). Kdyby se tedy alespoň část optimalizovaných skalárních součinů vyskytovala mimo oblast, kde ff nabývá vysokých hodnot, šel by odhad zlepšit.

Bohužel dle naměřených dat to vypadá, že hodnoty skalárních součinů se koncentrují pouze poblíž maxima ff. Viz obrázek . Tento výsledek intuitivně dává smysl, protože jenom takto může semidefinitní program dosáhnout lepší účelové funkce než počet změn barev v optimálním řešení. Ovšem náš jediný dolní odhad je hodnota semidefinitního programu a tedy nejsme schopní více přiblížit dolní a horní odhad k sobě.

Distribuce skalárních součinů 100100 běhů algoritmu pro n=200n=200.

Z grafu je vidět, že skoro nikdy semidefinitní program neumístí sousední body do protilehlých částí. Drobnou výjimku tvoří hodnota skalárního součinu okolo 1-1, kterých semidefinitní program za 100100 běhů vyrobil zhruba 100100. K tomuto mohl být donucen existencí dvojic aut stejného typu hned vedle sebe, kdy nemá jinou možnost než mezi nimi mít skalární součin 1-1.

Lemma: Střední hodnota počtu sousedních aut stejného typu je 11.

Důkaz: Pro každý typ auta máme (2n2)=2n(2n1)2=n(2n1){2n \choose 2} = {2n(2n-1) \over 2} = n (2n-1) možných pozic, kde se mohou nacházet a z toho 2n12n-1 z nich jsou vedle sebe. Střední hodnota indikátoru souslednosti aut daného typu je tedy 2n1n(2n1)=1n{2n-1 \over n (2n-1)} = {1\over n}. Z linearity střední hodnoty tedy počet sousedících aut stejného typu je n/n=1n/n = 1. QED

Ve 100 vstupech by tedy sousedních aut stejného typu mělo být ve střední hodnotě zhruba 100, což z části vysvětluje pozorovanou anomálii. Není však vyloučeno, že hodnoty skalárního součinu 1-1 nebo blízké program dosáhne i jinak.

Dimenze SDP

Semidefinitní program rozmísťuje vektory do n1n-1 dimenzionální sféry. Z naměřených dat však vychází, že semidefinitní program většinou generuje řešení, které má mnohem menší dimenzi. Přesněji řečeno, pro řešení často platí, že všechny vektory v něm mají několik prvních souřadnic velké hodnoty a ve zbylých souřadnicích mají hodnoty blízké nule. Tedy kdybychom vektory promítli na méně dimenzionální sféru (vzali místo nich nejbližší bod na ní), tak se účelová funkce moc nezmění.

Nevíme o žádné hypotéze, proč program generuje řešení s malou dimenzí. Taktéž není jasné, jestli či jak by toho šlo využit pro získání lepšího řešení či dolního odhadu. Z naměřených dat zobrazených na obrázcích na následujících stranách však vychází, že průměrná dimenze je mnohem menší než nn, ovšem nejspíše není omezena žádnou konstantou, tedy s rostoucím nn také roste, ale mnohem pomaleji. Hypotéza zní, že průměrná dimenze leží v Θ(logn)\Theta(\log n).

Malá dimenze má ale zásadní výhodu pro vizualizaci řešení, protože trojrozměrný prostor (tedy sféru dimenze 2) si zvládne člověk snadno představit. Z čehož plyne, že zhruba polovinu řešení pro n=50n=50 jsme schopni zakreslit jen s drobným zkreslením, tak, jak je ukázáno na obrázku .

Světlá barva bodu značí bod na zadní straně sféry. Černé čáry spojují sousední auta a šedé jsou jim středově symetrické (protože dvojice aut, jejichž druhá auta stejného typu jsou vedle sebe, je také přitahována k sobě).

Vizualizace jednoho z řešení pro n=50n=50, které se vejde do 3D.
Maximální hodnota v dané dimenzi pro n=400n=400.
Počet vektorů s danou souřadnicí větší než 0.050.05 pro n=400n=400.
Maximální hodnota v dané dimenzi pro n=200n=200.
Počet vektorů s danou souřadnicí větší než 0.050.05 pro n=200n=200.
Maximální hodnota v dané dimenzi pro n=100n=100.
Počet vektorů s danou souřadnicí větší než 0.050.05 pro n=100n=100.
Maximální hodnota v dané dimenzi pro n=50n=50.
Počet vektorů s danou souřadnicí větší než 0.050.05 pro n=50n=50.

Časová složitost algoritmu sdp\algo{sdp}

Víme, že existuje implementace algoritmu sdp\algo{sdp} s polynomiální časové složitosti (za použití elipsoidové metody). Použité řešiče však využívají jiných metod řešení semidefinitních programů a ani jeden z nich moc neslibuje, jakou přesně složitost má. Proto je na místě změřit, jak rychlé řešení jsou.

Testování probíhalo na stroji s procesorem AMD Ryzen 5 7600. Programům bylo poskytnuto 16GB16\,{\rm GB} operační paměti a běh byl omezen na jedno jádro procesoru. Během výpočtu na stroji neběželo nic kromě výpočtu a základních funkcí operačního systému.

Závislost času řešení na velikosti vstupu.

Dle výše uvedeného grafu můžeme regresí v logaritmickém grafu usuzovat, že časová složitost obou algoritmů je v O(n4)Ω(n3)\O(n^4) \cap \Omega(n^3). Implementace pomocí SDPA-C má menší multiplikativní konstantu a navíc mnohem rychlejší čas startu, který se zejména projevuje na malých instancích.

Skóre

Nejzajímavější je pro nás naměřené (relativní) skóre algoritmů.

Mezi uvažovanými řešeními jsou dvě implementace sdp\algo{sdp}. Implementace pomocí sage bohužel vyžaduje velké množství paměti a proto nebyla testovaná na tak velkých vstupech. O implementaci pomocí SDPA-C víme, že občas chybuje. Naštěstí chyby nenastávají tak často, aby to moc ovlivňovalo výsledné skóre. Pokud algoritmus chyboval a vrátil nějaké řešení, je uvažováno skóre daného řešení. Pokud algoritmus žádné řešení nevrátil, uvažuje se místo toho hodnota nn, což je jistě horní odhad na snadno dosažitelné řešení.

Naměřená závislost relativního skóre řešení na velikosti vstupu.

Na výše uvedeném grafu a tabulkách na následujících stranách si můžeme všimnout, že s rostoucím nn se u všech měřených algoritmů zmenšuje rozptyl relativního skóre.

Z grafu vidíme, že pro dostatečně velká nn je naměřené relativní skóre algoritmu sdp\algo{sdp} menší než 0.340.34. Z toho můžeme tedy usuzovat, že δsdp(n)0.34\delta_{\algo{sdp}}(n) \le 0.34 pro n{100,200,400,566,800,1131,1600,2263}n\in\{100, 200, 400, 566, 800, 1131, 1600, 2263\}. Z toho pak můžeme vyslovit hypotézu, že δsdp(n)0.34\delta_{\algo{sdp}}(n) \le 0.34 pro n100n \ge 100 a tedy i δsdp+0.34\delta_{\algo{sdp}}^+ \le 0.34.

Z naměřených dat také můžeme usuzovat, že sdp\algo{sdp} je lepší než libovolný z jiných představených algoritmů.

nn δg(n)\overline{\delta_{\algo{g}}(n)} Sδg(n)S_{\delta_{\algo{g}}}(n) 5%5 \% 25%25 \% 50%50 \% 75%75 \% 95%95 \%
10 0.53 0.158 0.3 0.4 0.5 0.6 0.8
20 0.51 0.109 0.35 0.45 0.5 0.6 0.7
50 0.508 0.068 0.4 0.46 0.5 0.56 0.62
100 0.502 0.0496 0.42 0.47 0.5 0.53 0.58
200 0.501 0.0356 0.44 0.48 0.5 0.525 0.56
400 0.5 0.0258 0.46 0.482 0.5 0.517 0.542
566 0.5 0.0221 0.465 0.484 0.5 0.516 0.537
800 0.501 0.0171 0.472 0.489 0.5 0.511 0.529
1131 0.501 0.0151 0.476 0.49 0.5 0.511 0.526
1600 0.501 0.012 0.481 0.492 0.501 0.508 0.52
2263 0.5 0.0105 0.482 0.492 0.5 0.507 0.516
3200 0.5 0.00883 0.486 0.494 0.501 0.507 0.514

Veškeré hodnoty jsou zaokrouhleny na 3 platné číslice.

δalg(n)\overline{\delta_{\alg}(n)} značí výběrový průměr, tedy 1m0i<mri\frac{1}{m}\sum_{0\le i < m} r_i, kde mm je počet testů a rir_i je relativní skóre ii-tého z nich.

Sδalg(n)S_{\delta_{\alg}(n)} značí výběrovou směrodatnou odchylku, tedy 1m10i<m(riδalg(n))2\sqrt{\frac{1}{m-1}\sum_{0\le i < m} \left(r_i - \overline{\delta_{\alg}(n)}\right)^2}.

Statistika algoritmu g\algo{g}.
nn δrg(n)\overline{\delta_{\algo{rg}}(n)} Sδrg(n)S_{\delta_{\algo{rg}}}(n) 5%5 \% 25%25 \% 50%50 \% 75%75 \% 95%95 \%
10 0.46 0.131 0.3 0.4 0.5 0.5 0.7
20 0.429 0.0926 0.3 0.35 0.45 0.5 0.6
50 0.41 0.0571 0.32 0.38 0.42 0.44 0.5
100 0.406 0.0396 0.34 0.38 0.41 0.43 0.47
200 0.403 0.0284 0.355 0.385 0.405 0.42 0.45
400 0.402 0.0194 0.37 0.388 0.403 0.415 0.435
566 0.402 0.017 0.375 0.39 0.403 0.413 0.431
800 0.401 0.0139 0.378 0.391 0.401 0.41 0.422
1131 0.4 0.0121 0.38 0.393 0.401 0.408 0.42
1600 0.4 0.0103 0.384 0.393 0.401 0.407 0.417
2263 0.4 0.00835 0.387 0.394 0.4 0.406 0.413
3200 0.4 0.00714 0.388 0.396 0.4 0.405 0.412
Statistika algoritmu rg\algo{rg}.
nn δrsg(n)\overline{\delta_{\algo{rsg}}(n)} Sδrsg(n)S_{\delta_{\algo{rsg}}}(n) 5%5 \% 25%25 \% 50%50 \% 75%75 \% 95%95 \%
10 0.446 0.123 0.3 0.4 0.4 0.5 0.6
20 0.411 0.0832 0.25 0.35 0.4 0.45 0.55
50 0.387 0.0517 0.3 0.36 0.38 0.42 0.48
100 0.377 0.0353 0.32 0.35 0.38 0.4 0.43
200 0.375 0.025 0.335 0.36 0.375 0.39 0.415
400 0.372 0.0175 0.343 0.36 0.372 0.383 0.4
566 0.371 0.0142 0.346 0.362 0.371 0.382 0.394
800 0.372 0.0126 0.35 0.364 0.371 0.38 0.393
1131 0.371 0.0102 0.355 0.364 0.371 0.378 0.388
1600 0.371 0.00875 0.357 0.365 0.371 0.377 0.385
2263 0.371 0.00763 0.358 0.366 0.371 0.376 0.384
3200 0.37 0.00624 0.36 0.366 0.37 0.375 0.38
Statistika algoritmu rsg\algo{rsg}.
nn δsdp(n)\overline{\delta_{\algo{sdp}}(n)} Sδsdp(n)S_{\delta_{\algo{sdp}}}(n) 5%5 \% 25%25 \% 50%50 \% 75%75 \% 95%95 \%
10 0.421 0.107 0.2 0.4 0.4 0.5 0.6
20 0.365 0.0642 0.25 0.3 0.35 0.4 0.45
50 0.33 0.0361 0.28 0.3 0.34 0.36 0.38
100 0.322 0.0242 0.28 0.31 0.32 0.34 0.36
200 0.323 0.0162 0.295 0.315 0.325 0.335 0.35
400 0.326 0.0115 0.305 0.32 0.328 0.333 0.343
566 0.326 0.00932 0.311 0.32 0.327 0.332 0.341
Statistika algoritmu sdp\algo{sdp} – Sage.
nn chyb δsdp(n)\overline{\delta_{\algo{sdp}}(n)} Sδsdp(n)S_{\delta_{\algo{sdp}}}(n) 5%5 \% 25%25 \% 50%50 \% 75%75 \% 95%95 \%
10 16 0.422 0.129 0.3 0.3 0.4 0.5 0.6
20 15 0.371 0.104 0.25 0.3 0.35 0.4 0.5
50 11 0.34 0.0783 0.28 0.3 0.34 0.36 0.4
100 10 0.328 0.0434 0.29 0.31 0.33 0.34 0.37
200 4 0.325 0.0291 0.295 0.315 0.325 0.335 0.345
400 2 0.325 0.0182 0.305 0.318 0.325 0.333 0.343
566 2 0.327 0.0189 0.309 0.322 0.327 0.332 0.341
800 0 0.328 0.00746 0.315 0.324 0.329 0.334 0.34
1131 0 0.329 0.00643 0.318 0.324 0.329 0.333 0.34
1600 0 0.33 0.00552 0.32 0.327 0.331 0.334 0.339
2263 0 0.331 0.00452 0.323 0.328 0.331 0.334 0.337
3200 0 0.33 0.00379 0.324 0.328 0.331 0.333 0.337
Statistika algoritmu sdp\algo{sdp} – SDPA-C.

Dolní odhad

Výstup z každého algoritmu nám dává horní odhad na optimum daného vstupu. Ovšem semidefinitní programování nám navíc dává i dolní odhad na optimum, protože víme, že optimum jednoho z ekvivalentních vyjádření účelové funkce je vždy menši rovno optimu BPS. Použité řešiče semidefinitních programů nám navíc dají i horní odhad na optimum SDP (který se od nalezeného řešení může nepatrně lišit).

Horní a dolní odhad na 10001\,000 náhodných instancí vygenerovaný sage spd\algo{spd}.

Takto vygenerovaný dolní odhad nám bohužel nepřináší žádnou zajímavou informaci o chování na náhodném vstupu. Připomeňme, že Hančl a kol. [4] dokázali, že δ0.214\delta^- \ge 0.214. Průměrný dolní odhad na testovaných vstupech je pro dostatečně velký vstup dle obrázku menší než 0.2140.214, tedy nedostáváme ani žádnou novou hypotézu na dolní odhad.

Nicméně stále je zajímavé, že pro konkrétní instanci umíme určit nějaký netriviální dolní odhad.

Závěr

V této práci jsme představili algoritmus sdp{\bf sdp} na BPS založený na semidefinitním programování. Bohužel se nám nepodařilo dokázat žádný netriviální odhad na δsdp+\delta_{\algo{sdp}}^+. Nicméně dle naměřených dat můžeme soudit, že δsdp+\delta_{\algo{sdp}}^+ se pohybuje okolo 0.34. Místo toho jsme však dokázali, že pro libovolný vstup bude střední hodnota (přes náhodná čísla generovaná algoritmem nikoliv přes vstup) skóre řešení nejhůře 0.212n0.212 n od optima, tedy, že platí α:E[δsdp(α)]δ(α)+0.212n.\forall \alpha:\qquad\E[\delta_{\algo{sdp}}(\alpha)] \le \delta(\alpha) + 0.212 n.

Toto řešení jsme dále dokonce dvakrát implementovali s využitím různých implementací řešení semidefinitních programů, které jsme tímto i porovnali. Z naměřených dat jsme jednak odhadli střední hodnotu skóre algoritmu přes náhodný vstup. A také jsme si všimli, že dimenze řešení semidefinitního programování je poměrně malá, což jsme zformulovali jako hypotézu.

Stále však zůstává otevřená otázka, kolik přesně je δ+\delta^+ a δ\delta^- (a případně zda se rovnají) a jaké nejlepší δalg+\delta^+_{\alg} je možno dosáhnout polynomiálním algoritmem alg\alg.

Seznam použité literatury

[1] Bonsma, P.; Epping, Th. a Hochstättler, W. Complexity results on restricted instances of a paint shop problem for words. Discrete Applied Mathematics [online]. 2006, 154(9), 1335–1343. ISSN 0166-218X. Dostupné z: https://www.sciencedirect.com/science/article/pii/S0166218X0500377X

[2] Gupta, Anupam; Kale, Satyen; Nagarajan, Viswanath; Saket, Rishi a Schieber, Baruch. The Approximability of the Binary Paintshop Problem. In: Raghavendra, Prasad; Raskhodnikova, Sofya; Jansen, Klaus a Rolim, José D. P., ed. Approximation, Randomization, and Combinatorial Optimization. Algorithms and Techniques. Berlin, Heidelberg: Springer Berlin Heidelberg, 2013, s. 205–217. ISBN 978-3-642-40328-6.

[3] Andres, Stephan Dominique a Hochstättler, Winfried. Some heuristics for the binary paint shop problem and their expected number of colour changes. Journal of Discrete Algorithms [online]. 2011, 9(2), 203–211. ISSN 1570-8667. Dostupné z: https://www.sciencedirect.com/science/article/pii/S1570866710000559

[4] Hančl, J.; Kabela, A.; Opler, M.; Sosnovec, J.; Šámal, R. a Valtr, P. Improved Bounds for the Binary Paint Shop Problem. In: Wu, Weili a Tong, Guangmo, ed. Computing and Combinatorics. Cham: Springer Nature Switzerland, 2024, s. 210–221. ISBN 978-3-031-49193-1.

[5] Epping, Th.; Hochstättler, W. a Oertel, P. Complexity results on a paint shop problem. Discrete Applied Mathematics [online]. 2004, 136(2), 217–226. ISSN 0166-218X. Dostupné z: https://www.sciencedirect.com/science/article/pii/S0166218X03004426

[6] Alon, Noga. Splitting necklaces. Advances in Mathematics [online]. 1987, 63(3), 247–253. ISSN 0001-8708. Dostupné z: https://www.sciencedirect.com/science/article/pii/0001870887900557

[7] Gärtner, Bernd a Matoušek, Jiří. Approximation algorithms and semidefinite programming. B.m.: Springer Science & Business Media, 2012.

[8] Sun, Kevin. Lecture notes for Graph Algorithms, lecture 22 [online]. 2019 [vid. 2024-04-20]. Dostupné z: https://people.csail.mit.edu/ronitt/COURSE/S20/NOTES/lec6-scribe.pdf

[9] Dimitrakakis, Alexander. Lecture notes for Randomness and Computation, lecture 6 [online]. 2020 [vid. 2024-04-20]. Dostupné z: https://people.csail.mit.edu/ronitt/COURSE/S20/NOTES/lec6-scribe.pdf

[10] SDPA Project. SDPA Official Page [online]. 1995–2024 [vid. 2024-03-30]. Dostupné z: https://sdpa.sourceforge.net/

[11] ISO/IEC. Working Draft, Standard for Programming Language C++ [online]. 2014 [vid. 2024-04-20]. Dostupné z: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf

[12] Autoři SageMath. SageMath Official Page [online]. [vid. 2024-03-31]. Dostupné z: https://www.sagemath.org/index.html

[13] The Sage Development Team. Sage – Semidefinite Programming [online]. 2005-2024 [vid. 2024-03-31]. Dostupné z: https://doc.sagemath.org/html/en/reference/numerical/sage/numerical/sdp.html

Seznam obrázků