קודקוד לכל קשת, ואותו $k$

VC ≤p DS

VC≤pDS\mathrm{VC}\le_p\mathrm{DS}, ולכן DS\mathrm{DS} (קבוצה שולטת) היא NP-שלמה.

הבנייה

על קלט ⟨G,k⟩\langle G,k\rangle עם G=(V,E)G=(V,E):

  1. לכל קשת xy∈Exy\in E: הוסף קודקוד חדש vxyv_{xy} וחבר אותו בקשת ל-xx ובקשת ל-yy.
  2. הסר מהגרף המתקבל את כל הקודקודים המבודדים, והחזר את הגרף G^=(V^,E^)\hat G=(\hat V,\hat E) יחד עם אותו kk.

מה עושה vxyv_{xy}, בשורה אחת: הוא כופה על אחד מבין x,yx,y להיות בפנים. זו כל הרדוקציה — תרגום הדרישה "כל קשת נגועה" לדרישה "כל קודקוד נשלט", על ידי הפיכת כל קשת לקודקוד שדורש שליטה.

למה צריך את שלב 2. קודקוד מבודד ב-GG אינו נוגע באף קשת ולכן לעולם אינו דרוש לכיסוי; לעומת זאת בקבוצה שולטת קודקוד מבודד חייב להיכנס לקבוצה, כי אין לו שכן שיכסה אותו. בלי שלב 2 היינו מחייבים את DS\mathrm{DS} להוסיף קודקודים שאין להם מקבילה בצד VC\mathrm{VC}, וזה היה מקלקל את שמירת התשובה. מכיוון שהסרת קודקודים מבודדים אינה משנה את התשובה של VC\mathrm{VC} (הקשתות לא השתנו), מותר להניח מכאן ואילך ש-GG נטול קודקודים מבודדים.

התכונה המבנית שנשתמש בה שוב ושוב: לכל קודקוד חדש vxyv_{xy} יש בדיוק שני שכנים ב-G^\hat G, והם xx ו-yy, ושניהם ב-VV.

המחשה

בנייה מודרכת

כיסוי קודקודים → קבוצה שולטת

שלב 1 מתוך 7
⟨G, k = 2⟩ ∈ VC ?
כיסוי קודקודים לקבוצה שולטת: קודקוד לכל קשת, ומחיקת קודקודים מבודדיםגרף המקור G עם הקודקודים a, b, c, d וקודקוד מבודד z מופיע בצד אחד. בצד השני הגרף Ĝ מוסיף קודקוד לכל קשת ומחבר אותו לשני קצותיה, מוחק את z, ושומר את אותו סף k. ההדגשות מראות את הכיסוי U שמשמש כקבוצה שולטת, קבוצה שולטת שמכילה קודקוד חדש, ואת מפת התיקון שמחזירה את הקודקוד החדש לקודקוד מקורי.G — גרף המקורabcdzמבודד
קודקוד מקורי מתוך V

נכונות — שני הכיוונים

VC ∈ ⟹ DS ∈

נניח ⟨G,k⟩∈VC\langle G,k\rangle\in\mathrm{VC}. אז קיימת U⊆VU\subseteq V עם ∀e∈E: e∩U≠∅\forall e\in E:\ e\cap U\ne\emptyset ו-∣U∣≤k|U|\le k.

נתבונן באותה UU בדיוק, כתת-קבוצה של V^\hat V (חוקי, כי V⊆V^V\subseteq\hat V). נראה שהיא שולטת ב-G^\hat G. יהי x∈V^x\in\hat V ונניח x∉Ux\notin U (אם x∈Ux\in U אין מה להוכיח).

מקרה 1: x∈Vx\in V. מכיוון ש-GG נטול קודקודים מבודדים, קיים y∈Vy\in V עם xy∈Exy\in E. UU כיסוי, ולכן x∈Ux\in U או y∈Uy\in U; הנחנו x∉Ux\notin U, ולכן y∈Uy\in U. וכן xy∈E⊆E^xy\in E\subseteq\hat E. אז ל-xx יש שכן ב-UU.

מקרה 2: x∉Vx\notin V. אז xx נוצר בשלב 1, כלומר קיימים a,b∈Va,b\in V עם ab∈Eab\in E ו-x=vabx=v_{ab}. UU כיסוי, ולכן a∈Ua\in U או b∈Ub\in U; ומהבנייה ax∈E^ax\in\hat E וגם bx∈E^bx\in\hat E. לכן קיים y∈{a,b}∩Uy\in\{a,b\}\cap U עם xy∈E^xy\in\hat E — ל-xx יש שכן ב-UU.

בשני המקרים x∈Ux\in U או שיש לו שכן ב-UU; לכן UU שולטת ב-G^\hat G, וגודלה ∣U∣≤k|U|\le k לא השתנה. מכאן ⟨G^,k⟩∈DS\langle\hat G,k\rangle\in\mathrm{DS}.

DS ∈ ⟹ VC ∈

