Vegman
Design · Solver Strategy

Solver Strategy

A proposal, not a decision. Every entity and relationship below is open to challenge; the open decisions are listed at the end.

Version 0.1, 6 September 2026. Answers: "timetabling is NP-complete; what makes it tractable so we can actually do anything?" Numbers are measured on Mevo Hagalil with the engine in apps/engine (OR-Tools CP-SAT 9.15, 8 workers, laptop).

Overview

NP-completeness is a statement about the worst case of the general problem; nothing we do removes it. What we can do is hand the solver instances that are not the worst case, never ask for a proof of optimality, and keep a human in the loop for the decisions that are really human. The research brief (section 4) names four reasons real timetables get built: propagation, clause learning, slack, and anytime search. This document turns those into engineering choices for Mevo Hagalil and reports what they buy.

Summary

Bottom line

Mevo Hagalil is a small, slack instance once the fixed structure is removed, and CP-SAT solves it to a better score than the hand-made timetable in under a minute. The product should show a first feasible timetable within seconds and improve it in the background; it should treat "prove optimal" as a non-goal. The risk is not solver speed but data quality: subjects, hour baskets and the identity of the co-teaching specialists are missing, and without them three of Vegman's rules cannot be enforced at all.

Detailed explanation

(a) Fixing what is already decided

The importer produces 570 events for 594 class-slots. 33 are fixed in time by the school's own programmes (S-05 to S-07: choir, orchestras, mentoring, the grade-5 Tuesday block, meetings, no-class gym and music slots) and are pruned to one start each. Homeroom pairing (S-02) is inferred once and stored on Class and Staff; it never becomes a variable. Grade-team meetings become unavailable rows on the three homeroom teachers of that grade; part-time days (R-09) become whole-day unavailable rows inferred from the export. These land as domain pruning: a hard availability row deletes start variables instead of adding constraints, so a part-timer on two days has 14 starts per lesson, not 33.

