L5.4 Kapitola K5 — Rozvrhování (Slot 5) · [MUST]

McNaughton (P |pmtn| Cmax)

Jedna nová věc Wrap-around plnění na $R$ strojů s preempcí: spočti $C_{max}^* = \max\{\max_i p_i, \frac{1}{R}\sum_i p_i\}$, nalévej úlohy sekvenčně do „polic“ délky $C_{max}^*$ a při přetečení rozřízni úlohu na další stroj — optimum v $\mathcal{O}(n)$.

Z [L5.1] Grahamovy notace víš, co znamená $P \,|\, \mathrm{pmtn} \,|\, C_{max}$: $R$ identických paralelních procesorů, nezávislé preemptivní úlohy (prázdná $\beta$ jinak = bez precedencí, $r_j = 0$), minimalizuj makespan. A z pmtn-demos v [L5.1] už tušíš, že preempce umí stlačit $C_{max}$ pod nepreemptivní optimum. Dnes ten princip proměníme v kompletní algoritmus — McNaughtonův — který je u zkoušky stavebním kamenem: sám o sobě je cvičná klasika a o pár lekcí dál ho bude volat Muntz & Coffman [L5.10] jako podprogram („Use McNaughton to re-schedule parts with more tasks on less res.“).

Ostrov „easy“ v NP-hard moři (slide 38)

Bez preempce je rozvrhování na paralelních strojích těžké hned od dvou procesorů: rozhodnout, jestli jde $n$ úloh rozdělit na dva stroje s makespanem $\le \frac{1}{2}\sum p_i$, je přesně 2-Partition — tu jsi modeloval v [L1.1] T01 (2-Partition, vč. vztahu k P2||Cmax).

Zkus sám: proč celá ta 2-Partition obtížnost zmizí, jakmile povolíme preempci?

Těžké na 2-Partition je, že bankovky (úlohy) jsou nedělitelné — hledáš podmnožinu s přesným součtem. S preempcí smíš úlohu rozříznout: naskládej úlohy za sebe do jednoho pásu délky $\sum p_i$ a pás rozstřihni přesně v polovině — každá půlka na jeden stroj. „Kombinatorické hledání podmnožiny“ se změnilo na triviální stříhání pásu. Jediný háček: rozstřižená úloha nesmí běžet na obou strojích současně — a právě tenhle háček řeší McNaughtonova konstrukce níže.

Slide 38 (EN 1:1) — Scheduling on Parallel Identical Resources, Minimizing $C_{max}$

Mapu si zapamatuj: preempce sama o sobě dělá z $C_{max}$ na identických strojích snadný problém (dnešní lekce); preempce + časová okna $r_j, \tilde{d}_j$ = toky [L5.0]; jakmile ale přibudou precedence, je to zase NP-hard a McNaughton přežívá jen jako podprogram aproximačního Muntze&Coffmana [L5.10]. Nepreemptivní $P\,||\,C_{max}$ (bez precedencí) řeší DP Rothkopf [L5.11] (pseudopolynomiálně) a aproximačně LPT [L5.12]; list scheduling (LS) je naproti tomu aproximace pro precedenční variantu $P\,|\,\mathrm{prec}\,|\,C_{max}$.

Jak rychle to vůbec může být hotovo?

Než začneš rozvrhovat, spočti si, pod co se žádný — ani sebechytřejší — preemptivní rozvrh nedostane.

Zkus sám: najdi dvě nezávislé dolní meze na $C_{max}$ libovolného rozvrhu $n$ úloh na $R$ strojích (i preemptivního).

① Práce: celkem je $\sum_i p_i$ jednotek práce a $R$ strojů jich za čas $C$ odvede nejvýš $R \cdot C$ (a to jen pokud ani okamžik nezahálí). Tedy $C_{max} \ge \frac{1}{R}\sum_i p_i$.

② Sekvenčnost: úloha smí být rozřezaná na kusy a kusy smí běžet na různých strojích — ale nikdy dva kusy téže úlohy současně (úloha neumí běžet paralelně sama se sebou). Nejdelší úloha tedy potřebuje $\max_i p_i$ času čistě za sebou: $C_{max} \ge \max_i p_i$.

Dohromady: $C_{max} \ge \max\{\max_i p_i, \frac{1}{R}\sum_i p_i\}$. Pointa lekce: tahle dolní mez je dosažitelná.