נניח שקיימת U^⊆V^\hat U\subseteq\hat V שולטת ב-G^\hat G עם ∣U^∣≤k|\hat U|\le k.

כאן אי אפשר לקחת את U^\hat U כמו שהיא — היא אולי מכילה קודקודים חדשים, ולכן אינה מוכלת ב-VV ובוודאי אינה כיסוי של GG. נבנה ממנה U⊆VU\subseteq V:

> לכל x∈U^x\in\hat U: אם x∈Vx\in V — נכניס את xx ל-UU; אם x∉Vx\notin V — נכניס אחד משכניו (לפי כלל שרירותי קבוע; הבחירה אינה משנה).

U⊆VU\subseteq V: לכל x∈U^∖Vx\in\hat U\setminus V שני שכניו ב-VV, ובמקרה הראשון הכנסנו x∈Vx\in V עצמו.

גודל: לכל איבר של U^\hat U הכנסנו לכל היותר איבר אחד, ולכן ∣U∣≤∣U^∣≤k|U|\le|\hat U|\le k. (ייתכן שהכנסנו את אותו קודקוד פעמיים ואז ∣U∣|U| קטן ממש — רק לטובתנו, כי דרוש חסם עליון.)

UU כיסוי בקודקודים של GG: תהי xy∈Exy\in E ונניח x∉Ux\notin U; נראה y∈Uy\in U.

ראשית, x∉Ux\notin U יחד עם x∈Vx\in V גורר x∉U^x\notin\hat U — אילו היה x∈U^x\in\hat U, הבנייה הייתה מכניסה אותו ל-UU.

כעת נתבונן ב-vxy∈V^v_{xy}\in\hat V; הוא קיים, כי xy∈Exy\in E ולכן שלב 1 יצר אותו. U^\hat U שולטת, ולכן vxy∈U^v_{xy}\in\hat U או שקיים שכן שלו ב-U^\hat U.

מקרה 1: vxy∈U^v_{xy}\in\hat U. אז בבניית UU הכנסנו אחד משכניו — את xx או את yy. מכיוון ש-x∉Ux\notin U, בהכרח הכנסנו את yy, ולכן y∈Uy\in U.

מקרה 2: קיים שכן של vxyv_{xy} ב-U^\hat U. שכניו הם בדיוק xx ו-yy, ושניהם ב-VV. מכיוון ש-x∉U^x\notin\hat U, בהכרח y∈U^y\in\hat U; ומכיוון ש-y∈Vy\in V, הבנייה הכניסה את yy עצמו ל-UU.

בשני המקרים y∈Uy\in U, ולכן xy∩U≠∅xy\cap U\ne\emptyset. מכיוון ש-xyxy שרירותית, UU כיסוי בגודל ≤k\le k, כלומר ⟨G,k⟩∈VC\langle G,k\rangle\in\mathrm{VC}.

סיבוכיות הרדוקציה

זמןO(|V| + |E|)
מקוםO(|V| + |E|)
גודל הפלט|V̂| ≤ |V| + |E|, |Ê| ≤ 3|E|

הלולאה רצה ∣E∣|E| פעמים, ובכל איטרציה מוסיפים קודקוד אחד ושתי קשתות — זמן קבוע (או O(log⁡)O(\log) בייצוג סביר). זיהוי הקודקודים המבודדים הוא מעבר יחיד על רשימות השכנויות, O(∣V∣+∣E∣)O(|V|+|E|). גם הפלט פולינומי, מה שנחוץ — אחרת אי אפשר היה לכתוב אותו בזמן פולינומי.

מה זה קונה

DS\mathrm{DS} היא NP-קשה, ומכיוון שהיא גם ב-NP\mathrm{NP} — NP-שלמה.

מלכודות

  • הרדוקציה הזהותית נכשלת. קבוצה שולטת אינה חייבת לכסות קשתות: ב-K1,3K_{1,3} (כוכב) המרכז לבדו שולט בכל הגרף וגם מכסה את כל הקשתות, אבל בגרף שהוא זוג קשתות זרות, קבוצה שולטת בגודל 22 יכולה להיבחר אחרת מכיסוי בגודל 22. הכיוון שנשבר הוא זה שדורש תרגום בין "נגיעה בקשת" ל"שליטה בקודקוד", וזה בדיוק מה שקודקוד הקשת vxyv_{xy} עושה.

  • רדוקציה אינה פותרת. האלגוריתם RR אינו יודע מהו UU ואינו יודע מהו U^\hat U — אלה מופיעים רק בהוכחת הנכונות, שבה מותר להניח שקיים פתרון ולבנות ממנו פתרון לצד השני.

השרשרת

נשענת על

מאיפה זה נקרא

  • שיעור 19משפט 4: VC≤pDS\mathrm{VC}\le_p\mathrm{DS}, ולכן DS\mathrm{DS} היא NP-שלמה
  • 2025הגדרת DS\mathrm{DS} והוכחת קשיותה.