11SUBSET SUM and its NP-completeness

בשיעור מוכיחים ש-SUBSET SUM היא NP-complete באמצעות רדוקציה מ-VC הבונה מספרים ספרה-ספרה כך שלא נוצרות נשאות, ומבחינים בין ערך המספרים לבין אורך הייצוג שלהם — ההבחנה שמסבירה מדוע אלגוריתם התכנון הדינמי מסדר $O(n\cdot S)$ אינו אלגוריתם פולינומי.

confidence: high2 recording(s)5 summary pagessubset-sumnp-completenessreductionsvertex-covergraph-coloringtrivial-languages

Builds on: lesson 7, lesson 8, lesson 9, lesson 10

The handwritten summary pages

Open page 1 full size

סיבוכיות שיעור 11 SUBSET SUM.pdf

Page 1 of 5 of the handwritten summary

בקצרה

  • מוכיחים שהבעיה SUBSET-SUM\mathrm{SUBSET\text{-}SUM} — בהינתן מספרים טבעיים a1,…,ana_1,\dots,a_n ומספר יעד SS, האם קיימת תת-קבוצת אינדקסים שסכום איבריה בדיוק SS — היא NP-complete.
  • החלק הקל: שייכות ל-NP, באמצעות certificate שהוא קבוצת האינדקסים עצמה.
  • החלק המהותי: רדוקציה VC≤pSUBSET-SUM\mathrm{VC} \le_p \mathrm{SUBSET\text{-}SUM}, שבה כל קודקוד וכל קשת מקבלים מספר שנבנה ספרה-ספרה: עמודה אחת לכל קשת, ועוד עמודה מובילה שסופרת קודקודים.
  • לב ההוכחה הוא טיעון אי-נשאות: בכל עמודת קשת סכום הספרות של כל המספרים הוא לכל היותר 33, ולכן חיבור ארוך בבסיס 1010 אף פעם אינו נושא, וניתן להסיק מן הסכום מסקנה נפרדת על כל עמודה בנפרד. בלי הטיעון הזה כל ההוכחה קורסת.
  • בנוסף מוכיחים בשיעור שתי תוצאות "מסביב": כל שפה ב-P ניתנת לרדוקציה לכל שפה לא-טריוויאלית (ולכן ≤p\le_p הוא כלי גס מדי מכדי להבחין בין בעיות בתוך P), ו-4COL\mathrm{4COL} היא NP-complete באמצעות רדוקציה מ-3COL\mathrm{3COL}.
  • מבחינים בין ערך המספרים לבין אורך הייצוג שלהם: אלגוריתם התכנון הדינמי מקורס האלגוריתמים רץ בזמן O(n⋅S)O(n\cdot S), וזה אינו זמן פולינומי בגודל הקלט. זו הסיבה ש-SUBSET-SUM\mathrm{SUBSET\text{-}SUM} היא NP-hard "חלשה" בלבד.
  • מי שקורא רק את הסעיף הזה צריך לדעת: הרדוקציה עצמה קצרה, אבל היא נשענת על שתי נקודות עדינות (אי-נשאות, ו"בדיוק KK" מול "לכל היותר KK") שנבחנות בדיוק בגללן.

רקע ותלויות

השיעור מניח את הדברים הבאים.

מחלקות ו-verifiers (שיעורים 7–8). PP היא מחלקת השפות הניתנות להכרעה בזמן פולינומי במכונת טיורינג דטרמיניסטית; NP\mathrm{NP} היא מחלקת השפות שעבורן קיים verifier פולינומי, כלומר קיימים פולינום pp ומכונה VV הרצה בזמן פולינומי כך ש-x∈Lx\in L אם ורק אם קיים cc באורך ∣c∣≤p(∣x∣)|c|\le p(|x|) שעבורו V(x,c)V(x,c) מקבלת. באופן שקול, NP\mathrm{NP} היא מחלקת השפות הנכרעות בזמן פולינומי במכונה אי-דטרמיניסטית.

רדוקציות (שיעורים 8–9). A≤pBA \le_p B פירושו: קיימת פונקציה ff הניתנת לחישוב בזמן פולינומי כך שלכל xx מתקיים x∈A  ⟺  f(x)∈Bx\in A \iff f(x)\in B. שימו לב לכיוון: A≤pBA \le_p B אומר ש-BB היא הבעיה הקשה יותר — אפשר לפתור את AA אם יודעים לפתור את BB. בהקלטה, כמו בכל דיבור חופשי, הכיוון מתהפך לעיתים קרובות; תמיד תרגמו חזרה לניסוח הפורמלי. שפה BB היא NP-hard אם לכל A∈NPA\in \mathrm{NP} מתקיים A≤pBA \le_p B, והיא NP-complete אם בנוסף B∈NPB\in \mathrm{NP}. הכלי המרכזי: אם CC היא NP-hard ו-C≤pBC \le_p B, אז גם BB היא NP-hard, מפני שהיחס ≤p\le_p טרנזיטיבי.

התוצאות שנשתמש בהן בפועל. משפט קוק–לוין (שיעור 9) נותן לנו את SAT\mathrm{SAT} כבעיה ה-NP-complete הראשונה, ומשיעור 10 יש בידינו ש-3SAT\mathrm{3SAT}, 3COL\mathrm{3COL} ו-VC\mathrm{VC} הן NP-complete. בשיעור הזה נשתמש ישירות רק בשתי עובדות: 3COL\mathrm{3COL} היא NP-hard, ו-VC\mathrm{VC} היא NP-hard.

נזכיר במלואן את שתי ההגדרות מהשיעור הקודם, כדי שלא תצטרכו לקפוץ:

  • VC\mathrm{VC} (Vertex Cover): הקלט הוא זוג (G,K)(G,K) כאשר G=(V,E)G=(V,E) גרף לא מכוון ו-K∈NK\in\mathbb{N}. כיסוי בקודקודים הוא קבוצה U⊆VU\subseteq V כך שלכל קשת e∈Ee\in E יש לפחות קצה אחד ב-UU (בהקלטה [00:53:37] סטודנט הציע "בדיוק אחד" והמרצה תיקן במפורש ל"לפחות אחד"; שימו לב שלפי זה VV עצמה היא תמיד כיסוי). מתקיים (G,K)∈VC(G,K)\in \mathrm{VC} אם ורק אם קיים כיסוי בקודקודים UU עם ∣U∣≤K|U|\le K.
  • kCOL\mathrm{kCOL}: הקלט הוא גרף G=(V,E)G=(V,E), והשאלה היא האם קיימת פונקציה f:V→{1,…,k}f:V\to\{1,\dots,k\} כך שאף קשת אינה מונוכרומטית, כלומר לכל xy∈Exy\in E מתקיים f(x)≠f(y)f(x)\ne f(y). kk הוא חלק משם הבעיה, לא מהקלט. הפונקציה אינה חייבת להיות על: מותר שצבע לא ינוצל כלל ([00:15:50]).

הגדרות

הגדרה 1: שפה טריוויאלית

תהי Σ\Sigma אלפבית. שפה B⊆Σ∗B\subseteq \Sigma^* נקראת טריוויאלית אם B=∅B=\emptyset או B=Σ∗B=\Sigma^*. אחרת היא אינה טריוויאלית, כלומר קיימים b1∈Bb_1\in B וגם b0∉Bb_0\notin B.

אינטואיציה. שפה טריוויאלית היא שפה שהתשובה עליה קבועה מראש ואינה תלויה בקלט: אפשר להכריע אותה בזמן קבוע ובמקום קבוע, בלי אפילו לקרוא את הקלט. לכן היא "קלה מדי" מכל בחינה, ובפרט אי אפשר לבצע אליה רדוקציה משפה כלשהי שאינה טריוויאלית — אין לאן לשלוח את שני סוגי הקלטים.

דוגמה. SAT\mathrm{SAT} אינה טריוויאלית: הנוסחה x∨¬xx\lor \lnot x ספיקה, והנוסחה x∧¬xx\land\lnot x אינה. אי-דוגמה. השפה {x:∣x∣≥0}=Σ∗\{x : |x|\ge 0\}=\Sigma^* טריוויאלית.

הגדרה 2: הבעיה SUBSET SUM

הקלט הוא סדרה של nn מספרים טבעיים a1,a2,…,ana_1,a_2,\dots,a_n ומספר טבעי נוסף SS, כולם נתונים בבסיס 1010. השאלה:

(a1,…,an,S)∈SUBSET-SUM  ⟺  ∃ I⊆{1,…,n}  s.t.  ∑i∈Iai=S.(a_1,\dots,a_n,S)\in \mathrm{SUBSET\text{-}SUM} \iff \exists\, I\subseteq\{1,\dots,n\}\ \ \text{s.t.}\ \ \sum_{i\in I} a_i = S .

אינטואיציה. מבקשים לבחור חלק מן המספרים כך שיפגעו בדיוק ביעד. שימו לב שמדובר בסדרה ולא בקבוצה: מותר שיופיעו חזרות, ולכן תת-הקבוצה היא של אינדקסים ולא של ערכים ([00:03:08] בהקלטה של שיעור 12, לגבי הבעיה האחות PARTITION — אותה הערה בדיוק).