Slide 40 (EN 1:1) — interpretace $C_{max}^*$

“The term $C_{\max}^* = \max\left\{\max_{i=1\ldots n}\{p_i\},\ \frac{1}{R} \sum_{1}^{n} p_i\right\}$ should be interpreted as follows:

Algoritmus: nalévání s wrap-around (slide 39)

Představ si $R$ „polic“, každou dlouhou přesně $C_{max}^*$. McNaughton bere úlohy v libovolném pořadí a nalévá je na první polici zleva doprava. Když se úloha nevejde (přetekla by za $C_{max}^*$), rozřízne ji: kus do konce police nechá tam a zbytkem začne plnit další polici od času $0$ — to je ten wrap-around.

Slide 39 (EN 1:1) — McNaughton's Algorithm for $P \,|\, \mathrm{pmtn} \,|\, C_{\max}$

Input: $R$, number of parallel identical resources, $n$, number of preemptive tasks and computation times $(p_1, p_2, \ldots, p_n)$.
Output: $n$-element vectors $s^1, s^2, z^1, z^2$ where $s_i^1$ (resp. $s_i^2$) is start time of the first (resp. second) part of task $T_i$ and $z_i^1$ (resp. $z_i^2$) is the resource ID on which the first (resp. second) part of task $T_i$ will be executed.”

s_i^1 = s_i^2 = z_i^1 = z_i^2 := 0 for all i ∈ 1..n;
t := 0; v := 1; i := 1;
C*_max = max { max_{i=1..n} {p_i}, (1/R) · Σ_{1..n} p_i };
while i ≤ n do
    if t + p_i ≤ C*_max then
        s_i^1 := t; z_i^1 := v; t := t + p_i; i := i + 1;
    else
        s_i^2 := t; z_i^2 := v; p_i := p_i − (C*_max − t); t := 0; v := v + 1;
    end
end

“Time complexity is $\mathcal{O}(n)$.”

Čtení pseudokódu: $t$ je hladina zaplnění aktuální police $v$. Větev if = úloha se vejde celá. Větev else = přetečení: kus $[t, C_{max}^*]$ zůstane na stroji $v$ (uloží se jako druhá část $s_i^2, z_i^2$ — časově běží později), zbytek $p_i - (C_{max}^* - t)$ se vrátí do smyčky se stejným $i$ a přistane na stroji $v+1$ od času $0$ jako první část ($s_i^1 = 0$). Každá úloha projde větví else nejvýš jednou — proto nejvýš dvě části.

Zkus sám (klíčový argument korektnosti): rozříznutá úloha má kusy $[t, C_{max}^*]$ na stroji $v$ a $[0,\, p_i - (C_{max}^* - t)]$ na stroji $v+1$. Proč se nikdy nepřekrývají v čase?

Kus na novém stroji končí v čase $p_i - (C_{max}^* - t)$ a kus na starém začíná v čase $t$. Překryv by nastal, kdyby $p_i - (C_{max}^* - t) > t$, tj. po úpravě $p_i > C_{max}^*$ — to ale odporuje definici $C_{max}^* \ge \max_i p_i$. Přesně kvůli tomuhle je v $C_{max}^*$ složka $\max_i p_i$: zaručuje, že zalomený zbytek doběhne dřív, než první kus na předchozím stroji začne. (A složka $\frac{1}{R}\sum p_i$ zaručuje $\sum p_i \le R \cdot C_{max}^*$, takže se všechno do $R$ polic vejde a algoritmus nikdy nepotřebuje stroj $R+1$.)

Zkus sám: kolik nejvýš preempcí (řezů) rozvrh obsahuje?

Řez vzniká jen při přechodu na další stroj a přechodů je nejvýš $R - 1$ (ze stroje $1$ až na stroj $R$). Tedy nejvýš $R-1$ preempcí; každá úloha je rozdělena nejvýš na dvě části. To je u zkoušky pěkná kontrola: víc než $R-1$ řezů v tvém Ganttu = někde chyba.

Optimalita je teď zadarmo: výsledný rozvrh je přípustný (kusy se nepřekrývají, vše se vešlo) a končí v $C_{max}^*$, což je dolní mez každého rozvrhu — takže $C_{max}^*$ je optimum a McNaughton ho dosahuje. Žádné chytré pořadí úloh není potřeba.

