{{TOC float}}

{{Sources| Tohle je poněkud obšírnější výcuc ke státnicovým okruhům ze složitosti pro obory Státnice_-_Informatika_-_I3:_Matematická_lingvistika a Státnice_-_Informatika_-_I2:_Softwarové_systémy, pocházející ze zápisků z předmětu Složitost I -- User:Tuetschek 22:44, 16 Aug 2010 (CEST)

}}

Popis složitosti algoritmů

Definice (Velikost dat, krok algoritmu)

Velikost dat je obvykle počet bitů, potřebných k jejich zapsání, např. data D  ⁣ D\,\! jako pro čísla a1,…,an  ⁣ a_1,\dots,a_n\,\! je velikost dat ∣D∣=∑i=1n⌈log⁡ai⌉  ⁣ |D|=\sum_{i=1}^n \lceil \log a_i \rceil\,\!.

Krok algoritmu je jedna operace daného abstraktního stroje (např. Turingův stroj, stroj RAM), zjednodušeně jde o nějakou operaci, proveditelnou v konstantním čase (např. aritmetické operace, porovnání hodnot, přiřazení -- pro jednoduché číselné typy).

Definice (Časová složitost)

Časová složitost je funkce f:N→N  ⁣ f:\mathbb{N}\to\mathbb{N}\,\! taková, že f(∣D∣)  ⁣ f(|D|)\,\! udává počet kroků daného algoritmu, pokud je spuštěn na datech D  ⁣ D\,\!.

Definice (Asymptotická složitost)

Řekneme, že funkce f(n)  ⁣ f(n)\,\! je asymptoticky menší nebo rovna než g(n)  ⁣ g(n)\,\!, značíme f(n)  ⁣ f(n)\,\! je O(g(n))  ⁣ O(g(n))\,\!, právě tehdy, když

:∃c>0∃n0∀n>n0:0≤f(n)≤c⋅g(n)  ⁣\exists c>0 \exists n_0 \forall n>n_0: 0 \leq f(n) \leq c \cdot g(n)\,\!

Funkce f(n)  ⁣ f(n)\,\! je asymptoticky větší nebo rovna než g(n)  ⁣ g(n)\,\!, značíme f(n)  ⁣ f(n)\,\! je Ω(g(n))  ⁣ \Omega(g(n))\,\!, právě tehdy, když

:∃c>0∃n0∀n>n0:0≤c⋅g(n)≤f(n)  ⁣\exists c>0 \exists n_0 \forall n>n_0: 0 \leq c \cdot g(n) \leq f(n)\,\!

Funkce f(n)  ⁣ f(n)\,\! je asymptoticky stejná jako g(n)  ⁣ g(n)\,\!, značíme f(n)  ⁣ f(n)\,\! je Θ(g(n))  ⁣ \Theta(g(n))\,\!, právě tehdy, když

:∃c1,c2>0∃n0∀n>n0:0≤c1⋅g(n)≤f(n)≤c2⋅g(n)  ⁣\exists c_1,c_2>0 \exists n_0 \forall n>n_0: 0 \leq c_1 \cdot g(n) \leq f(n) \leq c_2 \cdot g(n)\,\!