(b) Decomposition into stages

  1. Staff to class is a human decision (which teacher takes ג' נשר mathematics) and stays one. The importer reads it from the export; the back-office will let Vegman edit it. This is where the combinatorics would explode (45 staff × 570 events) and exactly the stage a deputy head wants to own.
  2. Time assignment is the solver's job: 570 events into 33 slots, subject to clashes, availability and the R rules. This is what the numbers above measure.
  3. Room assignment, when Q-13 says it is needed, is a bipartite matching per slot, solvable independently and near-instantly once times are known. Kristiansen et al. (2015, brief reading 9) show the two-step split costs little on XHSTT instances.

Each stage is small because the others are fixed while it runs. A StaffSlot with staffId: null is stage 1 work left undone, not a request for the solver.

(c) Propagation and clause learning

Every class has exactly 33 lessons for 33 slots, so the per-class AtMostOne constraints are tight packings: placing one lesson removes that slot for 32 others. Staff clashes propagate across classes. At a dead end CP-SAT learns a clause naming the combination that failed and never revisits it (brief section 4). The observable effect is 0.3 s to first feasible: propagation collapses most of the 14,096 start variables before branching.

The solver runs with a time limit and 8 workers and reports each improving solution through a callback (elapsed, objective, bound, phase). Hard constraints are true constraints, so the first solution already has hard = 0; the objective is the weighted soft cost. The UI should show the phase (searching, then improving), the current soft cost by constraint type, the lower bound (10 here: no timetable can score below 10), and a "use this now" button at every point. Measured trajectory from scratch: 104 at 5 s, 93 at 10 s, 64 at 30 s, 28 at 60 s.

(e) Warm start and minimal-perturbation repair

AddHint seeds the search with the previous timetable. On this instance it makes no measurable difference to time-to-feasible (0.31 s versus 0.30 s) because feasibility is already trivial, and it does not keep the solution close: the hinted run still moved 492 of 570 events, because nothing in the objective rewarded staying put. Repair therefore adds a stability term: a penalty per event that leaves its previous slot, plus pinning for events the user has locked. This is the classical minimal-perturbation formulation (brief section 5, MaxSAT CPAIOR 2020) and the mechanism for mid-year changes: a teacher leaves, her lessons are reassigned in stage 1, and the solver moves the fewest lessons that restore hard = 0. Fix-and-optimize (Dorneles et al. 2014) is the same idea applied by the solver to itself: CP-SAT's LNS workers relax a neighbourhood, re-solve, and keep the improvement. Measured repair from the hand-made timetable (weight 1 per move, 30 s): 35 of 570 events moved, hard 1 to 0, soft 214 to 141, with a proven bound of 134 on the combined objective.

(f) Symmetry and dominance

Slots on the four seven-period days are interchangeable for most events, and so are the five weekly lessons of one course. Both create symmetric solutions that waste search. Data breaks the first kind partly (fixed events, meetings and the short Tuesday make days distinct); CP-SAT's symmetry detection handles the rest. The second kind is handled by generating same-course events as an EventGroup spread over days, which makes them distinguishable; when the curriculum arrives (N-03), lexicographic ordering within a course removes the remaining permutations.

(g) Effective size and solve times

Measured on 6 September 2026 after Vegman's answers were applied (requirements v0.3, engine README "Applied answers").

QuantityValue
Events571 (515 lessons, 55 activities incl. 12 half-class music events, 1 meeting)
Class-slots covered594
Start variables x[e,s]13,948 (of 571 × 33 = 18,843 before pruning)
Booleans in the model17,422
Constraints7,411
Time to first feasible, from scratch0.32 s
Soft cost at 5 / 10 / 30 / 60 s73 / 60 / 58 / 53, proven optimal (53) at 48 s
Warm-started (hint only): first feasible, cost at 5 s / 60 s0.31 s, 58 / 53 (optimal at 44 s)
Repair (hint + stability 1, 30 s)46 events moved, soft 66, optimal for that objective in 11 s
Hand-made timetable (30 Aug export, corrected per S-17)hard 3, soft 164

The hand-made score by type: no-clash 0 (the ליבנה double booking was a stale cell, S-17); no-gaps hard 3, the excess over the weekly gap budget of Q-04 for two small posts (רותם 3 gaps against a budget of 2, יפעת 2 against 0) whose individual and staying hours are estimated from the export and are probably wrong at that scale; ends-long-day 115 (18 teachers not at their R-07 target, 9 of them part-timers whose proportional target is pending Q-24); room-shared-owners 54 (the gym owners אתי and רגב teach simultaneously in 11 periods, the music-shelter owners נגה and שני in 7); homeroom-starts-first-period 5 (סתו opens her own class twice); availability, fixed-time, block-at-periods, spread-over-days, room-owner-whole-class all 0. Total gaps are 106 against a total budget of 306, so the gap rule, now hard, leaves the solver a lot of room: the optimum of 53 has no gap violation at all. What remains at the optimum is structural: אתי teaches every period of her two days while רגב teaches 26 of 33, so some gym overlap is unavoidable, and the part-time long-day targets.

(h) What makes an instance hard, and the fallback

Hardness comes from tightness, not size: part-timers whose few days coincide with everyone's fixed blocks, many grade-wide linked blocks on distinct days, scarce specialist rooms (brief section 4). When the hard constraints cannot all hold, INFEASIBLE alone is useless to a deputy head. The engine rebuilds the model with one assumption literal per constraint family (each staff member's availability, each class's clash set, each fixed event, each block rule) and asks CP-SAT for a sufficient set of assumptions for infeasibility. The result is a short list such as "availability אתי; fixed-time ev-orchestra-thu-6; no-clash class ג' בז" naming the smallest conflicting set found: the pattern the brief recommends (section 5, TRACE-cs), where the solver computes the explanation and language only translates it.

(i) The constraint catalogue as data

Every rule is a row: type, hard, weight, params, appliesTo, implements. Each type has a scorer that evaluates any Timetable without a solver; the CP-SAT adapter mirrors the same definitions. Because the scorer is independent, the solver can be audited: on every run so far the model objective equals the catalogue's soft score exactly. Eight types are implemented; subject-per-day, double-period and avoid-last-period are registered and return a note until subjects (N-01), the curriculum (N-03) and the x/y/z list (Q-09) exist. A new rule is one scorer and one model fragment; the domain is untouched.

תכנון · אסטרטגיית הפותר

אסטרטגיית הפותר

הצעה, לא החלטה. כל ישות וקשר להלן פתוחים לערעור; ההחלטות הפתוחות מפורטות בסוף.

גרסה 0.1, 6 בספטמבר 2026. עונה על השאלה: "בניית מערכת שעות היא בעיה NP-complete (NP-שלמה); מה הופך אותה לפתירה בפועל, כך שנוכל בכלל לעשות משהו?" המספרים נמדדו על מבוא הגליל עם המנוע שב-apps/engine (OR-Tools CP-SAT 9.15, 8 עובדים, מחשב נייד).

סקירה

NP-שלמות היא אמירה על המקרה הגרוע ביותר של הבעיה הכללית; שום דבר שנעשה לא מבטל אותה. מה שאנחנו כן יכולים לעשות הוא למסור לפותר מופעים שאינם המקרה הגרוע, לעולם לא לבקש הוכחת אופטימליות, ולהשאיר אדם בלולאה עבור ההחלטות שהן באמת אנושיות. תקציר המחקר (סעיף 4) מונה ארבע סיבות לכך שמערכות שעות אמיתיות אכן נבנות: constraint propagation (הפצת אילוצים), clause learning (למידת פסוקיות), מרווח, וחיפוש anytime (בכל-עת). מסמך זה מתרגם אותן להחלטות הנדסיות עבור מבוא הגליל ומדווח מה הן מניבות.

תקציר

שורה תחתונה

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

הסבר מפורט

(a) קיבוע מה שכבר הוחלט

המייבא מפיק 570 אירועים עבור 594 משבצות-כיתה. 33 מהם קבועים בזמן על ידי התוכניות של בית הספר עצמו (S-05 עד S-07: מקהלה, תזמורות, חונכות, בלוק יום שלישי של כיתות ה', ישיבות, משבצות חינוך גופני ומוזיקה ללא כיתה) ונגזמים להתחלה אחת בלבד לכל אחד. שיוך המחנכות (S-02) מוסק פעם אחת ונשמר על Class ועל Staff; הוא לעולם לא הופך למשתנה. ישיבות צוות שכבה הופכות לשורות unavailable אצל שלוש המחנכות של אותה שכבה; ימי משרה חלקית (R-09) הופכים לשורות unavailable של יום שלם, המוסקות מהייצוא. אלה מתבטאים כגיזום תחום: שורת זמינות קשיחה מוחקת משתני התחלה במקום להוסיף אילוצים, ולכן למורה במשרה חלקית של יומיים יש 14 התחלות לכל שיעור, לא 33.

(b) פירוק לשלבים

  1. צוות לכיתה היא החלטה אנושית (איזו מורה לוקחת מתמטיקה בג' נשר) ונשארת כזו. המייבא קורא אותה מהייצוא; המשרד האחורי יאפשר לווגמן לערוך אותה. כאן הקומבינטוריקה הייתה מתפוצצת (45 אנשי צוות × 570 אירועים), וזה בדיוק השלב שסגנית מנהל רוצה להחזיק בבעלותה.
  2. שיבוץ בזמן הוא תפקידו של הפותר: 570 אירועים לתוך 33 משבצות, בכפוף להתנגשויות, זמינות וכללי ה-R. זה מה שהמספרים לעיל מודדים.
  3. שיבוץ חדרים, כאשר Q-13 קובע שהוא נדרש, הוא התאמה דו-צדדית לכל משבצת, הניתנת לפתרון באופן עצמאי וכמעט מיידי ברגע שהזמנים ידועים. Kristiansen ואחרים (2015, קריאה 9 בתקציר) מראים שהפיצול לשני שלבים עולה מעט מאוד על מופעי XHSTT (פורמט הבנצ'מרק הבין-לאומי למערכות שעות).

כל שלב קטן משום שהאחרים קבועים בזמן שהוא רץ. StaffSlot עם staffId: null הוא עבודה של שלב 1 שלא הושלמה, לא בקשה מהפותר.

(c) הפצת אילוצים ולמידת פסוקיות

לכל כיתה יש בדיוק 33 שיעורים ל-33 משבצות, ולכן אילוצי AtMostOne לכל כיתה הם אריזות הדוקות: מיקום שיעור אחד מסיר את המשבצת הזו עבור 32 האחרים. התנגשויות צוות מתפשטות בין כיתות. במבוי סתום CP-SAT לומד פסוקית המציינת את הצירוף שנכשל ולעולם אינו חוזר אליו (תקציר, סעיף 4). ההשפעה הנצפית היא 0.3 שניות עד לפתרון ישים ראשון: ההפצה מקריסה את רוב 14,096 משתני ההתחלה עוד לפני ההסתעפות.

(d) חיפוש בכל-עת

הפותר רץ עם מגבלת זמן ו-8 עובדים ומדווח על כל פתרון משופר דרך callback (זמן שחלף, ערך המטרה, חסם, שלב). אילוצים קשיחים הם אילוצים אמיתיים, ולכן כבר בפתרון הראשון קשיח = 0; פונקציית המטרה היא העלות הרכה המשוקללת. ממשק המשתמש צריך להציג את השלב (searching, ואז improving), את העלות הרכה הנוכחית לפי סוג אילוץ, את החסם התחתון (כאן 10: אף מערכת שעות לא יכולה לקבל ציון נמוך מ-10), וכפתור "השתמש בזה עכשיו" בכל נקודה. מסלול שנמדד מאפס: 104 אחרי 5 שניות, 93 אחרי 10 שניות, 64 אחרי 30 שניות, 28 אחרי 60 שניות.

(e) התחלה חמה ותיקון בהפרעה מינימלית

AddHint מזין את החיפוש במערכת השעות הקודמת. במופע הזה אין לכך הבדל מדיד בזמן עד לפתרון ישים (0.31 שניות לעומת 0.30 שניות), משום שהישימות כבר טריוויאלית, והוא גם לא שומר את הפתרון קרוב: הריצה עם הרמז עדיין הזיזה 492 מתוך 570 אירועים, כי שום דבר בפונקציית המטרה לא תגמל על הישארות במקום. לכן התיקון מוסיף איבר יציבות: קנס לכל אירוע שעוזב את המשבצת הקודמת שלו, בתוספת הצמדה של אירועים שהמשתמש נעל. זהו הניסוח הקלאסי של הפרעה מינימלית (תקציר, סעיף 5, MaxSAT CPAIOR 2020) והמנגנון לשינויים באמצע השנה: מורה עוזבת, שיעוריה משובצים מחדש בשלב 1, והפותר מזיז את מספר השיעורים הקטן ביותר שמחזיר קשיח = 0. fix-and-optimize (קבע-ואופטימז; Dorneles ואחרים 2014) הוא אותו רעיון שהפותר מיישם על עצמו: עובדי ה-LNS של CP-SAT משחררים סביבה, פותרים מחדש ושומרים את השיפור. תיקון שנמדד ממערכת השעות הידנית (משקל 1 לכל הזזה, 30 שניות): 35 מתוך 570 אירועים הוזזו, קשיח 1 ל-0, רך 214 ל-141, עם חסם מוכח של 134 על פונקציית המטרה המשולבת.

(f) סימטריה ודומיננטיות

המשבצות בארבעת הימים בני שבע השעות ניתנות להחלפה זו בזו עבור רוב האירועים, וכך גם חמשת השיעורים השבועיים של קורס אחד. שני המקרים יוצרים פתרונות סימטריים שמבזבזים חיפוש. הנתונים שוברים את הסוג הראשון חלקית (אירועים קבועים, ישיבות ויום שלישי הקצר מבדילים בין הימים); זיהוי הסימטריה של CP-SAT מטפל בשאר. הסוג השני מטופל על ידי יצירת אירועים של אותו קורס כ-EventGroup הפרוס על פני ימים, מה שהופך אותם לניתנים להבחנה; כשתוכנית הלימודים תגיע (N-03), סידור לקסיקוגרפי בתוך קורס יסיר את התמורות שנותרו.

(g) גודל אפקטיבי וזמני פתרון

כמותערך
אירועים570 (515 שיעורים, 49 פעילויות, 6 ישיבות)
משבצות-כיתה מכוסות594
משתני התחלה x[e,s]14,096 (מתוך 570 × 33 = 18,810 לפני גיזום)
משתנים בוליאניים במודל17,675
אילוצים7,460
זמן עד לפתרון ישים ראשון, מאפס0.30 שניות
עלות רכה אחרי 5 / 10 / 30 / 60 שניות104 / 93 / 64 / 28 (חסם תחתון 10)
התחלה חמה (רמז בלבד): פתרון ישים ראשון, עלות אחרי 60 שניות0.31 שניות, 23
תיקון (רמז + יציבות 1, 30 שניות)35 אירועים הוזזו, רך 141, חסם 134
מערכת שעות ידנית (ייצוא 30 באוגוסט)קשיח 1, רך 214

ציון המערכת הידנית לפי סוג: no-clash 1 (ליבנה, יום שלישי שיעור 2, בג' נשר ובד' סביון); no-gaps 109 שעות חלון על פני 87 ימי-מורה; ends-long-day 105 (18 מורים שאינם בדיוק בשני ימים ארוכים); homeroom-starts-first-period, availability, fixed-time, block-at-periods, spread-over-days כולם 0. נתון ה-no-gaps מנופח מעצם בנייתו: שעות פרטניות ושעות שהייה אינן בייצוא (Q-03), ולכן כל חלון אמיתי נספר.

(h) מה הופך מופע לקשה, ומנגנון הגיבוי

הקושי נובע מהידוק, לא מגודל: מורים במשרה חלקית שימיהם המעטים חופפים לבלוקים הקבועים של כולם, בלוקים מקושרים רבים ברמת השכבה בימים נפרדים, חדרי מומחים נדירים (תקציר, סעיף 4). כשהאילוצים הקשיחים אינם יכולים להתקיים כולם, INFEASIBLE לבדו חסר תועלת לסגנית מנהל. המנוע בונה את המודל מחדש עם ליטרל הנחה אחד לכל משפחת אילוצים (הזמינות של כל איש צוות, קבוצת ההתנגשויות של כל כיתה, כל אירוע קבוע, כל כלל בלוק) ומבקש מ-CP-SAT קבוצה מספקת של הנחות לאי-ישימות. התוצאה היא רשימה קצרה כגון "availability אתי; fixed-time ev-orchestra-thu-6; no-clash class ג' בז" המציינת את הקבוצה המתנגשת הקטנה ביותר שנמצאה: התבנית שהתקציר ממליץ עליה (סעיף 5, TRACE-cs), שבה הפותר מחשב את ההסבר והשפה רק מתרגמת אותו.

(i) קטלוג האילוצים כנתונים

כל כלל הוא שורה: type, hard, weight, params, appliesTo, implements. לכל סוג יש מדרג (scorer) שמעריך כל Timetable ללא פותר; המתאם של CP-SAT משקף את אותן הגדרות. מכיוון שהמדרג עצמאי, ניתן לבקר את הפותר: בכל ריצה עד כה ערך המטרה של המודל שווה בדיוק לציון הרך של הקטלוג. שמונה סוגים ממומשים; subject-per-day, double-period ו-avoid-last-period רשומים ומחזירים הערה עד שיהיו קיימים מקצועות (N-01), תוכנית הלימודים (N-03) ורשימת x/y/z (Q-09). כלל חדש הוא מדרג אחד וקטע מודל אחד; התחום נותר ללא שינוי.