Běh na instanci slidu 40 (Example 1)

Slide 40, Example 1: $p = (2, 3, 2, 3, 2)$, $R = 3$. Proklikej běh — v každém kroku sleduj hladinu $t$ a kde řežeme:

Nebezpečné polopravdy kolem McNaughtona
Key takeaways — L5.4
T01 McNaughton's Algorithm for P |pmtn| Cmax — Example 2 zdroj: slide 39 (Input/Output EN 1:1) + slide 40 Example 2; cvičná příprava na Muntz&Coffmana [L5.10]
Assignment (EN; instance = slide 40 Example 2, pokyny i–iii vlastní — přiznáno)

Input: $R$, number of parallel identical resources, $n$, number of preemptive tasks and computation times $(p_1, p_2, \ldots, p_n)$. Output: $n$-element vectors $s^1, s^2, z^1, z^2$ where $s_i^1$ (resp. $s_i^2$) is start time of the first (resp. second) part of task $T_i$ and $z_i^1$ (resp. $z_i^2$) is the resource ID on which the first (resp. second) part of task $T_i$ will be executed.”

“Example 2: $p = (10, 8, 4, 14, 1)$, $R = 3$.”

(i) Compute $C_{\max}^*$ (show both components).
(ii) Run McNaughton's algorithm and draw the resulting Gantt chart.
(iii) How many preemptions does the schedule contain, and which resources are idle (and when)?

a) Co je v zadání?

Pět preemptivních nezávislých úloh, tři identické stroje, minimalizuj makespan. Spočítat mez $C_{max}^*$, mechanicky provést nalévání s wrap-around a popsat výsledek (preempce, zahálení). Pozor: tady vyhrává složka $\max p_i$ — instance je schválně jiná než Example 1.

b) Co k tomu budeme potřebovat?

  • Tato lekce — vzorec $C_{max}^*$ a smyčka algoritmu (takeaways).
  • [L5.1] Grahamova notace — čtení $P \,|\, \mathrm{pmtn} \,|\, C_{max}$ a kreslení Ganttova diagramu.

c) Jak nad úlohou uvažovat?

Nejdřív obě složky meze: čemu se rovná $\max_i p_i$ a čemu $\frac{1}{R}\sum_i p_i$? Která vyhraje a co to říká o zahálení strojů ($R \cdot C_{max}^*$ vs. $\sum p_i$)? Pak jen disciplinovaně nalévej v pořadí $T_1, \ldots, T_5$ a u každého přetečení si zapiš obě části ($s^2, z^2$ = kus do konce police, $s^1, z^1$ = zbytek na dalším stroji od nuly) a ověř, že se nepřekrývají.

d) Úplné řešení (běh a Gantt vlastní provedení algoritmu — přiznáno; $C_{\max}^*$ dle slidu 40)

(i) $\max_i p_i = 14$ (úloha $T_4$); $\frac{1}{R}\sum_i p_i = \frac{10+8+4+14+1}{3} = \frac{37}{3} \approx 12{,}33$. Slide 40: “compute $C_{\max}^* = \max\{14, \frac{37}{3}\} = 14$.” Vyhrála sekvenčnost — a protože $R \cdot C_{max}^* = 42 > 37 = \sum p_i$, stroje budou dohromady $5$ jednotek času zahálet.

(ii) Běh smyčky ($t$ = hladina aktuální police, $C_{max}^* = 14$):

  • $T_1$ ($p=10$): $0 + 10 \le 14$ → celá na $P^1$, $[0,10]$; $t = 10$.
  • $T_2$ ($p=8$): $10 + 8 = 18 > 14$ → řez: druhá část $[10,14]$ na $P^1$ ($s_2^2 = 10$, $z_2^2 = 1$; 4 jednotky), zbytek $8-4 = 4$ → první část $[0,4]$ na $P^2$ ($s_2^1 = 0$, $z_2^1 = 2$). Kontrola překryvu: $4 \le 10$ ✓.
  • $T_3$ ($p=4$): $4 + 4 = 8 \le 14$ → celá na $P^2$, $[4,8]$; $t = 8$.
  • $T_4$ ($p=14$): $8 + 14 = 22 > 14$ → řez: druhá část $[8,14]$ na $P^2$ (6 jednotek), zbytek $14-6 = 8$ → první část $[0,8]$ na $P^3$. Kontrola: $8 \le 8$ ✓ (těsně — kusy na sebe přesně navazují).
  • $T_5$ ($p=1$): $8 + 1 = 9 \le 14$ → celá na $P^3$, $[8,9]$. Konec.