Funkce f(n)  ⁣ f(n)\,\! je asymptoticky ostře menší než g(n)  ⁣ g(n)\,\! (f(n)  ⁣ f(n)\,\! je o(g(n))  ⁣ o(g(n))\,\!, když

:∀c>0∃n0∀n>n0:0≤f(n)<c⋅g(n)  ⁣\forall c>0 \exists n_0 \forall n>n_0: 0\leq f(n) <c\cdot g(n)\,\!

Funkce f(n)  ⁣ f(n)\,\! je asymptoticky ostře větší než g(n)  ⁣ g(n)\,\! (f(n)  ⁣ f(n)\,\! je w(g(n))  ⁣ w(g(n))\,\!, když

:∀c>0∃n0∀n>n0:0≤c⋅g(n)<f(n)  ⁣\forall c>0 \exists n_0 \forall n>n_0: 0\leq c\cdot g(n) <f(n)\,\!

Poznámka

Asymptotická složitost zkoumá chování algoritmů na velkých datech, zařazuje je podle toho do kategorií. Zanedbává multiplikativní a aditivní konstanty.

Rozděl a panuj

*Pasáž knihy Jakuba Černého - Rozděl a panuj

Definice (Metoda rozděl a panuj)

Rozděl a panuj je metoda návrhu algoritmů (ne strukturované programování), která má 3 kroky:

  1. rozděl -- rozdělí úlohu na několik podúloh stejného typu, ale menší velikosti

  2. vyřeš -- vyřeší podúlohy a to buď přímo pro dostatečně malé, nebo rekurzivně pro větší

  3. sjednoť -- sjednotí řešení podúloh do řešení původní úlohy

Aplikace

{{TODO|Strassen}}

Analýza složitosti algoritmů rozděl a panuj

Poznámka (Vytvoření rekurentní rovnice)

Pro časovou složitost algoritmů typu rozděl a panuj zpravidla dostávám nějakou rekurentní rovnici.

  • T(n)  ⁣ T(n)\,\! budiž doba zpracování úlohy velikosti n  ⁣ n\,\!, za předpokladu, že T(n)=Θ(1)  ⁣ T(n)=\Theta(1)\,\! pro n≤n0  ⁣ n\leq n_0\,\!.

  • D(n)  ⁣ D(n)\,\! budiž doba na rozdělení úlohy velikosti n  ⁣ n\,\! na a  ⁣ a\,\! podúloh stejné velikosti nc  ⁣ \frac{n}{c}\,\!.

  • S(n)  ⁣ S(n)\,\! budiž doba na sjednocení řešení podúloh velikosti nc  ⁣ \frac{n}{c}\,\! na jednu úlohu velikosti n  ⁣ n\,\!. Dostávám rovnici

:T(n)={D(n)+aT(nc)+S(n)n>n0Θ(1)n≤n0  ⁣T(n)=\begin{cases} D(n)+aT(\frac{n}{c})+S(n) \quad\quad & n > n_0 \\ \Theta(1) & n \leq n_0 \end{cases}\,\!

Poznámka

Při řešení rekurentních rovnic:

  • Zanedbávám celočíselnost (n2  ⁣ \frac{n}{2}\,\! místo ⌈n2⌉  ⁣ \lceil\frac{n}{2}\rceil\,\! a ⌊n2⌋  ⁣ \lfloor\frac{n}{2}\rfloor\,\!)

  • Nehledím na konkrétní hodnoty aditivních a multiplikativních konstant, asymptotické notace používám i v zadání rekurentních rovnic, i v jejich řešení.

Věta (Substituční metoda)

  1. Uhodnu asymptoticky správné řešení

  2. Indukcí ověřím správnost (zvláště horní a dolní odhad)

Věta (Metoda "kuchařka" (Master Theorem))

Nechť a≥1,c>1,d≥0∈R  ⁣ a\geq 1, c>1,d\geq 0\in\mathbb{R}\,\! a nechť T:N→N  ⁣ T:\mathbb{N}\to\mathbb{N}\,\! je neklesající funkce taková, že ∀n  ⁣ \forall n\,\! tvaru ck  ⁣ c^k\,\! platí

:T(n)=aT(nc)+Θ(nd)  ⁣T(n)=aT(\frac{n}{c}) + \Theta(n^d)\,\!

Potom

  1. Je-li log⁡ca≠d  ⁣ \log_c a \neq d\,\!, pak T(n)  ⁣ T(n)\,\! je Θ(nmax⁡{log⁡ca,d})  ⁣ \Theta( n^{\max\{\log_c a, d\}} )\,\!

  2. Je-li log⁡ca=d  ⁣ \log_c a = d\,\!, pak T(n)  ⁣ T(n)\,\! je Θ(ndlog⁡cn)  ⁣ \Theta( n^d \log_c n )\,\!

Věta (Master Theorem, varianta 2)

Nechť 0<ai<1  ⁣ 0<a_i<1\,\!, kde i∈{1,…,k}  ⁣ i\in\{1,\dots,k\}\,\! a d≥0  ⁣ d\geq 0\,\! jsou reálná čísla a nechť T:N→N  ⁣ T:\mathbb{N}\to\mathbb{N}\,\! splňuje rekurenci

:T(n)=∑i=1kT(ai⋅n)+Θ(nd)  ⁣T(n)=\sum_{i=1}^k T(a_i\cdot n) + \Theta(n^d)\,\!

Nechť je číslo x  ⁣ x\,\! řešením rovnice ∑i=1kaix=1  ⁣ \sum_{i=1}^k a_i^x = 1\,\!. Potom

  1. Je-li x≠d  ⁣ x \neq d\,\! (tedy ∑i=1kaid≠1  ⁣ \sum_{i=1}^k a_i^d \neq 1\,\!), pak T(n)  ⁣ T(n)\,\! je Θ(nmax⁡{x,d})  ⁣ \Theta( n^{\max\{x, d\}} )\,\!

  2. Je-li x=d  ⁣ x = d\,\! (tedy ∑i=1kaid=1  ⁣ \sum_{i=1}^k a_i^d = 1\,\!), pak T(n)  ⁣ T(n)\,\! je Θ(ndlog⁡n)  ⁣ \Theta( n^d \log n )\,\!

Dynamické programování

{{Sources|Převzato z vypracovaných otázek V. Bedecse --

User:Tuetschek 10:34, 30 Aug 2010 (CEST)}} {{zkazky|

  • Dynamické programování (2012, Dvořák) - U dynamickýho programování jsem nějak sesmolil princip fungování a napsal jsem tam jeden konkrétní algoritmus (z grafiky - matchování vrcholů dvou mnohoúhelníků), na kterym jsem ukazoval, jak to funguje. To bylo OK, ale tahal ze mě pořád nějakej obecnej princip, jak to funguje. V rámci toho jsem ještě za pochodu vymýšlel algoritmus na batoh (to se mi vůbec nedělalo dobře, když vedle mě seděl a čekal na výsledek). Na konec jsme se teda asi dobrali toho, co chtěl slyšet - že se řešení konstruuje z menších podúloh stylem zdola nahoru (narozdíl od rozděl&panuj, kde to je v zásadě shora dolů).

}} Dynamické programování je metoda řešení problemů, které v sobě obsahují

překrývající se subproblémy (subproblémy jsou závislé narozdíl od Rozděl a panuj).

Příklad

Typickým příkladem je výpočet fibonaciho čísla. Fib. posloupnost je definována

jako: :f(0)=1,f(1)=1f(0) = 1, f(1) = 1

:f(n+2)=f(n+1)+f(n)f(n+2) = f(n+1) + f(n)

Výpočet třeba 4. čísla by pak byl f(4)=f(3)+f(2)=f(2)+f(1)+f(1)+f(0)=f(1)+f(0)+f(1)+f(1)+f(0)=5f(4) = f(3) + f(2) = f(2) + f(1) + f(1) + f(0) = f(1) + f(0) + f(1) +f(1) +f(0) = 5. Vidíme, že jsme f(2)f(2) počítali dvakrát, f(1)f(1) třikrát a f(0)f(0) dvakrát. Ve větším měřítku toto zbytečně počítání vede k exponenciální složitosti algoritmu. Lepší cestou je počítat "od spodu", kdy pomoci f(0)f(0) a f(1)f(1) spočteme f(2)f(2), pak s jeho pomoci f(3)f(3) nakonec f(4)f(4) s lineární složitosti.

V dynamickém programování se například vytvoří mapa Fibonacciho čísel a jejich hodnot. Před tím, než začnu počítat hodnotu nějakého Fibonacciho čísla, se podívám do mapy.

Nutné podmínky

V dynamickém programování využíváme:

  1. Překrývání podproblému - problém lze rozdělit na podproblémy, jejichž řešení se využívá opakovaně.

  2. Optimální podstruktury - optimální řešení lze zkonstruovat z optimálních řešení podproblémů.

Postupy

Obvykle se používá jeden ze dvou přístupů k dynamickému programování:

  • Top-down - problém se rekurzivně dělí na podproblémy a po jejich vyřešení se zapamatují výsledky, které se použijí při případném opětovném řešení daného podproblému.

  • Bottom-up - nejdříve se spočítají všechny možné podproblémy (viz příklad s Fibonacciho posloupnosti), které se potom skládají do řešení větších problémů. Tento přístup je výhodnější z hlediska počtu volání funkci a místa na zásobníků, ale ne vždy musí být zřejmě, které všechny subproblémy je třeba předem spočítat.

Použití

Problém batohu -- máme věci různé váhy a batoh určité nosnosti. Které věci máme dát do batohu, abychom jej co nejlépe zaplnili (jednorozměrná varianta problému batohu)? Speciální případ je součet podmnožiny (SP). Algoritmus je popsán v sekci o NP-úplnosti.

Uzávorkování součinu matic (Matrix chain multiplication) tak, aby počet skalárních součinů byl co nejmenší. Dělá se pomocí 2 čtvercových matic (MM a KK) řádu rovného počtu násobených matic, kde pracujeme jen nad diagonálou. Hodnota na MijM_{ij} udává minimální počet skalárních součinů při nejlepším uzávorkování matic ii až jj, hodnota KijK_{ij} určuje matici, která rozděluje závorkování na dvě podmnožiny matic. Hodnotu MijM_{ij} lze zkonstruovat ze všech MikM_{ik} a MkjM_{kj} pro i<k<ji<k<j.

Hladové algoritmy

Motivace

Problém 1

Dán souvislý neorientovaný graf G=(V,E)  ⁣ G=(V,E)\,\! a funkce d:E→R+  ⁣ d:E\to\mathbb{R}^+\,\!, udávající délky hran. Najděte minimální kostru grafu G  ⁣ G\,\!, tj. kostru G′=(V,E′)  ⁣ G'=(V,E')\,\! tak, že ∑e∈E′d(e)  ⁣ \sum_{e\in E'} d(e)\,\! je minimální.

Problém 2

Je dána množina S={1,…,n}  ⁣ S=\{1,\dots,n\}\,\! úkolů jednotkové délky. Ke každému úkolu je dána lhůta dokončení di∈N  ⁣ d_i\in\mathbb{N}\,\! a pokuta wi∈N  ⁣ w_i\in\mathbb{N}\,\!, kterou je úkol i  ⁣ i\,\! penalizován, není-li hotov do své lhůty. Najděte rozvrh (permutaci úkolů od času 0  ⁣ 0\,\! do času n  ⁣ n\,\!), který minimalizuje celkovou pokutu.

Problém 3

Je dána množina S={1,…,n}  ⁣ S=\{1,\dots,n\}\,\! úkolů. Ke každému úkolu je dán čas jeho zahájení si  ⁣ s_i\,\! ukončení fi  ⁣ f_i\,\!, si≤fi  ⁣ s_i\leq f_i\,\!. Úkoly i  ⁣ i\,\! a j  ⁣ j\,\! jsou kompatibilní, pokud se intervaly

ParseError: KaTeX parse error: Undefined control sequence: \[ at position 2: \̲[̲s_i,f_i)\,\!

a

ParseError: KaTeX parse error: Undefined control sequence: \[ at position 2: \̲[̲s_j,f_j)\,\!

nepřekrývají. Najděte co největší množinu (po dvou) kompatibilních úkolů.

Matroid

Definice (Matroid)

Matroid je uspořádaná dvojice M=(S,I)  ⁣ M=(S,I)\,\!, splňující:

  • S  ⁣ S\,\! je konečná neprázdná množina (*prvky matroidu * M  ⁣ M\,\!)

  • I  ⁣ I\,\! je neprázdná množina podmnožin S  ⁣ S\,\! (nezávislé podmnožiny), která má

  1. dědičnou vlastnost: B∈I∧A⊆B⇒A∈I  ⁣ B\in I \wedge A\subseteq B\quad \Rightarrow\quad A\in I\,\!,

  2. výměnnou vlastnost: A,B∈I∧∣A∣<∣B∣⇒∃x∈B\A:A∪{x}∈I  ⁣ A,B\in I \wedge |A|<|B|\quad \Rightarrow\quad \exists x\in B\backslash A: A\cup\{x\}\in I\,\!.

Věta (O velikosti maximálních nezávislých podmnožin)

Všechny maximální (maximální vzhledem k inkluzi) nezávislé podmnožiny v matroidu mají stejnou velikost.

Důkaz

Z výměnné vlastnosti, nechť A,B∈I  ⁣ A, B\in I\,\! maximální, ∣A∣<∣B∣  ⁣ |A|<|B|\,\!, pak A∪{x}∈I,x∉A  ⁣ A\cup\{x\}\in I, x\notin A\,\!, což je spor.

Definice (Vážený matroid)

Matroid M=(S,I)  ⁣ M=(S,I)\,\! je vážený, pokud je dána funkce w:S→R+  ⁣ w:S\to\mathbb{R}^+\,\! a její rozšíření na podmnožiny množiny S  ⁣ S\,\! je definováno předpisem:

:A⊆S⇒w(A)=∑x∈Aw(x)  ⁣A\subseteq S \Rightarrow w(A)=\sum_{x\in A}w(x)\,\!

Problém 1 a 2 -- zobecněný

Pro daný vážený matroid nalezněte nezávislou podmnožinu s co největší vahou (optimální množinu). Protože váhy jsou kladné, vždy se bude jednat o maximální nez. množinu.

Problém 1 je spec. případ tohoto, protože můžeme uvažovat grafový matroid (nad hranami) -- MG=(S,I)  ⁣ M_G = (S, I)\,\!, kde S=E  ⁣ S = E\,\! a pro A⊆E  ⁣ A\subseteq E\,\! platí A∈I  ⁣ A\in I\,\!, pokud hrany z A  ⁣ A\,\! netvoří cyklus (tj. indukovaný podgraf tvoří les).

Dědičná vlastnost této struktury je zřejmá, výměnnost se dá dokázat následovně: mějme A,B⊆E,∣A∣<∣B∣  ⁣ A,B\subseteq E, |A|<|B|\,\!. Pak lesy z A,B  ⁣ A, B\,\! mají n−a>n−b  ⁣ n-a > n-b\,\! stromů (vč. izolovaných vrcholů). V B  ⁣ B\,\! musí být strom, který se dotýká ≥2  ⁣ \geq 2\,\! různých stromů z A  ⁣ A\,\!. Ten obsahuje hranu, která není v žádném stromě A  ⁣ A\,\! a netvoří cyklus a tak ji můžu k A  ⁣ A\,\! přidat.

Váhovou funkci převedu na hledání maxim: w(e)=c−d(e)  ⁣ w(e) = c - d(e)\,\!, kde c  ⁣ c\,\! je dost velká konstanta, aby všechny váhy byly kladné. Algoritmus pak najde max. množinu, kde hrany netvoří cyklus. Implicitně bude mít n−1  ⁣ n-1\,\! hran, takže půjde o kostru a její w  ⁣ w\,\! bude maximální, tedy původní váha minimální.

Pro problém 2 zavedeme pojem kanonického rozvrhu -- takového rozvrhu, kde jsou všechny včasné úkoly rozvrženy před všemi zpožděnými a uspořádány podle neklesající lhůty dokončení (tohle na celkové pokutě nic nezmění a máme bijekci mezi množinou včasných úkolů a kanonickými rozvrhy).

Optimální množinu pak lze hledat jen nad kanonickými rozvrhy -- nezávislou množinou úkolů nazvu takovou, pro kterou existuje kanonický rozvrh tak, že žádný úkol v ní obsažený není zpožděný. Potom hledání max. nezávislé množiny při ohodnocení pokutami je hledání nejmenší pokuty (odeberu co nejvíc z možné celkové pokuty).

Pak zbývá dokázat, že takto vytvořená struktura je matroid. Dědičná vlastnost je triviální -- vyhodím-li něco z nezávislé množiny, nechám v rozvrhu mezery a bude platit stále. Pro výměnnou vlastnost zavedu pomocnou funkci Nt(C)=∣{i∈C∣di≤t}∣  ⁣ N_t(C) = |\{i\in C| d_i\leq t\}|\,\!, udávající počet úkolů z množiny C  ⁣ C\,\! se lhůtou do času t  ⁣ t\,\!. Pak množina C  ⁣ C\,\! je nezávislá, právě když ∀t∈{1,…,n}:Nt(C)≤t  ⁣ \forall t\in\{1,\dots,n\}: N_t(C)\leq t\,\!.

Pak máme-li 2 nezávislé A  ⁣ A\,\!, B  ⁣ B\,\!, ∣B∣>∣A∣  ⁣ |B|>|A|\,\!, označíme k  ⁣ k\,\! největší okamžik takový, že Nk(B)≤Nk(A)  ⁣ N_k(B)\leq N_k(A)\,\!, tj. od k+1  ⁣ k+1\,\! dál platí Nt(A)<Nt(B)  ⁣ N_t(A) <N_t(B)\,\!. To skutečně nastane, protože ∣B∣=Nn(B)>Nn(A)=∣A∣  ⁣ |B| = N_n(B) > N_n(A) = |A|\,\!. Pak určitě v B  ⁣ B\,\! je ostře víc úkolů s di=k+1  ⁣ d_i = k+1\,\! než v A  ⁣ A\,\!, tj. ∃x∈B\A  ⁣ \exists x\in B\backslash A\,\! se lhůtou k+1  ⁣ k+1\,\!. A∪{x}  ⁣ A \cup \{x\}\,\! je nezávislá, protože Nt(A∪{x})=Nt(A)  ⁣ N_t(A\cup\{x\}) = N_t(A)\,\! pro t≤k  ⁣ t\leq k\,\! a Nt(A∪{x})≤Nt(B)  ⁣ N_t(A\cup\{x\}) \leq N_t(B)\,\! pro t≥k+1  ⁣ t\geq k+1\,\!.

Hladový algoritmus na váženém matroidu

Algoritmus (Greedy)

Mám zadaný matroid M=(S,I)  ⁣ M=(S,I)\,\!, kde S={x1,…,xn}  ⁣ S = \{x_1,\dots,x_n\}\,\! a w:S→R+  ⁣ w:S\to\mathbb{R}^+\,\!. Potom

  1. A:=∅  ⁣ A:=\emptyset\,\!, setřiď a přeznač S  ⁣ S\,\! sestupně podle vah

  2. pro každé xi  ⁣ x_i\,\! zkoušej: je-li A∪{xi}∈I  ⁣ A\cup\{x_i\}\in I\,\!, tak A:=A∪{xi}  ⁣ A:=A\cup\{x_i\}\,\!

  3. vrať A  ⁣ A\,\! jako maximální nezávislou množinu

Pokud přidám nějaké xi  ⁣ x_i\,\!, nikdy nezruším nezávislost množiny; s už přidanými prvky se nic nestane. Časová složitost je Θ(nlog⁡n)  ⁣ \Theta(n\log n)\,\! na setřídění podle vah, testování nezávislosti množiny závisí na typu matriodu (f(n)  ⁣ f(n)\,\!), takže celkem něco jako Θ(nlog⁡n+n⋅f(n))  ⁣ \Theta(n\log n + n\cdot f(n))\,\!.

Důkaz

  • Vyhození prvků, které samy o sobě nejsou nezávislé množiny, nic nezkazí (z dědičné vlastnosti).

  • První vybrané xi  ⁣ x_i\,\! je "legální" (nezablokuje mi cestu), protože mezi max. nez. množinami určitě existuje taková, která jím mohla vzniknout (z výměnné vlastnosti -- vezmeme první prvek, který je sám o sobě nez. mn. a s pomocí nějaké max. nez. množiny B  ⁣ B\,\! ho doplníme, vzniklé {xi}∪(B\{xj})  ⁣ \{x_i\}\cup (B\backslash \{ x_j\})\,\! musí být také maximální).

  • Nalezení optimální množiny obsahující pevné (první vybrané) xi  ⁣ x_i\,\! v M=(S,I)  ⁣ M=(S,I)\,\! je ekvivalentní nalezení optimální množiny v M′=(S′,I′)  ⁣ M' = (S', I')\,\!, kde S′={y∈S∣{xi,y}∈I}  ⁣ S' = \{ y \in S | \{ x_i,y\}\in I\}\,\! a I′={B⊂S\{xi}∣B∪{xi}∈I}  ⁣ I' = \{ B\subset S\backslash \{x_i\} | B\cup \{x_i\} \in I\}\,\! (je-li S′  ⁣ S'\,\! neprázdná, je to matroid, vlastnosti se přenesou z původního; pokud je S′  ⁣ S'\,\! prázdná, tak algoritmus končí) a tedy když vyberu xi  ⁣ x_i\,\!, nezatarasím si cestu k optimu -- stačí ukázat, že A∪{x}  ⁣ A\cup\{x\}\,\! je optimální v M  ⁣ M\,\! právě když A  ⁣ A\,\! je optimální v M′  ⁣ M'\,\!.

  • Takže když budu vybírat (indukcí opakovaně) xi  ⁣ x_i\,\! podle váhy, dojdu k optimální množině.

Algoritmus (Hladový algoritmus na problém 3)

Máme S={1,…,n}  ⁣ S=\{1,\dots,n\}\,\! množinu úkolů s časy startů si  ⁣ s_i\,\! a konců fi  ⁣ f_i\,\!. Provedeme:

  1. A:=∅  ⁣ A:=\emptyset\,\!, f0:=0,j:=0  ⁣ f_0:= 0, j:= 0\,\!

  2. setřiď úkoly podle fi  ⁣ f_i\,\! vzestupně a přeznač

  3. pro každé i  ⁣ i\,\! zkoušej: je-li si≥fj  ⁣ s_i \geq f_j\,\!, pak A:=A∪{i}  ⁣ A:=A\cup\{i\}\,\! a j:=i  ⁣ j:=i\,\!

  4. vrať A  ⁣ A\,\! jako max. množinu nekryjících se úkolů

Složitost je nlog⁡n  ⁣ n\log n\,\! na setřídění, zbytek už lineární. Sice to funguje, ale tahle struktura NENÍ matroid -- nesplňuje výměnnou vlastnost. Algoritmus má ale stejný důkaz jako předchozí na matroidech (legálnost hladového výběru -- existuje max. množina obsahující prvek 1  ⁣ 1\,\! -- a existenci optimální množiny -- převod na "menší" zadání).

{{Statnice I3}}