דוגמה. (3,7,11,2  ;  S=13)∈SUBSET-SUM(3,7,11,2\;;\;S=13)\in \mathrm{SUBSET\text{-}SUM} שכן 11+2=1311+2=13. אי-דוגמה. (4,6,10  ;  S=13)∉SUBSET-SUM(4,6,10\;;\;S=13)\notin \mathrm{SUBSET\text{-}SUM}: כל המספרים זוגיים ולכן כל סכום חלקי זוגי.

הערת בסיס. בסיס 1010 נבחר לנוחות בלבד — הוא מאפשר לכתוב על הלוח "חיבור ארוך" ולראות את העמודות ([00:56:15]). כל בסיס ≥2\ge 2 נותן את אותה בעיה בדיוק, מפני שההמרה בין בסיס 22 לבסיס 1010 משנה את אורך הייצוג בגורם קבוע log⁡210\log_2 10. הבסיס האונרי הוא היוצא מן הכלל היחיד — ראו הגדרה 3.

הגדרה 3: ערך מספר מול אורך הייצוג שלו

עבור a∈Na\in\mathbb{N}, הערך הוא aa עצמו, ואילו אורך הייצוג בבסיס b≥2b\ge 2 הוא ⌈log⁡b(a+1)⌉\lceil \log_b (a+1)\rceil ספרות. הקשר ביניהם מעריכי: כדי לייצג את nn נחוצים Θ(log⁡n)\Theta(\log n) ביטים.

אינטואיציה. אלגוריתם נקרא פולינומי אם זמן ריצתו פולינומי באורך הקלט, לא בערכיו. כשהקלט הוא גרף גדול ומספר קטן, ההבחנה אינה מזיקה: בבעיות כמו CLIQUE\mathrm{CLIQUE} ו-IS\mathrm{IS} מקבלים (G,K)(G,K), ו-K≤∣V∣K\le |V|, כך שהגרף "בולע" את המספר ותרומתו לאורך הקלט זניחה ([00:48:18]). כשהקלט מורכב כולו ממספרים, כמו כאן, ההבחנה קריטית.

אי-דוגמה מאירה. אלגוריתם בדיקת ראשוניות הנאיבי עובר על כל המספרים עד n\sqrt{n} ובודק חלוקה. מספר האיטרציות n\sqrt n נראה פולינומי, אך אורך הקלט הוא Θ(log⁡n)\Theta(\log n), ולכן n=212log⁡n\sqrt n = 2^{\frac12\log n} הוא מעריכי באורך הקלט ([00:49:19]).

המקרה האונרי. אם מייצגים מספר בבסיס 11 (אונרי), אורך הייצוג שווה לערך. אז — ורק אז — אלגוריתם שזמנו פולינומי בערך הופך לאלגוריתם פולינומי ([00:50:25]).

משפטים והוכחות

משפט 1: כל שפה ב-P ניתנת לרדוקציה לכל שפה לא-טריוויאלית

תהיינה A,B⊆Σ∗A,B\subseteq\Sigma^* שפות. אם A∈PA\in P ו-BB אינה טריוויאלית, אז A≤pBA \le_p B.

תזכורת מחישוביות ([00:00:32]). ראינו שם את הטענה המקבילה: אם A∈RA\in R (כריעה) ו-BB אינה טריוויאלית, אז A≤mBA \le_m B. ההוכחה כאן היא אותה הוכחה בדיוק; ההבדל היחיד הוא שכאן מתחייבים גם על זמן הריצה של הרדוקציה.

הוכחה. מכיוון ש-A∈PA\in P, קיימת מכונה MAM_A המכריעה את AA בזמן פולינומי. מכיוון ש-BB אינה טריוויאלית, קיים b1∈Bb_1\in B וקיים b0∉Bb_0\notin B. שני המחרוזות האלה קבועות ונבחרות לפני שהמכונה רואה קלט כלשהו.

נגדיר מכונה MM באופן הבא. על קלט xx:

  1. הרץ את MAM_A על xx.
  2. אם MAM_A קיבלה את xx — החזר b1b_1. אחרת — החזר b0b_0.

נכונות. יהי x∈Σ∗x\in\Sigma^*.

  • נניח x∈Ax\in A. אז MAM_A מקבלת את xx, ולכן M(x)=b1∈BM(x)=b_1\in B.
  • נניח x∉Ax\notin A. אז MAM_A דוחה את xx, ולכן M(x)=b0∉BM(x)=b_0\notin B.

בשני המקרים x∈A  ⟺  M(x)∈Bx\in A \iff M(x)\in B, כנדרש.

זמן ריצה. שלב 1 דורש זמן פולינומי ב-∣x∣|x|, לפי הגדרת MAM_A. שלב 2 הוא כתיבת אחת משתי מחרוזות קבועות. כאן ישנה נקודה עדינה שסטודנטית העלתה בהקלטה ([00:09:43]): "אבל b0,b1b_0,b_1 עלולים להיות ארוכים מאוד!" — נכון, אבל אורכם אינו תלוי ב-xx. המכונה MM מחזיקה אותם "בבטן" כחלק מתיאורה, היא לא מקבלת אותם מבחוץ, והם נקבעו לפני שהוגדר xx. לכן, כפונקציה של ∣x∣|x|, שלב 2 לוקח זמן קבוע. סך הכול MM רצה בזמן פולינומי בגודל הקלט, ולכן A≤pBA\le_p B. ■\blacksquare

המשמעות ([00:02:37]–[00:04:12]). הטענה אומרת ש-PP היא המחלקה הקלה ביותר ביחס לרדוקציות זמן פולינומי: כל שפה לא-טריוויאלית "קשה לפחות כמו" כל שפה ב-PP. אבל אנחנו יודעים שגם בתוך PP יש דרגות קושי — למשל, ממשפט ההיררכיה לזמן (מן הפרק הראשון של הקורס) יש שפה הניתנת להכרעה בזמן n3n^3 ולא בזמן ליניארי. המסקנה: רדוקציות זמן פולינומי הן כלי גס מדי מכדי להבחין בין בעיות בתוך PP — מבחינתן כל הבעיות ב-PP הן אותו דבר. זהו הכלי המתאים להוכחת קושי, לא לדירוג עדין.

הערה: בהרצאה זה נאמר בקיצור; הפירוט כאן. השימוש הישיר בטענה (בשיעורי הבית, [00:12:25]) הוא להראות שמחלקה כמו DTime(n10)\mathrm{DTime}(n^{10}) אינה סגורה לרדוקציות זמן פולינומי. הנימוק: קחו B∈DTime(n10)B\in \mathrm{DTime}(n^{10}) לא-טריוויאלית כלשהי (למשל B={x:xB=\{x : x מתחיל ב-0}0\}, שהיא אפילו ליניארית). לפי משפט ההיררכיה לזמן קיימת A∈DTime(n11)∖DTime(n10)A\in \mathrm{DTime}(n^{11})\setminus \mathrm{DTime}(n^{10}), ובפרט A∈PA\in P. לפי משפט 1, A≤pBA\le_p B. אילו DTime(n10)\mathrm{DTime}(n^{10}) הייתה סגורה כלפי מטה ל-≤p\le_p, היה נובע A∈DTime(n10)A\in \mathrm{DTime}(n^{10}) — סתירה.

משפט 2: 4COL\mathrm{4COL} היא NP-complete

שייכות ל-NP. ה-certificate הוא הצביעה עצמה, g:V→{1,2,3,4}g:V\to\{1,2,3,4\}, שאורכה 2∣V∣2|V| ביטים — פולינומי בגודל הקלט. ה-verifier עובר על כל הקשתות ובודק לכל xy∈Exy\in E ש-g(x)≠g(y)g(x)\ne g(y); זמן O(∣E∣)O(|E|). הבדיקה מקבלת אם ורק אם קיימת צביעה חוקית, כנדרש.

NP-hardness: 3COL≤p4COL\mathrm{3COL} \le_p \mathrm{4COL}.

האלגוריתם. על קלט G=(V,E)G=(V,E):

  1. בנה גרף G^\hat G על ידי הוספת קודקוד חדש v^\hat v לגרף, וחיבורו בקשת לכל הקודקודים ב-VV.
  2. החזר את G^\hat G.

זמן ריצה. הבנייה מוסיפה קודקוד אחד ו-∣V∣|V| קשתות, ולכן היא לינארית בגודל הקלט; בפרט פולינומית. הפלט קטן מפי שניים מן הקלט ועוד קבוע, כך שגודלו פולינומי בגודל הקלט ([00:26:10]).

נכונות. יהי G=(V,E)G=(V,E) גרף. נסמן ב-G^=(V^,E^)\hat G=(\hat V,\hat E) את הגרף המוחזר על ידי האלגוריתם בהרצתו על GG, וב-v^\hat v את הקודקוד הנוסף.

כיוון ראשון: G∈3COL⇒G^∈4COLG\in \mathrm{3COL} \Rightarrow \hat G\in \mathrm{4COL}. קיימת צביעה חוקית f:V→{1,2,3}f:V\to\{1,2,3\}, כלומר אין ב-GG קשת מונוכרומטית. נגדיר g:V^→{1,2,3,4}g:\hat V\to\{1,2,3,4\} על ידי

