1717from ortools .sat .python import cp_model
1818
1919from cascade .compiler import DURATION_UNIT
20- from cascade .compiler .ast import Status , TaskAST
20+ from cascade .compiler .ast import Status
2121from .helpers import piecewise_linear_objective
2222from .piecewise_functions .piecewise_linear_function import (
2323 PiecewiseLinearConstraint ,
@@ -144,6 +144,13 @@ def print_schedule(self):
144144 print_formatted_text (formatted_output )
145145
146146
147+ def add_hints (model : cp_model .CpModel , solver : cp_model .CpSolver ):
148+ model .clear_hints ()
149+ for i , _ in enumerate (model .proto .variables ):
150+ v_ = model .get_int_var_from_proto_index (i )
151+ model .add_hint (v_ , solver .value (v_ ))
152+
153+
147154@dataclass
148155class BasicModel :
149156 """
@@ -167,7 +174,11 @@ def get_total_slots(self) -> int:
167174
168175 def solve (self ) -> cp_model .CpSolver :
169176 solver = cp_model .CpSolver ()
170- # solver.parameters.log_search_progress = True
177+ solver .parameters .log_search_progress = True
178+ # stop when we are within 2% of the upper bound of optimum (provable) cause making it drop can take a long time.
179+ solver .parameters .relative_gap_limit = 0.02
180+ # since we are adding hints, models are no longer suffering from cold start issues, we might just add a time limit to solve plateau problem
181+ solver .parameters .max_time_in_seconds = 120
171182 status = solver .solve (self .model )
172183
173184 match status :
@@ -306,8 +317,10 @@ def to_cuf_model(self) -> CUFModel:
306317 return CUFModel .from_total_utility_model (self )
307318
308319 def set_objective_constraint (self ):
309- optimal = int (self .solve ().objective_value )
320+ sol = self .solve ()
321+ optimal = int (sol .objective_value )
310322 self .model .clear_objective ()
323+ add_hints (self .model , sol )
311324 self .model .add (sum (utility .y for utility in self .utilities .values ()) >= optimal )
312325
313326 @classmethod
@@ -414,9 +427,8 @@ def from_basic_model(cls, basic_model: BasicModel) -> Self:
414427 cuf_prod [id ],
415428 [utilities [id ].y , total_slots - interval_vars [id ].end_expr ()],
416429 )
417- # TODO: This 2x is probably not necessary
418430 cuf [id ] = model .new_int_var (
419- 0 , 2 * node .priority * total_slots * YSCALE , f"cuf_{ id } "
431+ 0 , node .priority * total_slots * YSCALE , f"cuf_{ id } "
420432 )
421433 model .add (cuf [id ] == cuf_int [id ].y + cuf_prod [id ])
422434
@@ -456,8 +468,10 @@ def from_total_utility_model(cls, tu_model: TotalUtilityModel) -> Self:
456468 return cls (** vars (tu_model ))
457469
458470 def set_objective_constraint (self ):
459- optimal = int (self .solve ().objective_value )
471+ sol = self .solve ()
472+ optimal = int (sol .objective_value )
460473 self .model .clear_objective ()
474+ add_hints (self .model , sol )
461475 self .model .add (sum (self .cuf .values ()) >= optimal )
462476
463477
0 commit comments