(iii) Preempce: $2$ (úlohy $T_2$ a $T_4$) $= R - 1$ — mez je tu těsná. Zahálí jen $P^3$ v intervalu $[9,14]$, tedy $5$ jednotek $= R \cdot C_{max}^* - \sum p_i = 42 - 37$ ✓. Rozvrh končí v $C_{max} = 14 = C_{max}^*$, a protože $T_4$ sama potřebuje $14$ sekvenčních jednotek, lépe to nejde — optimální.

T02 Kolik preempce ušetří — McNaughton vs. nepreemptivní optimum zdroj: VLASTNÍ drill (přiznáno) — navazuje na 2-Partition z [L1.1] a slide 38
Assignment (EN; vlastní — přiznáno)

Consider $n = 4$ tasks with processing times $p = (5, 5, 5, 3)$ on $R = 2$ parallel identical resources.

(i) Solve $P \,|\, \mathrm{pmtn} \,|\, C_{\max}$ by McNaughton's algorithm: compute $C_{\max}^*$, draw the Gantt chart and count the preemptions.
(ii) Now forbid preemption ($P2 \,||\, C_{\max}$). What is the optimal makespan? Compare with (i).
(iii) Explain on this instance why the non-preemptive problem is the hard one (which subset-sum question are you implicitly answering?).

a) Co je v zadání?

Stejná čtveřice úloh dvakrát: jednou s preempcí (mechanický McNaughton), jednou bez ní (malý případový rozbor). Cíl je uvidět rozdíl: preempce dosáhne dolní meze práce, nepreemptivní rozvrh ne — a důvod je přesně 2-Partition.

b) Co k tomu budeme potřebovat?

c) Jak nad úlohou uvažovat?

U (i) jen dosazuj. U (ii) si uvědom: nepreemptivní rozvrh na 2 strojích = rozdělení množiny $\{5,5,5,3\}$ na dvě podmnožiny; makespan = větší ze součtů. Jaké součty podmnožin vůbec existují? Jde trefit $9 = \frac{18}{2}$?

d) Úplné řešení (vlastní — přiznáno)

(i) $C_{max}^* = \max\{5, \frac{5+5+5+3}{2}\} = \max\{5, 9\} = 9$. Nalévání: $T_1$ → $P^1\,[0,5]$; $T_2$: $5+5 = 10 > 9$ → druhá část $[5,9]$ na $P^1$ (4 jednotky), zbytek $1$ → první část $[0,1]$ na $P^2$ (kontrola: $1 \le 5$ ✓); $T_3$ → $P^2\,[1,6]$; $T_4$: $6+3 = 9 \le 9$ → $P^2\,[6,9]$. Jedna preempce ($T_2$) $= R-1$; nikdo nezahálí ($2 \cdot 9 = 18 = \sum p_i$); $C_{max} = 9$.

(ii) Bez preempce rozděluješ celé úlohy. Dosažitelné součty podmnožin $\{5,5,5,3\}$ jsou $0, 3, 5, 8, 10, 13, 15, 18$ — součet $9$ neexistuje. Nejvyrovnanější dělení je $\{5,3\} \,|\, \{5,5\}$ s náklady $8\,|\,10$, takže nepreemptivní optimum je $C_{max} = \mathbf{10} > 9$. Preempce tu ušetří přesně tu jednotku, kterou nejde „rozměnit“.

(iii) Otázka „existuje nepreemptivní rozvrh s $C_{max} \le \frac{1}{2}\sum p_i = 9$?“ je doslova otázka „existuje podmnožina se součtem $9$?“ — tedy 2-Partition (slide 38: redukce na $P2\,||\,C_{max}$ s prahem $0{,}5 \cdot \sum p_i$). Proto je nepreemptivní verze NP-hard, zatímco s preempcí jsme v (i) odpověděli za $\mathcal{O}(n)$ stříháním pásu — žádnou podmnožinu hledat nemusíme.

← Předchozí L5.3 · Time-indexed ILP pro PS1|temp|Cmax [FOTO]