g(v)={f(v)v∈V4otherwiseg(v)=\begin{cases} f(v) & v\in V\\ 4 & \text{otherwise}\end{cases}

תהא e=xy∈E^e=xy\in \hat E.

  • אם e∈Ee\in E, אז g(x)=f(x)g(x)=f(x) ו-g(y)=f(y)g(y)=f(y), ומכיוון ש-ff צביעה חוקית של GG נובע g(x)≠g(y)g(x)\ne g(y).
  • אחרת ee היא קשת חדשה, ולכן x=v^x=\hat v או y=v^y=\hat v. הקודקוד v^\hat v צבוע ב-44 והשני צבוע בצבע מתוך {1,2,3}\{1,2,3\}, ולכן שוב g(x)≠g(y)g(x)\ne g(y).

כך או כך g(x)≠g(y)g(x)\ne g(y), ולכן gg היא צביעה חוקית של G^\hat G ב-44 צבעים, כלומר G^∈4COL\hat G\in \mathrm{4COL}.

כיוון שני: G^∈4COL⇒G∈3COL\hat G\in \mathrm{4COL} \Rightarrow G\in \mathrm{3COL}. קיימת צביעה חוקית g:V^→{1,2,3,4}g:\hat V\to\{1,2,3,4\} של G^\hat G. ללא הגבלת הכלליות g(v^)=4g(\hat v)=4 — הצבעים סימטריים לחלוטין, ואם v^\hat v קיבל צבע אחר נחליף את שמות שני הצבעים. נגדיר f:V→{1,2,3,4}f:V\to\{1,2,3,4\} על ידי f(v)=g(v)f(v)=g(v) לכל v∈Vv\in V, ונראה שהטווח בפועל הוא {1,2,3}\{1,2,3\}: יהי x∈Vx\in V. מכיוון שחיברנו את v^\hat v לכל קודקודי VV, מתקיים xv^∈E^x\hat v\in \hat E, ולכן g(x)≠g(v^)=4g(x)\ne g(\hat v)=4. לכן לכל x∈Vx\in V מתקיים f(x)∈{1,2,3}f(x)\in\{1,2,3\}.

כעת תהא xy∈Exy\in E קשת. לא הסרנו קשתות, ולכן גם xy∈E^xy\in\hat E, ומכיוון ש-gg חוקית ב-G^\hat G נקבל f(x)=g(x)≠g(y)=f(y)f(x)=g(x)\ne g(y)=f(y). לכן ff היא צביעה חוקית של GG ב-33 צבעים, כלומר G∈3COLG\in \mathrm{3COL}. ■\blacksquare

למה הבנייה נראית כך — שני ניסיונות שנשברו.

ניסיון ראשון: הזהות ([00:16:53]–[00:18:30]). סטודנט הציע להחזיר את GG עצמו: הרי אם GG הוא 33-צביע אז בפרט הוא 44-צביע. הכיוון הראשון עובד — וזו בדיוק הסיבה לחשוד. הכיוון השני קורס: הקליק K4K_4 הוא 44-צביע (כל קודקוד בצבע משלו) ובוודאות אינו 33-צביע, שכן בקליק בגודל nn כל שני קודקודים מחוברים ולכן דרושים nn צבעים. אז K4∈4COLK_4\in \mathrm{4COL} אבל K4∉3COLK_4\notin \mathrm{3COL}, והזהות אינה רדוקציה.

ניסיון שני: להוסיף קודקוד בלי לחבר אותו ([00:31:29]–[00:34:41]). סטודנטית שאלה למה בכלל צריך את הקשתות החדשות. גם כאן הכיוון הראשון עובר בלי שינוי. הכיוון השני נשבר בדיוק בשורה אחת: הצעד שאומר "לכל x∈Vx\in V מתקיים g(x)≠4g(x)\ne 4" נשען כולו על קיום הקשת xv^x\hat v. בלי הקשתות אין שום מניעה שקודקוד ב-VV ייצבע ב-44, והצמצום של gg ל-VV לא יהיה צביעה בשלושה צבעים.

הערה: בהרצאה נאמר על כך רק ש"ההוכחה נשברת"; שימו לב שזה אינו מוכיח שהבנייה החלופית אינה רדוקציה — היא באמת אינה, אבל כדי לטעון זאת דרושה דוגמה נגדית, ולא רק כישלון של הוכחה מסוימת. דוגמה נגדית: G=K4G=K_4 ללא הקשתות החדשות נותן גרף שהוא K4K_4 בתוספת קודקוד מבודד; הגרף הזה 44-צביע, ואילו K4K_4 אינו 33-צביע.

ניסיון שלישי — ולמעשה הטעות החמורה מכולן ([00:21:39]–[00:23:45]). סטודנט ניסח את אותה בנייה נכונה במילים "נוסיף קודקוד חדש ונצבע אותו בצבע רביעי", והמרצה עצר את השיעור וכינה זאת "חטא כבד". שימו לב היכן בדיוק נמצאת הטעות: הבנייה זהה, אבל הניסוח מייחס לאלגוריתם גישה לצביעה. לאלגוריתם הרדוקציה אין ולא יכולה להיות גישה לפתרון. הוא מקבל גרף ומחזיר גרף; הוא אינו מחפש צביעה, אינו מקבל אחת ואינו יודע אם קיימת. הצביעות ff ו-gg מופיעות אך ורק בהוכחת הנכונות, ששם — ורק שם — מותר להניח "קיימת צביעה חוקית". זו הסיבה שבניסוח שלמעלה שלב 1 של האלגוריתם מדבר רק על קודקודים וקשתות, ואילו הפונקציה gg מוגדרת רק בתוך כיוון ההוכחה. המרצה השווה זאת לרדוקציה מ-HALT\mathrm{HALT}: אסור לכתוב "אם המכונה עוצרת אז נחזיר כך", מפני שאי אפשר לבדוק זאת. אותו עיקרון בדיוק חוזר במשפט 4 להלן — הרדוקציה מ-VC\mathrm{VC} ל-SUBSET-SUM\mathrm{SUBSET\text{-}SUM} בונה מספרים מהגרף ומ-KK בלבד, ואינה מחפשת כיסוי.

משפט 3: SUBSET-SUM∈NP\mathrm{SUBSET\text{-}SUM} \in \mathrm{NP}

הוכחה. ה-certificate הוא קבוצת האינדקסים I⊆{1,…,n}I\subseteq\{1,\dots,n\}, שאפשר לקודד ב-nn ביטים — פולינומי בגודל הקלט. ה-verifier מקבל (a1,…,an,S)(a_1,\dots,a_n,S) ואת II, מסכם ∑i∈Iai\sum_{i\in I}a_i ומשווה ל-SS. אם כל מספר תופס לכל היותר ℓ\ell ספרות, חיבור של עד nn מספרים כאלה דורש O(nℓ)O(n\ell) פעולות, וההשוואה O(ℓ)O(\ell) — כלומר זמן פולינומי באורך הקלט. ה-verifier מקבל עבור certificatecertificate כלשהו אם ורק אם קיימת II עם הסכום הנכון, כלומר אם ורק אם הקלט בשפה. באופן שקול: בוחרים את II באופן אי-דטרמיניסטי ומסכמים. ■\blacksquare

הערה: המרצה הדגיש שוב ושוב שלא אומרים "מגרילים" אלא "בוחרים באופן אי-דטרמיניסטי" — הגרלה שייכת לאלגוריתמים אקראיים, ואי-דטרמיניזם הוא דבר אחר לגמרי (ההערה נאמרה במפורש בשיעור העוקב, [00:03:40] בתמליל 18, לגבי אותו טיעון בדיוק).

משפט 4 (לב השיעור): VC≤pSUBSET-SUM\mathrm{VC} \le_p \mathrm{SUBSET\text{-}SUM}, ולכן SUBSET-SUM\mathrm{SUBSET\text{-}SUM} היא NP-complete

הרעיון. נבנה מספרים שאפשר לחשוב עליהם כשורות בטבלה: עמודה מיוחדת אחת בשם dd, ועוד עמודה אחת לכל קשת. שורת קודקוד "מדווחת" באילו קשתות הוא נוגע; שורת קשת היא וקטור יחידה. סכום היעד דורש בדיוק 22 בכל עמודת קשת ובדיוק KK בעמודה dd. הקסם הוא שהדרישה "בדיוק 22" ניתנת לסיפוק אם ורק אם לפחות אחד משני קצות הקשת נבחר.

האלגוריתם. על קלט G=(V,E)G=(V,E) ו-K∈NK\in\mathbb{N}, נסמן m=∣E∣m=|E| ו-E={e1,…,em}E=\{e_1,\dots,e_m\}.

  1. אם K>∣V∣K>|V|, החלף את KK ב-∣V∣|V|. (הצדקה למטה.)
  2. לכל קודקוד v∈Vv\in V נייצר מספר ava_v בן m+1m+1 ספרות, שבו הספרה השמאלית ביותר היא 11, ולכל 1≤j≤m1\le j\le m הספרה ה-(j+1)(j+1) משמאל היא 11 אם v∈ejv\in e_j ו-00 אחרת.
  3. לכל קשת e∈Ee\in E נייצר מספר aea_e בן m+1m+1 ספרות, שבו הספרה השמאלית ביותר היא 00, ולכל 1≤j≤m1\le j\le m הספרה ה-(j+1)(j+1) משמאל היא 11 אם ורק אם e=eje=e_j, ואחרת 00.
  4. נגדיר מספר יעד SS בן m+⌈log⁡10(K+1)⌉m+\lceil\log_{10}(K+1)\rceil ספרות: ⌈log⁡10(K+1)⌉\lceil\log_{10}(K+1)\rceil הספרות השמאליות ביותר מייצגות את KK, וכל יתר הספרות שוות 22.
  5. החזר את רשימת המספרים {av}v∈V∪{ae}e∈E\{a_v\}_{v\in V}\cup\{a_e\}_{e\in E} ואת SS.

באלגברה, במקום בציור, אלה בדיוק המספרים

av  =  10m  +  ∑j=1m[ v∈ej ]⋅10 m−j,aei  =  10 m−i,S  =  K⋅10m  +  ∑j=1m2⋅10 m−j.a_v \;=\; 10^{m} \;+\; \sum_{j=1}^{m} [\,v\in e_j\,]\cdot 10^{\,m-j}, \qquad a_{e_i} \;=\; 10^{\,m-i}, \qquad S \;=\; K\cdot 10^{m} \;+\; \sum_{j=1}^{m} 2\cdot 10^{\,m-j}.

על צעד 0 והביטוי "בדיוק KK". ההגדרה של VC\mathrm{VC} מדברת על כיסוי בגודל לכל היותר KK, ואילו הבנייה כופה בעמודה dd סכום של בדיוק KK. הפער אינו מזיק, משתי סיבות: (א) הוספת קודקודים לכיסוי משאירה אותו כיסוי, ולכן אם קיים כיסוי בגודל ≤K\le K ו-K≤∣V∣K\le|V|, אפשר להשלים אותו לכיסוי בגודל בדיוק KK; (ב) אם K>∣V∣K>|V| אז (G,K)∈VC(G,K)\in \mathrm{VC} תמיד (הקבוצה VV עצמה מכסה), ולכן ההחלפה K←∣V∣K\leftarrow|V| אינה משנה את התשובה, שכן (G,K)∈VC  ⟺  (G,min⁡(K,∣V∣))∈VC(G,K)\in \mathrm{VC} \iff (G,\min(K,|V|))\in \mathrm{VC}. צעד 0 מבוצע בזמן O(log⁡K+log⁡∣V∣)O(\log K+\log|V|).

הערה: בהרצאה ובסיכום עוברים ישר ל"קיים UU כיסוי עם ∣U∣=K|U|=K" ([01:13:18]) בלי לומר מדוע מותר; הפירוט כאן.

למה 4.1 (אי-נשאות) — הצעד שבלעדיו כלום לא עובד

תהי II תת-קבוצה כלשהי של המספרים שנבנו. נסמן U=I∩{av}v∈VU=I\cap\{a_v\}_{v\in V} (ונזהה אותה עם קבוצת קודקודים), ולכל 1≤j≤m1\le j\le m נסמן

cj  =  ∣{v∈U:v∈ej}∣  +  [ aej∈I ].c_j \;=\; \bigl|\{v\in U : v\in e_j\}\bigr| \;+\; [\,a_{e_j}\in I\,].

אזי:

  1. 0≤cj≤30\le c_j\le 3 לכל jj;
  2. ∑x∈Ix  =  ∣U∣⋅10m  +  ∑j=1mcj⋅10 m−j\displaystyle \sum_{x\in I} x \;=\; |U|\cdot 10^{m} \;+\; \sum_{j=1}^{m} c_j\cdot 10^{\,m-j}, וזהו בדיוק הייצוג העשרוני של הסכום בספרות c1,…,cmc_1,\dots,c_m — כלומר החיבור הארוך אינו נושא באף עמודת קשת;
  3. ∑j=1mcj⋅10 m−j<10m\displaystyle \sum_{j=1}^{m} c_j\cdot 10^{\,m-j} < 10^{m}.

הוכחה. (1) לקשת eje_j יש בדיוק שני קצוות. לכן לכל היותר שני מספרי קודקוד נושאים 11 בעמודה jj, ובנוסף בדיוק מספר קשת אחד — aeja_{e_j} — נושא שם 11. סך כל האחדות בעמודה jj על פני כל המספרים שנבנו הוא לכל היותר 2+1=32+1=3, ובפרט זה חסם על cjc_j.

(2) הזהות עצמה נובעת מפתיחת הסכום לפי ההצגה האלגברית שלמעלה וקיבוץ לפי חזקות 1010. הטענה שזהו הייצוג העשרוני נובעת מ-(1): כל מקדם cjc_j מקיים 0≤cj≤3≤90\le c_j\le 3\le 9, ולכן הוא ספרה חוקית בבסיס 1010 ואין העברה לעמודה שמשמאלה. זו כל המשמעות של "אין נשאות": בסיס 1010 נבחר גדול דיו מכדי שסכום עמודה כלשהי יגלוש. (למעשה כל בסיס ≥4\ge 4 היה מספיק; בסיס 1010 נבחר מטעמי נוחות כתיבה בלבד.)

(3) ∑j=1mcj10m−j≤∑j=1m3⋅10m−j=3⋅10m−19=10m−13<10m\displaystyle\sum_{j=1}^m c_j 10^{m-j}\le \sum_{j=1}^m 3\cdot 10^{m-j} = 3\cdot\frac{10^m-1}{9}=\frac{10^m-1}{3}<10^m. ■\blacksquare

למה זה קריטי. בלי (1) לא היינו רשאים "לקרוא ספרה-ספרה". אילו סכום עמודה כלשהי היה מגיע ל-1010 או יותר, הוא היה מעביר 11 שמאלה, וסכום כולל שנראה נכון היה יכול להתקבל מצירוף עמודות שגוי לגמרי — למשל 1010 אחדות בעמודה אחת היו "מתחזות" לספרה 11 בעמודה שכנה. הטיעון כולו נשען על כך שאין שום קשר בין העמודות, ולכן שוויון הסכומים גורר שוויון בכל ספרה בנפרד. זה מנוסח כמסקנה הבאה.

מסקנה 4.2 (קריטריון הספרות)

בסימוני למה 4.1, מתקיים ∑x∈Ix=S\sum_{x\in I} x = S אם ורק אם ∣U∣=K|U|=K וגם cj=2c_j=2 לכל 1≤j≤m1\le j\le m.

הוכחה. (⇐\Leftarrow) הצבה ישירה בזהות של למה 4.1(2).

(⇒\Rightarrow) נסמן L=∑jcj10m−jL=\sum_{j} c_j 10^{m-j} ו-L′=∑j2⋅10m−jL'=\sum_j 2\cdot 10^{m-j}. לפי למה 4.1(3) מתקיים 0≤L<10m0\le L<10^m, ובאותו חשבון גם 0≤L′<10m0\le L'<10^m. מן ההנחה, ∣U∣⋅10m+L  =  K⋅10m+L′⟹(∣U∣−K)⋅10m  =  L′−L.|U|\cdot 10^m + L \;=\; K\cdot 10^m + L' \quad\Longrightarrow\quad \bigl(|U|-K\bigr)\cdot 10^m \;=\; L'-L . אגף ימין מקיים ∣L′−L∣<10m|L'-L|<10^m, ואגף שמאל הוא כפולה שלמה של 10m10^m; לכן שני האגפים אפס. מכאן ∣U∣=K|U|=K וגם L=L′L=L'. שני הסכומים כתובים במקדמים שכולם בין 00 ל-99 (למה 4.1(1), ו-2≤92\le 9), ולכן מיחידות ההצגה בבסיס 1010 נובע cj=2c_j=2 לכל jj. ■\blacksquare

שימו לב היכן נכנס כאן הצורך לכתוב את KK כבלוק של ספרות ולא כספרה בודדת: מספר הקודקודים הנבחרים ∣U∣|U| עשוי להיות 1010 או יותר, ואז "הספרה" השמאלית איננה ספרה. הטיעון לעיל אינו מניח דבר על ∣U∣|U| — הוא רק מנצל את העובדה שכל מה שמתחת ל-10m10^m אינו מגיע ל-10m10^m.

הוכחת המשפט

זמן ריצה. האלגוריתם עובר לולאה אחת על הקודקודים ולולאה אחת על הקשתות, וכותב לכל אחד מהם מספר בן m+1m+1 ספרות; בנוסף הוא כותב את SS. סך גודל הפלט הוא O((∣V∣+m)⋅m+log⁡K)O\bigl((|V|+m)\cdot m + \log K\bigr) ספרות — פולינומי בגודל הקלט. בדיקת "האם v∈ejv\in e_j" היא O(1)O(1) בייצוג רשימות שכנויות, ולכן זמן החישוב פרופורציוני לגודל הפלט. המרצה ציין שהאלגוריתם רץ למעשה בזמן ליניארי בגודל הפלט ([01:11:00]).

הערה חשובה שנאמרה רק ברמז: הערך של כל מספר שנבנה הוא בסדר גודל 10m10^{m} — מעריכי בגודל הקלט! זו אינה בעיה, מפני שהרדוקציה נדרשת לרוץ בזמן פולינומי, וכתיבת מספר כזה עולה רק m+1m+1 ספרות. זו בדיוק ההבחנה של הגדרה 3, מן הצד השני שלה: הרדוקציה חוקית רק מפני שמותר לה לייצר מספרים בעלי ערך אדיר באורך ייצוג צנוע.

נכונות, כיוון ראשון: (G,K)∈VC⇒(G,K)\in \mathrm{VC} \Rightarrow הפלט ב-SUBSET-SUM\mathrm{SUBSET\text{-}SUM}.

נניח (G,K)∈VC(G,K)\in \mathrm{VC} (לאחר צעד 0 מתקיים K≤∣V∣K\le|V|). לפי הדיון על צעד 0 קיים כיסוי בקודקודים U⊆VU\subseteq V עם ∣U∣=K|U|=K בדיוק. נסמן I1={au∣u∈U}I_1=\{a_u \mid u\in U\}.

נסכום את המספרים ב-I1I_1. בעמודה dd כל אחד מהם תורם 11, ובחרנו בדיוק KK קודקודים, ולכן התרומה שם היא KK — בדיוק כמו ב-SS.

כעת יהי 1≤j≤m1\le j\le m. מכיוון ש-UU כיסוי, לפחות אחד מקצות eje_j שייך ל-UU; ומכיוון של-eje_j יש רק שני קצוות, לכל היותר שניים שייכים. לכן סכום הספרות בעמודה jj הוא 11 או 22.

נגדיר I2I_2 כך: לכל jj שעבורו סכום העמודה יצא 11, נוסיף ל-I2I_2 את המספר aeja_{e_j} המתאים לאותה קשת. המספר aeja_{e_j} מוסיף 11 בדיוק לעמודה jj ואפס לכל עמודה אחרת (כולל עמודת dd), ולכן הוא "מתקן" מ-11 ל-22 בלי לגעת בשום מקום אחר. שימו לב שהוא אינו יכול לתקן מ-00 ל-22 — וזה מדויק: המצב 00 לא ייתכן כאן דווקא מפני ש-UU כיסוי ([01:18:47]).

נקבל cj=2c_j=2 לכל jj ו-∣U∣=K|U|=K, ולפי מסקנה 4.2 סכום המספרים ב-I1∪I2I_1\cup I_2 הוא בדיוק SS.

נכונות, כיוון שני: הפלט ב-SUBSET-SUM\mathrm{SUBSET\text{-}SUM} ⇒(G,K)∈VC\Rightarrow (G,K)\in \mathrm{VC}.

הערה: כיוון זה אינו כתוב בסיכום, ובהרצאה הוא נאמר בעל פה בלבד ([01:29:33]) עם המשפט "אתם רוצים באמת להרגיש שאתם מבינים את זה — תכתבו את זה". הנה הכתיבה.

נניח שקיימת תת-קבוצה II של המספרים שנבנו שסכומה בדיוק SS. נסמן, כמו בלמה 4.1, U=I∩{av}v∈VU=I\cap\{a_v\}_{v\in V} (מזוהה עם קבוצת קודקודים). לפי מסקנה 4.2 מתקיים

∣U∣=K,cj=∣{v∈U:v∈ej}∣+[ aej∈I ]=2for every 1≤j≤m.|U|=K, \qquad c_j = \bigl|\{v\in U: v\in e_j\}\bigr| + [\,a_{e_j}\in I\,] = 2 \quad \text{for every } 1\le j\le m .

יהי 1≤j≤m1\le j\le m. המחובר [ aej∈I ][\,a_{e_j}\in I\,] הוא לכל היותר 11, שכן יש מספר אחד בלבד המתאים לקשת eje_j ולכן אפשר לבחור אותו לכל היותר פעם אחת. לכן

∣{v∈U:v∈ej}∣  =  2−[ aej∈I ]  ≥  1.\bigl|\{v\in U: v\in e_j\}\bigr| \;=\; 2 - [\,a_{e_j}\in I\,] \;\ge\; 1 .

כלומר לכל קשת eje_j יש לפחות קצה אחד ב-UU, ולכן UU הוא כיסוי בקודקודים של GG. גודלו ∣U∣=K≤K|U|=K\le K, ולכן (G,K)∈VC(G,K)\in \mathrm{VC}. ■\blacksquare

מסקנה. VC\mathrm{VC} היא NP-hard (שיעור 10), ולפי הטרנזיטיביות של ≤p\le_p נובע ש-SUBSET-SUM\mathrm{SUBSET\text{-}SUM} היא NP-hard. יחד עם משפט 3 מתקבל ש-SUBSET-SUM\mathrm{SUBSET\text{-}SUM} היא NP-complete.

משפט 5: אלגוריתם התכנון הדינמי אינו אלגוריתם פולינומי

בקורס האלגוריתמים ראינו אלגוריתם תכנון דינמי המכריע את SUBSET-SUM\mathrm{SUBSET\text{-}SUM} בזמן O(n⋅S)O(n\cdot S) (טבלה בגודל n×Sn\times S). האלגוריתם הזה אינו פולינומי בגודל הקלט.

הוכחה. נתבונן במשפחת קלטים שבה המספרים גדולים משמעותית מכמותם: לכל 1≤i≤n1\le i\le n מתקיים 2n≤ai≤22n2^{n}\le a_i\le 2^{2n}, וכן 2n≤S≤22n2^{n}\le S\le 2^{2n}.

גודל הקלט. יש n+1n+1 מספרים, וכל אחד מהם דורש לכל היותר 2n2n ביטים. לכן אורך הקלט הוא לכל היותר (n+1)⋅2n=O(n2)(n+1)\cdot 2n = O(n^2) ביטים.

זמן הריצה. n⋅S≥n⋅2nn\cdot S \ge n\cdot 2^{n}, שכן S≥2nS\ge 2^n.

ההשוואה. נסמן ב-NN את אורך הקלט; אז N=Θ(n2)N=\Theta(n^2), כלומר n=Θ(N)n=\Theta(\sqrt N), וזמן הריצה הוא לפחות 2Ω(N)2^{\Omega(\sqrt N)}. הפונקציה 2N2^{\sqrt N} גדולה אסימפטוטית מכל פולינום ב-NN, ולכן זמן הריצה אינו פולינומי בגודל הקלט. ■\blacksquare

מה זה בדיוק ([00:46:11], [00:47:13]). הביטוי 2N2^{\sqrt N} הוא לא בדיוק "מעריכי" — זה מעריכי בשורש של גודל הקלט — אבל הוא בוודאות אינו פולינומי. המרצה הקפיד על הניסוח הזה. אלגוריתם כזה נקרא pseudo-polynomial: פולינומי בערך המספרים ולא באורך ייצוגם.

המסקנה על הבעיה. מכאן ש-SUBSET-SUM\mathrm{SUBSET\text{-}SUM} היא NP-hard חלשה (weakly NP-hard): אם היו מייצגים את המספרים בבסיס אונרי, אורך הייצוג היה שווה לערך, אלגוריתם ה-O(n⋅S)O(n\cdot S) היה נעשה פולינומי, והבעיה הייתה נופלת ל-PP. שימו לב שזה אינו סותר את משפט 4: הרדוקציה שם מייצרת מספרים שערכם כ-10m10^{m}, וכתיבתם בבסיס אונרי הייתה דורשת מקום מעריכי — כלומר הרדוקציה אינה רדוקציה ל-SUBSET-SUM\mathrm{SUBSET\text{-}SUM} האונרית.

דוגמאות ותרגילים מהשיעור

דוגמה 1: מעקב מלא אחרי הרדוקציה VC≤pSUBSET-SUM\mathrm{VC} \le_p \mathrm{SUBSET\text{-}SUM}

זהו בדיוק המופע שהמרצה הריץ על הלוח והופיע בעמוד 5 בסיכום.

הגרף. V={1,2,3,4,5}V=\{1,2,3,4,5\}, ריבוע 1 ⁣− ⁣2 ⁣− ⁣3 ⁣− ⁣4 ⁣− ⁣11\!-\!2\!-\!3\!-\!4\!-\!1 ובתוכו קודקוד 55 המחובר ל-22 ול-44. הקשתות ממוספרות:

e1={1,2},e2={2,3},e3={3,4},e4={1,4},e5={2,5},e6={4,5},K=3.e_1=\{1,2\},\quad e_2=\{2,3\},\quad e_3=\{3,4\},\quad e_4=\{1,4\},\quad e_5=\{2,5\},\quad e_6=\{4,5\},\qquad K=3 .

כאן n=∣V∣=5n=|V|=5, m=∣E∣=6m=|E|=6, וכל מספר הוא בן 77 ספרות.

המספרים שהאלגוריתם מייצר.

dde1e_1e2e_2e3e_3e4e_4e5e_5e6e_6
a1a_11100100
a2a_21110010
a3a_31011000
a4a_41001101
a5a_51000011
ae1a_{e_1}0100000
ae2a_{e_2}0010000
ae3a_{e_3}0001000
ae4a_{e_4}0000100
ae5a_{e_5}0000010
ae6a_{e_6}0000001
SS3222222

בקריאה כמספרים: a3=1011000a_3 = 1011000, ae5=0000010a_{e_5}=0000010, S=3222222S=3222222. שורות הקשתות הן בדיוק מטריצת היחידה ([01:24:48]), ושורת קודקוד היא שורת מטריצת השכנויות קודקוד–קשת עם 11 מוביל.

כיוון ראשון (מכיסוי לסכום). ניקח את הכיסוי U={2,4,5}U=\{2,4,5\}, שגודלו ∣U∣=3=K|U|=3=K. ואכן הוא כיסוי: e1e_1 מכוסה על ידי 22, e2e_2 על ידי 22, e3e_3 על ידי 44, e4e_4 על ידי 44, e5e_5 על ידי 22 ו-55, ו-e6e_6 על ידי 44 ו-55.

I1={a2,a4,a5},a2+a4+a5  =  3 1 1 1 1 2 2.I_1=\{a_2,a_4,a_5\},\qquad a_2+a_4+a_5 \;=\; 3\,1\,1\,1\,1\,2\,2 .

בדיקה עמודה-עמודה: dd: 1+1+1=31+1+1=3. e1e_1: 1+0+0=11+0+0=1. e2e_2: 1+0+0=11+0+0=1. e3e_3: 0+1+0=10+1+0=1. e4e_4: 0+1+0=10+1+0=1. e5e_5: 1+0+1=21+0+1=2. e6e_6: 0+1+1=20+1+1=2. אף עמודה לא עברה את 22 — כמובטח בלמה 4.1.

העמודות e1,e2,e3,e4e_1,e_2,e_3,e_4 יצאו 11, ולכן

I2={ae1,ae2,ae3,ae4},I_2=\{a_{e_1},a_{e_2},a_{e_3},a_{e_4}\},

ובחיבור:

3111122+0100000+0010000+0001000+0000100  =  3222222  =  S.✓3111122+0100000+0010000+0001000+0000100 \;=\; 3222222 \;=\; S. \qquad\checkmark

כיוון שני (מסכום לכיסוי). נניח שמישהו נותן לנו את הקבוצה {a2,a4,a5,ae1,ae2,ae3,ae4}\{a_2,a_4,a_5,a_{e_1},a_{e_2},a_{e_3},a_{e_4}\} ואומר שסכומה SS. לפי מסקנה 4.2 אנחנו קוראים מן הסכום: הבלוק השמאלי הוא 33, ולכן נבחרו בדיוק 33 מספרי קודקוד — הקודקודים {2,4,5}\{2,4,5\}. בכל עמודת קשת הסכום הוא 22; למשל בעמודה e3e_3 תרם a4a_4 אחת ו-ae3a_{e_3} אחת. מכיוון ש-ae3a_{e_3} יכול לתרום לכל היותר 11, בהכרח לפחות אחד מקצות e3e_3 נמצא בקבוצה — וזה 44. חוזרים על אותו שיקול לכל אחת משש העמודות ומקבלים ש-{2,4,5}\{2,4,5\} מכסה את כל הקשתות, כלומר כיסוי בקודקודים בגודל 3≤K3\le K. ✓\checkmark

מה היה קורה בלי אי-נשאות? נניח לרגע שהיינו עובדים בבסיס 22 ובעמודה של e5e_5 היו שלושה מספרים עם 11. אז 1+1+1=31+1+1=3 היה נכתב כ-11211_2, כלומר נשא 11 לעמודה של e4e_4, וסכום סופי "נכון" היה יכול להתקבל מקבוצה שאינה כיסוי כלל. זו בדיוק הסיבה שאנחנו סופרים כמה אחדות יכולות להצטבר בעמודה (לכל היותר 33) ובוחרים בסיס גדול מזה.

דוגמה 2: הדוגמה עם 77 קשתות שנמחקה על הלוח

בעמוד 4 בסיכום מופיע אותו גרף עם 77 קשתות, ו-a3=10110001a_3=10110001, S=32222222S=32222222. בהקלטה ([01:22:44], [01:23:15]) המרצה אומר "מחקתי קשת אחת כדי שזה ייכנס לי ללוח" — כלומר עמוד 4 מתעד את המצב לפני המחיקה ועמוד 5 את המצב הסופי. שתי הגרסאות תקינות; הדוגמה המלאה והמאומתת היא זו שבדוגמה 1.

דוגמה 3: מעקב מלא אחרי הרדוקציה 3COL≤p4COL\mathrm{3COL} \le_p \mathrm{4COL}

מופע חיובי. ניקח G=C5G=C_5, המעגל באורך 55: V={1,2,3,4,5}V=\{1,2,3,4,5\} והקשתות 12,23,34,45,5112,23,34,45,51.

הבנייה. האלגוריתם מוסיף קודקוד v^\hat v ומחבר אותו לכל חמשת הקודקודים. הגרף המתקבל G^\hat G הוא הגלגל בעל 66 קודקודים ו-5+5=105+5=10 קשתות.

מ-3COL\mathrm{3COL} ל-4COL\mathrm{4COL}. מעגל אי-זוגי אינו 22-צביע אבל כן 33-צביע; ניקח

f(1)=1,  f(2)=2,  f(3)=1,  f(4)=2,  f(5)=3.f(1)=1,\; f(2)=2,\; f(3)=1,\; f(4)=2,\; f(5)=3 .

בדיקה: 12:1≠212: 1\ne2, 23:2≠123: 2\ne1, 34:1≠234: 1\ne2, 45:2≠345: 2\ne3, 51:3≠151: 3\ne1 — צביעה חוקית. לפי הבנייה שבמשפט 2 נגדיר gg שמסכימה עם ff על VV ומקצה g(v^)=4g(\hat v)=4. חמש הקשתות הישנות בסדר כי ff חוקית; חמש הקשתות החדשות בסדר כי v^\hat v לבדו נושא את הצבע 44. לכן G^∈4COL\hat G\in \mathrm{4COL}. ✓\checkmark

מ-4COL\mathrm{4COL} ל-3COL\mathrm{3COL}. נניח שקיבלנו את הצביעה החוקית

g(1)=2,  g(2)=3,  g(3)=2,  g(4)=3,  g(5)=4,  g(v^)=1.g(1)=2,\; g(2)=3,\; g(3)=2,\; g(4)=3,\; g(5)=4,\; g(\hat v)=1 .

כאן g(v^)≠4g(\hat v)\ne 4, ולכן נפעיל את שלב "ללא הגבלת הכלליות": נחליף בין שמות הצבעים 11 ו-44 ונקבל g′(v^)=4g'(\hat v)=4, g′(5)=1g'(5)=1, ושאר הערכים ללא שינוי. החלפת שמות צבעים שומרת על חוקיות, שכן היא פרמוטציה חח"ע של הטווח. כעת f=g′∣Vf=g'|_V נותנת

f(1)=2,  f(2)=3,  f(3)=2,  f(4)=3,  f(5)=1,f(1)=2,\; f(2)=3,\; f(3)=2,\; f(4)=3,\; f(5)=1 ,

וכל הערכים אכן ב-{1,2,3}\{1,2,3\} — בדיוק מפני שכל קודקוד ב-VV שכן של v^\hat v ולכן אסור לו לקבל 44. הצביעה חוקית על כל חמש הקשתות של C5C_5, ולכן G∈3COLG\in \mathrm{3COL}. ✓\checkmark

מופע שלילי. ניקח G=K4G=K_4. אז G^=K5\hat G=K_5. אכן K4∉3COLK_4\notin \mathrm{3COL} (בקליק בגודל nn דרושים nn צבעים) וגם K5∉4COLK_5\notin \mathrm{4COL} מאותו נימוק — הרדוקציה שולחת "לא" ל"לא", כנדרש. ✓\checkmark

אותו מופע שובר את הבנייה השגויה. אילו לא היינו מחברים את v^\hat v בקשתות, היינו מקבלים על הקלט K4K_4 את הגרף "K4K_4 ועוד קודקוד מבודד", שהוא 44-צביע. אז מופע ה"לא" K4K_4 היה נשלח למופע "כן" — דוגמה נגדית מפורשת לכך שהבנייה החלופית אינה רדוקציה.

תרגיל 1 (נפתר בכיתה): מדוע הזהות אינה רדוקציה מ-3COL\mathrm{3COL} ל-4COL\mathrm{4COL}?

פתרון. צריך למצוא גרף שהוא 44-צביע ואינו 33-צביע. הקליק K4K_4 הוא כזה: הוא 44-צביע כי אפשר לתת לכל קודקוד צבע משלו, והוא אינו 33-צביע כי בקליק כל שני קודקודים מחוברים ולכן דרושים לפחות 44 צבעים. לכן id(K4)=K4∈4COL\mathrm{id}(K_4)=K_4\in \mathrm{4COL} אך K4∉3COLK_4\notin \mathrm{3COL}, בסתירה לתנאי הרדוקציה.

תרגיל 2 (נפתר בכיתה): האם היה אפשר לעשות רדוקציה מ-IS\mathrm{IS} או מ-CLIQUE\mathrm{CLIQUE} במקום מ-VC\mathrm{VC}?

פתרון ([00:54:41]). כן. יש רדוקציה מיידית IS≤pVC\mathrm{IS} \le_p \mathrm{VC}: הקבוצה UU היא כיסוי בקודקודים אם ורק אם V∖UV\setminus U היא קבוצה בלתי תלויה, ולכן מספיק להעביר (G,K)↦(G,∣V∣−K)(G,K)\mapsto (G,|V|-K). אפשר לשלב אותה בחזית הרדוקציה שלנו ולקבל IS≤pSUBSET-SUM\mathrm{IS} \le_p \mathrm{SUBSET\text{-}SUM} ישירות. מ-CLIQUE\mathrm{CLIQUE} עוברים תחילה לגרף המשלים ואז ל-∣V∣−K|V|-K. המרצה הדגיש שהבחירה ב-VC\mathrm{VC} שרירותית לחלוטין ונובעת מכך שזו הרדוקציה הקלאסית בספרות ([00:55:43]) — לא מפני שהאחרות שגויות, אלא מפני שהן מוסיפות רעש להוכחה.

תרגיל 3 (שיעורי בית): DTime(n10)\mathrm{DTime}(n^{10}) אינה סגורה לרדוקציות זמן פולינומי

פתרון. ראו ההערה בסוף משפט 1: בוחרים B∈DTime(n10)B\in \mathrm{DTime}(n^{10}) לא-טריוויאלית, לוקחים ממשפט ההיררכיה A∈P∖DTime(n10)A\in P\setminus \mathrm{DTime}(n^{10}), ומקבלים ממשפט 1 ש-A≤pBA\le_p B בעוד A∉DTime(n10)A\notin \mathrm{DTime}(n^{10}).

תרגיל 4: מה גודל טבלת התכנון הדינמי?

פתרון ([01:05:32] בתמליל 18). סטודנט הציע לפתור בעיה קרובה בעזרת טבלה בגודל KK. שאלת הבדיקה שהמרצה החזיר: כמה ביטים דרושים כדי לתאר את KK? התשובה log⁡K\log K, ולכן טבלה בגודל KK היא מעריכית באורך הייצוג של KK. זו בדיוק הבדיקה שיש להריץ בכל פעם שמופיע בקלט מספר, והיא זהה בתוכנה למשפט 5.

הערות מהשיעור

כל התזמונים מתייחסים לתמליל QfE6eBttdJgQfE6eBttdJg אלא אם צוין אחרת.

  • [00:21:39]–[00:23:45] — הטעות שהמרצה כינה "חטא כבד". סטודנט הציע כרדוקציה: "נוסיף קודקוד חדש ונצבע אותו בצבע רביעי". הבנייה עצמה נכונה, אבל הניסוח שגוי מיסודו: לאלגוריתם הרדוקציה אין שום גישה לצביעה. הוא מקבל גרף ומחזיר גרף, הוא לא מחפש צביעה, לא מקבל אותה ולא מעניין אותו אם קיימת. הצביעה מופיעה רק בהוכחה שהאלגוריתם הוא רדוקציה. המרצה השווה זאת לרדוקציה מ-HALT\mathrm{HALT} שבה אסור לומר "אם המכונה עוצרת אז נחזיר כך" — אי אפשר לבדוק זאת. עקרון הברזל: רדוקציה אינה באה להכריע את הבעיה, אלא רק להעביר תכונה הלאה מבלי לדעת כלל אם היא מתקיימת. זו בדיוק הנקודה שסטודנטים מפילים עליה במבחן.
  • [00:16:53] — איך בודקים ניסיון רדוקציה. "אם הכיוון הראשון קל מדי — תחשדו." זו הוריסטיקה טובה: כאשר כיוון אחד יוצא בשורה, בדרך כלל השני נשבר.
  • [00:15:50]–[00:16:21] — הפונקציה בצביעה אינה חייבת להיות על. צביעה ב-33 צבעים היא גם צביעה ב-44 צבעים שבה הצבע הרביעי לא נוצל. ואפילו אם רוצים "בדיוק 44", אפשר לצבוע קודקוד אחד מחדש בצבע הרביעי בלי ליצור קשת מונוכרומטית (בגרף עם לפחות ארבעה קודקודים). ב-MAXCUT\mathrm{MAXCUT}, לעומת זאת, "לפחות" כן שינה — לא תמיד אפשר לעבור בין "בדיוק" ל"לכל היותר".
  • [00:09:43] — שאלת סטודנטית ששווה זהב. "אבל b1b_1 עלול להיות מחרוזת ארוכה מאוד, אז איך שלב 2 לוקח זמן קבוע?" התשובה: b0,b1b_0,b_1 נקבעו לפני שראינו את הקלט; הם חלק מתיאור המכונה, לא חלק מהקלט. זמן ריצה נמדד תמיד כפונקציה של גודל הקלט, ולכן כתיבתם היא O(1)O(1) ב-∣x∣|x|. עצה תחבירית שהמרצה נתן: כתבו את המשתנים בסדר הופעתם — b0,b1b_0,b_1 קודמים ל-xx, ולכן אינם יכולים לתלות בו.
  • [00:52:32] — קיצורים. המרצה סירב במפורש לקצר את SUBSET-SUM\mathrm{SUBSET\text{-}SUM} לראשי תיבות. שווה לאמץ בכתיבה שלכם: ראשי תיבות מקומיים הם מקור נפוץ לבלבול בבדיקה.
  • [01:19:56]–[01:21:36] — "אל תשאלו איך הייתם חושבים על זה". אחרי שהוצגה הרדוקציה, סטודנטית שאלה איך בכלל חושבים על בנייה כזאת. תשובת המרצה: זו אינה השאלה הנכונה בשלב הזה. השאלה הנכונה היא "האם הבנתי למה זה נכון". על הבנייה הזו ישבו אנשים חודשים; הציפייה מכם היא לדעת אותה, להבין למה היא עובדת ולעבוד איתה — לא להמציא אותה מאפס. לעומת זאת, על רדוקציה כמו 3COL≤p4COL\mathrm{3COL}\le_p \mathrm{4COL} כן מצפים מכם להגיע לבד ([01:21:03]).
  • [01:29:33] — הכיוון השני נשאר כתרגיל. המרצה הציג את הכיוון ⇐\Leftarrow בעל פה בלבד ואמר "אם אתם רוצים באמת להרגיש שאתם מבינים את זה — תכתבו את זה". הוא כתוב במלואו במשפט 4 לעיל.
  • [00:44:01] — המשפט שכדאי לזכור בעל פה. "כשעובדים עם מספרים, הערך של המספר והקידוד של המספר זה לא אותו דבר."
  • [00:38:29], [00:40:49] — היסטוריית האלגוריתמים לבעיה. ראיתם את הבעיה במבוא (פתרון רקורסיבי: לכל איבר מחליטים בפנים/בחוץ, עץ רקורסיה בגודל 2n2^n) ובאלגוריתמים (תכנון דינמי, טבלה בגודל n×Sn\times S). האלגוריתם הנאיבי ביותר הוא מעבר על כל 2n2^n תת-הקבוצות.

פערים בין הסיכום להקלטה

  • מקור: תמליל QfE6eBttdJgQfE6eBttdJg, [00:00:00]. הפער: הכתוביות אומרות "נניח כי AA ב-PP וכי BB טריוויאלית", בלי השלילה. ההכרעה: זו נפילת שלילה אופיינית לתמלול אוטומטי. הסיכום (עמוד 1) והתזכורת מחישוביות ב-[00:00:32] אומרים שניהם "BB אינה טריוויאלית", וזה גם המצב המתמטי הנכון — עבור BB טריוויאלית הטענה שקרית. תוקן בגוף הקובץ.
  • מקור: עמוד 5 בסיכום. הפער: הסיכום מוכיח רק את הכיוון (G,K)∈VC⇒(G,K)\in \mathrm{VC} \Rightarrow פלט ב-SUBSET-SUM\mathrm{SUBSET\text{-}SUM}; הכיוון ההפוך חסר לגמרי, ובהקלטה הוא נאמר בעל פה בלבד ([01:29:33]). ההכרעה: הכיוון השני נכתב כאן במלואו לפי הסקיצה שנאמרה, כולל הנימוק שמספר קשת יכול לתרום לכל היותר 11 ולכן בהכרח לפחות קצה אחד נבחר.
  • מקור: הסיכום וההקלטה כאחד. הפער: טיעון אי-הנשאות אינו מנוסח בשום מקום כטענה; שניהם רק מציינים שסכום עמודת קשת הוא בין 11 ל-22 בכיסוי מסוים. ההכרעה: נוסח כאן כלמה 4.1 עם הוכחה מלאה (חסם 33 על סכום עמודה, ולכן ספרה חוקית בבסיס 1010; כל בסיס ≥4\ge 4 מספיק), ומסקנה 4.2 שמצדיקה את הקריאה ספרה-ספרה.
  • מקור: הסיכום (עמוד 5) וההקלטה ([01:13:18]). הפער: שניהם עוברים מ-"(G,K)∈VC(G,K)\in \mathrm{VC}" ישירות ל-"קיים כיסוי UU עם ∣U∣=K|U|=K", בעוד ההגדרה של VC\mathrm{VC} היא "לכל היותר KK". ההכרעה: אין כאן שגיאה מהותית, אבל יש חוסר. נוסף צעד 0 לאלגוריתם (K←min⁡(K,∣V∣)K\leftarrow\min(K,|V|)) והצדקה שהשלמת כיסוי לגודל בדיוק KK אפשרית.
  • מקור: הסיכום (עמוד 4) וההקלטה ([01:07:50]). הפער: נכתב ש-SS הוא בן ∣E∣+log⁡10K|E|+\log_{10}K ספרות. ההכרעה: מספר הספרות המדויק הוא ∣E∣+⌈log⁡10(K+1)⌉|E|+\lceil\log_{10}(K+1)\rceil; זהו עיגול מקובל ולא שגיאה, אך נכתב כאן במדויק. נשמר הדגש של ההקלטה ([00:59:38]) שהבלוק השמאלי אינו ספרה בודדת.
  • מקור: עמוד 4 בסיכום מול עמוד 5. הפער: הדוגמה בעמוד 4 היא על גרף בעל 77 קשתות (a3=10110001a_3=10110001, S=32222222S=32222222) ואילו עמוד 5 מציג גרף בעל 66 קשתות. ההכרעה: אין כאן סתירה — בהקלטה ([01:22:44]) המרצה אומר שמחק קשת אחת כדי שהטבלה תיכנס ללוח. הדוגמה המפורטת בקובץ היא של עמוד 5, שנבדקה עמודה-עמודה.
  • מקור: עמוד 4 בסיכום. הפער: שורת הקלט של הבעיה כתובה "kk מספרים a1,…,ana_1,\dots,a_n", עם אי-התאמה בין kk ל-nn. ההכרעה: הקלט הוא nn מספרים; זו כנראה פליטת קולמוס, ובכל יתר הסיכום ובהקלטה ([00:39:09]) מופיע nn. תוקן.
  • מקור: ההקלטה בלבד. הפער: כל הדיון בהבחנה בין ערך לאורך ייצוג ([00:40:49]–[00:51:30]) — האלגוריתם הנאיבי על 2n2^n תת-קבוצות, בדיקת ראשוניות נאיבית, המקרה האונרי, ואי-תלות הבסיס — מופיע בסיכום רק כשתי שורות כחולות. ההכרעה: שוחזר במלואו ונוסח כמשפט 5 ובהגדרה 3.
  • מקור: ההקלטה בלבד. הפער: שני "הניסיונות שנשברו" ברדוקציה 3COL≤p4COL\mathrm{3COL}\le_p \mathrm{4COL} (הזהות; הוספת קודקוד בלי קשתות) והדיון על מה מותר לרדוקציה לדעת ([00:16:53], [00:21:39], [00:31:29]) אינם בסיכום כלל. ההכרעה: נכללו במלואם, כולל דוגמאות נגדיות מפורשות שההרצאה לא נתנה; זהו החומר החשוב ביותר בהקלטה שאינו בסיכום.
  • מקור: חלוקת החומר בין קבצי השיעורים. הפער: הרדוקציה 3COL≤p4COL\mathrm{3COL}\le_p \mathrm{4COL} נמצאת בעמודים 2–3 של סיכום שיעור 11 (הקובץ הזה) ולא בסיכומי שיעור 10, אף שבמקור נכתבה גם שם. ההכרעה: לפי הסיכום הכתוב היא שייכת לשיעור 11 ונכתבת כאן במלואה (משפט 2, דוגמה 3, תרגיל 1); על הקובץ של שיעור 10 להפנות לכאן.
  • מקור: הקצאת התמלילים במשימה. הפער: תמליל 18 (fnWzohq8TdofnWzohq8Tdo) הוגדר כתמליל הראשי לשיעור זה, אך תוכנו הוא שיעור 12 (PARTITION, BIN PACKING, מעגלים המילטוניים, TSP), והוא נפתח במילים "בשיעור האחרון ראינו את SUBSET SUM". ההכרעה: תמליל 17 (QfE6eBttdJgQfE6eBttdJg) הוא התמליל הראשי בפועל — חמשת עמודי הסיכום מופיעים בו לפי הסדר. סומן בהתאם בשדה sources.

סיכום ונקודות למבחן

מה לזכור בעל פה.

  1. SUBSET-SUM\mathrm{SUBSET\text{-}SUM}: בהינתן a1,…,an,Sa_1,\dots,a_n,S בבסיס ≥2\ge 2, האם קיימת I⊆{1,…,n}I\subseteq\{1,\dots,n\} עם ∑i∈Iai=S\sum_{i\in I}a_i=S. הבעיה NP-complete.
  2. הרדוקציה: VC≤pSUBSET-SUM\mathrm{VC} \le_p \mathrm{SUBSET\text{-}SUM}. m+1m+1 עמודות: עמודה מובילה dd + עמודה לכל קשת. ava_v מתחיל ב-11 ומסמן את הקשתות הנוגעות ב-vv; aea_e מתחיל ב-00 והוא וקטור יחידה; S=K⋅10m+∑j2⋅10m−jS=K\cdot 10^m+\sum_j 2\cdot 10^{m-j}.
  3. הטיעון: בכל עמודת קשת מצטברות לכל היותר 33 אחדות ⇒\Rightarrow אין נשאות ⇒\Rightarrow שוויון סכומים = שוויון ספרה-ספרה ⇒\Rightarrow "בדיוק 22 בכל עמודה"   ⟺  \iff "לפחות קצה אחד נבחר", ו-"KK בעמודה dd"   ⟺  \iff "נבחרו בדיוק KK קודקודים".
  4. DP\mathrm{DP} בזמן O(n⋅S)O(n\cdot S) הוא pseudo-polynomial ולא פולינומי. ערך מול אורך ייצוג: log⁡\log ביטים לערך nn.
  5. A∈PA\in P ו-BB לא-טריוויאלית ⇒A≤pB\Rightarrow A\le_p B; מכאן ש-≤p\le_p גס מדי מכדי להבחין בין בעיות בתוך PP.
  6. 4COL\mathrm{4COL} היא NP-complete באמצעות הוספת קודקוד המחובר לכל השאר.

מלכודות סטנדרטיות.

  • לכתוב רדוקציה שמסתכלת על הפתרון. "אם הגרף 33-צביע נחזיר..." — אסור. האלגוריתם רואה רק את הקלט הגולמי. הצביעה/הכיסוי/ההשמה מופיעים אך ורק בהוכחת הנכונות.
  • לשכוח להוכיח את הכיוון השני. בדיוק הכיוון שהסיכום מדלג עליו הוא הכיוון שנשבר בבניות שגויות.
  • להניח אי-נשאות בלי לנמק. במבחן צריך לומר במפורש: בכל עמודה מצטברות לכל היותר 33 אחדות, ולכן בבסיס 1010 אין נשאות, ולכן אפשר לקרוא ספרה-ספרה.
  • לבלבל בין "לכל היותר KK" ל"בדיוק KK" בהגדרת VC\mathrm{VC}.
  • לקרוא ל-O(n⋅S)O(n\cdot S) "פולינומי". זו המלכודת המרכזית של השיעור. תמיד שאלו: מה אורך הייצוג של המספר, לא מה ערכו.
  • להפוך את כיוון הרדוקציה. A≤pBA\le_p B פירושו ש-BB קשה לפחות כמו AA. כדי להוכיח ש-BB קשה, מתחילים מבעיה קשה ידועה ואליה לא עושים רדוקציה — עושים ממנה.

צ'ק-ליסט: אחרי השיעור אתם צריכים לדעת

  • לנסח את SUBSET-SUM\mathrm{SUBSET\text{-}SUM} פורמלית ולהוכיח שהיא ב-NP\mathrm{NP} עם certificate מפורש.
  • לבנות את המספרים av,ae,Sa_v,a_e,S עבור גרף קטן נתון, ולחשב את הסכום בשתי הבחירות.
  • לנמק במלואו מדוע אין נשאות ולמה בלעדיה הטיעון קורס.
  • להוכיח את שני כיווני הנכונות של הרדוקציה, ולנמק מדוע היא פולינומית — כולל למה מותר לה לייצר מספרים בעלי ערך מעריכי.
  • לחשב אורך קלט מול זמן ריצה במשפחת הקלטים 2n≤ai,S≤22n2^n\le a_i,S\le 2^{2n}, ולהסביר מדוע O(n⋅S)O(n\cdot S) אינו פולינומי.
  • לבנות את הרדוקציה 3COL≤p4COL\mathrm{3COL}\le_p \mathrm{4COL} מאפס, ולהסביר מדוע הזהות ומדוע קודקוד לא מחובר אינם עובדים.

Questions left open

  • עמוד 4 בסיכום: כותרת המשנה הכחולה שמעל דוגמת הגדלים ($2^n \le a_i \le 2^{2n}$) אינה חד־משמעית; שוחזרה לפי ההקשר כ'הבחנה'.
  • עמוד 4 בסיכום: שורת הקלט כתובה 'k מספרים $a_1,\dots,a_n$'; מדובר כנראה בפליטת קולמוס והכוונה ל-$n$ מספרים.
  • עמוד 5 בסיכום: הערה קצרה בכתב יד ליד חץ הסיכום בדוגמה שוחזרה כ'ונחבר אותם לסכום שקיבלנו'; הניסוח המדויק אינו ודאי.
  • בהקלטה [00:12:25] נאמר שבשיעורי הבית יש להוכיח שמחלקה מהצורה $\mathrm{DTime}(n^{10})$ אינה סגורה לרדוקציות זמן פולינומי; החזקה המדויקת שנאמרה אינה ברורה בכתוביות.
  • ה-slug 'subset-sum' מתאר בחסר את הקובץ: השיעור מכסה גם את הטענה על רדוקציות משפות ב-P (עמוד 1) וגם את 3COL ≤p 4COL (עמודים 2–3). ההיקף האמיתי נמצא ב-title_he. שם הקובץ לא שונה, כנדרש.
  • הרדוקציה 3COL ≤p 4COL מופיעה בעמודים 2–3 של סיכום שיעור 11 ולא בסיכומי שיעור 10; היא נכתבת כאן במלואה, ועל הקובץ של שיעור 10 להפנות לכאן במקום לשכפל אותה.