@@ -2385,6 +2385,19 @@ cdef class Constraint:
23852385 constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(self .scip_cons))).decode(' UTF-8' )
23862386 return constype == ' knapsack'
23872387
2388+ def isCumulative (self ):
2389+ """
2390+ Returns True if constraint is a cumulative constraint.
2391+ Cumulative is typically used in scheduling applications.
2392+
2393+ Returns
2394+ -------
2395+ bool
2396+
2397+ """
2398+ constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(self .scip_cons))).decode(' UTF-8' )
2399+ return constype == ' cumulative'
2400+
23882401 def isLinearType (self ):
23892402 """
23902403 Returns True if constraint can be represented as a linear constraint.
@@ -7206,6 +7219,96 @@ cdef class Model:
72067219
72077220 return pyCons
72087221
7222+ def addConsCumulative (self , vars , durations , demands , capacity , name = " " ,
7223+ initial = True , separate = True , enforce = True , check = True ,
7224+ modifiable = False , propagate = True , local = False , dynamic = False ,
7225+ removable = False , stickingatnode = False ):
7226+ """
7227+ Add a cumulative constraint.
7228+
7229+ A cumulative constraint models resource-constrained scheduling: given jobs
7230+ with start times, durations, and demands on a shared resource of fixed
7231+ capacity, it ensures that at every time point t the total demand of all
7232+ jobs active at t does not exceed the capacity. Job j is active at t if
7233+ start[j] <= t < start[j] + duration[j].
7234+
7235+ The start times are given as integer variables in `vars`. The `durations`,
7236+ `demands`, and `capacity` arguments must be fixed integers. End times are
7237+ implicit (start + duration); post separate constraints if explicit end
7238+ variables are needed.
7239+
7240+ If you simply want the jobs to not overlap, set all durations to '1'.
7241+
7242+ Parameters
7243+ ----------
7244+ vars : list of Variable
7245+ list of integer variables corresponding to job start times
7246+ durations : list of int
7247+ list of durations, one for each job
7248+ demands : list of int
7249+ list of demands, one for each job
7250+ capacity : int
7251+ available cumulative capacity at any time point
7252+ name : str, optional
7253+ name of the constraint (Default value = "")
7254+ initial : bool, optional
7255+ should the LP relaxation of constraint be in the initial LP? (Default value = True)
7256+ separate : bool, optional
7257+ should the constraint be separated during LP processing? (Default value = True)
7258+ enforce : bool, optional
7259+ should the constraint be enforced during node processing? (Default value = True)
7260+ check : bool, optional
7261+ should the constraint be checked for feasibility? (Default value = True)
7262+ propagate : bool, optional
7263+ should the constraint be propagated during node processing? (Default value = True)
7264+ local : bool, optional
7265+ is the constraint only valid locally? (Default value = False)
7266+ dynamic : bool, optional
7267+ is the constraint subject to aging? (Default value = False)
7268+ removable : bool, optional
7269+ should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
7270+ stickingatnode : bool, optional
7271+ should the constraint always be kept at the node where it was added,
7272+ even if it may be moved to a more global node? (Default value = False)
7273+
7274+ Returns
7275+ -------
7276+ Constraint
7277+ The newly created cumulative constraint
7278+ """
7279+
7280+ cdef int nvars = len (vars )
7281+ cdef int i
7282+ cdef int * durations_array = < int * > malloc(nvars * sizeof(int ))
7283+ cdef int * demands_array = < int * > malloc(nvars * sizeof(int ))
7284+ cdef SCIP_CONS* scip_cons
7285+ cdef _VarArray wrapper
7286+
7287+ assert nvars == len (durations) == len (demands), " Number of variables, durations, and demands must be the same."
7288+
7289+ if name == ' ' :
7290+ name = ' c' + str (SCIPgetNConss(self ._scip)+ 1 )
7291+
7292+ wrapper = _VarArray(vars )
7293+ for i in range (nvars):
7294+ durations_array[i] = < int > durations[i]
7295+ demands_array[i] = < int > demands[i]
7296+
7297+ PY_SCIP_CALL(SCIPcreateConsCumulative(
7298+ self ._scip, & scip_cons, str_conversion(name), nvars, wrapper.ptr, durations_array,
7299+ demands_array, capacity, initial, separate, enforce, check, propagate, local, modifiable,
7300+ dynamic, removable, stickingatnode))
7301+
7302+ free(durations_array)
7303+ free(demands_array)
7304+
7305+ PY_SCIP_CALL(SCIPaddCons(self ._scip, scip_cons))
7306+
7307+ pyCons = self ._getOrCreateCons(scip_cons)
7308+ PY_SCIP_CALL(SCIPreleaseCons(self ._scip, & scip_cons))
7309+
7310+ return pyCons
7311+
72097312 def addConsSOS1 (self , vars , weights = None , name = " " ,
72107313 initial = True , separate = True , enforce = True , check = True ,
72117314 propagate = True , local = False , dynamic = False ,
0 commit comments