forked from ds4dm/PySCIPOpt
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconshdlr.pxi
457 lines (387 loc) · 19.5 KB
/
conshdlr.pxi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
##@file conshdlr.pxi
#@brief base class of the Constraint Handler plugin
cdef class Conshdlr:
cdef public Model model
cdef public str name
def consfree(self):
'''calls destructor and frees memory of constraint handler '''
pass
def consinit(self, constraints):
'''calls initialization method of constraint handler '''
pass
def consexit(self, constraints):
'''calls exit method of constraint handler '''
pass
def consinitpre(self, constraints):
'''informs constraint handler that the presolving process is being started '''
pass
def consexitpre(self, constraints):
'''informs constraint handler that the presolving is finished '''
pass
def consinitsol(self, constraints):
'''informs constraint handler that the branch and bound process is being started '''
pass
def consexitsol(self, constraints, restart):
'''informs constraint handler that the branch and bound process data is being freed '''
pass
def consdelete(self, constraint):
'''sets method of constraint handler to free specific constraint data '''
pass
def constrans(self, sourceconstraint):
'''sets method of constraint handler to transform constraint data into data belonging to the transformed problem '''
return {}
def consinitlp(self, constraints):
'''calls LP initialization method of constraint handler to separate all initial active constraints '''
return {}
def conssepalp(self, constraints, nusefulconss):
'''calls separator method of constraint handler to separate LP solution '''
return {}
def conssepasol(self, constraints, nusefulconss, solution):
'''calls separator method of constraint handler to separate given primal solution '''
return {}
def consenfolp(self, constraints, nusefulconss, solinfeasible):
'''calls enforcing method of constraint handler for LP solution for all constraints added'''
print("python error in consenfolp: this method needs to be implemented")
return {}
def consenforelax(self, solution, constraints, nusefulconss, solinfeasible):
'''calls enforcing method of constraint handler for a relaxation solution for all constraints added'''
print("python error in consenforelax: this method needs to be implemented")
return {}
def consenfops(self, constraints, nusefulconss, solinfeasible, objinfeasible):
'''calls enforcing method of constraint handler for pseudo solution for all constraints added'''
print("python error in consenfops: this method needs to be implemented")
return {}
def conscheck(self, constraints, solution, checkintegrality, checklprows, printreason, completely):
'''calls feasibility check method of constraint handler '''
print("python error in conscheck: this method needs to be implemented")
return {}
def consprop(self, constraints, nusefulconss, nmarkedconss, proptiming):
'''calls propagation method of constraint handler '''
return {}
def conspresol(self, constraints, nrounds, presoltiming,
nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds, nnewholes,
nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides, result_dict):
'''calls presolving method of constraint handler '''
return result_dict
def consresprop(self):
'''sets propagation conflict resolving method of constraint handler '''
return {}
def conslock(self, constraint, locktype, nlockspos, nlocksneg):
'''variable rounding lock method of constraint handler'''
print("python error in conslock: this method needs to be implemented")
return {}
def consactive(self, constraint):
'''sets activation notification method of constraint handler '''
pass
def consdeactive(self, constraint):
'''sets deactivation notification method of constraint handler '''
pass
def consenable(self, constraint):
'''sets enabling notification method of constraint handler '''
pass
def consdisable(self, constraint):
'''sets disabling notification method of constraint handler '''
pass
def consdelvars(self, constraints):
'''calls variable deletion method of constraint handler'''
pass
def consprint(self, constraint):
'''sets constraint display method of constraint handler '''
pass
def conscopy(self):
'''sets copy method of both the constraint handler and each associated constraint'''
pass
def consparse(self):
'''sets constraint parsing method of constraint handler '''
pass
def consgetvars(self, constraint):
'''sets constraint variable getter method of constraint handler'''
pass
def consgetnvars(self, constraint):
'''sets constraint variable number getter method of constraint handler '''
return {}
def consgetdivebdchgs(self):
'''calls diving solution enforcement callback of constraint handler, if it exists '''
pass
# local helper functions for the interface
cdef Conshdlr getPyConshdlr(SCIP_CONSHDLR* conshdlr):
cdef SCIP_CONSHDLRDATA* conshdlrdata
conshdlrdata = SCIPconshdlrGetData(conshdlr)
return <Conshdlr>conshdlrdata
cdef Constraint getPyCons(SCIP_CONS* cons):
cdef SCIP_CONSDATA* consdata
consdata = SCIPconsGetData(cons)
return <Constraint>consdata
cdef SCIP_RETCODE PyConshdlrCopy (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_Bool* valid):
return SCIP_OKAY
cdef SCIP_RETCODE PyConsFree (SCIP* scip, SCIP_CONSHDLR* conshdlr):
PyConshdlr = getPyConshdlr(conshdlr)
PyConshdlr.consfree()
Py_DECREF(PyConshdlr)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsInit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consinit(constraints)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsExit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexit(constraints)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsInitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consinitpre(constraints)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsExitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexitpre(constraints)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsInitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consinitsol(constraints)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsExitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool restart):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexitsol(constraints, restart)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsDelete (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, SCIP_CONSDATA** consdata):
PyConshdlr = getPyConshdlr(conshdlr)
PyCons = getPyCons(cons)
assert <Constraint>consdata[0] == PyCons
PyConshdlr.consdelete(PyCons)
consdata[0] = NULL
Py_DECREF(PyCons)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsTrans (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* sourcecons, SCIP_CONS** targetcons):
cdef Constraint PyTargetCons
PyConshdlr = getPyConshdlr(conshdlr)
PySourceCons = getPyCons(sourcecons)
result_dict = PyConshdlr.constrans(PySourceCons)
# create target (transform) constraint: if user doesn't return a constraint, copy PySourceCons
# otherwise use the created cons
if "targetcons" in result_dict:
PyTargetCons = result_dict.get("targetcons")
targetcons[0] = PyTargetCons.scip_cons
Py_INCREF(PyTargetCons)
else:
PY_SCIP_CALL(SCIPcreateCons(scip, targetcons, str_conversion(PySourceCons.name), conshdlr, <SCIP_CONSDATA*>PySourceCons,
PySourceCons.isInitial(), PySourceCons.isSeparated(), PySourceCons.isEnforced(), PySourceCons.isChecked(),
PySourceCons.isPropagated(), PySourceCons.isLocal(), PySourceCons.isModifiable(), PySourceCons.isDynamic(),
PySourceCons.isRemovable(), PySourceCons.isStickingAtNode()))
return SCIP_OKAY
cdef SCIP_RETCODE PyConsInitlp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool* infeasible):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consinitlp(constraints)
infeasible[0] = result_dict.get("infeasible", infeasible[0])
return SCIP_OKAY
cdef SCIP_RETCODE PyConsSepalp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.conssepalp(constraints, nusefulconss)
result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
return SCIP_OKAY
cdef SCIP_RETCODE PyConsSepasol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss,
SCIP_SOL* sol, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution()
solution.sol = sol
result_dict = PyConshdlr.conssepasol(constraints, nusefulconss, solution)
result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
return SCIP_OKAY
cdef SCIP_RETCODE PyConsEnfolp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss,
SCIP_Bool solinfeasible, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consenfolp(constraints, nusefulconss, solinfeasible)
result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
return SCIP_OKAY
cdef SCIP_RETCODE PyConsEnforelax (SCIP* scip, SCIP_SOL* sol, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_Bool solinfeasible, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution()
solution.sol = sol
result_dict = PyConshdlr.consenforelax(solution, constraints, nusefulconss, solinfeasible)
result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
return SCIP_OKAY
cdef SCIP_RETCODE PyConsEnfops (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss,
SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consenfops(constraints, nusefulconss, solinfeasible, objinfeasible)
result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
return SCIP_OKAY
cdef SCIP_RETCODE PyConsCheck (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_SOL* sol, SCIP_Bool checkintegrality,
SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool completely, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution()
solution.sol = sol
result_dict = PyConshdlr.conscheck(constraints, solution, checkintegrality, checklprows, printreason, completely)
result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
return SCIP_OKAY
cdef SCIP_RETCODE PyConsProp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, int nmarkedconss,
SCIP_PROPTIMING proptiming, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consprop(constraints, nusefulconss, nmarkedconss, proptiming)
result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
return SCIP_OKAY
cdef SCIP_RETCODE PyConsPresol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nrounds, SCIP_PRESOLTIMING presoltiming,
int nnewfixedvars, int nnewaggrvars, int nnewchgvartypes, int nnewchgbds, int nnewholes,
int nnewdelconss, int nnewaddconss, int nnewupgdconss, int nnewchgcoefs, int nnewchgsides,
int* nfixedvars, int* naggrvars, int* nchgvartypes, int* nchgbds, int* naddholes,
int* ndelconss, int* naddconss, int* nupgdconss, int* nchgcoefs, int* nchgsides, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
# dictionary for input/output parameters
result_dict = {}
result_dict["nfixedvars"] = nfixedvars[0]
result_dict["naggrvars"] = naggrvars[0]
result_dict["nchgvartypes"] = nchgvartypes[0]
result_dict["nchgbds"] = nchgbds[0]
result_dict["naddholes"] = naddholes[0]
result_dict["ndelconss"] = ndelconss[0]
result_dict["naddconss"] = naddconss[0]
result_dict["nupgdconss"] = nupgdconss[0]
result_dict["nchgcoefs"] = nchgcoefs[0]
result_dict["nchgsides"] = nchgsides[0]
result_dict["result"] = result[0]
PyConshdlr.conspresol(constraints, nrounds, presoltiming,
nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds, nnewholes,
nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides, result_dict)
result[0] = result_dict["result"]
nfixedvars[0] = result_dict["nfixedvars"]
naggrvars[0] = result_dict["naggrvars"]
nchgvartypes[0] = result_dict["nchgvartypes"]
nchgbds[0] = result_dict["nchgbds"]
naddholes[0] = result_dict["naddholes"]
ndelconss[0] = result_dict["ndelconss"]
naddconss[0] = result_dict["naddconss"]
nupgdconss[0] = result_dict["nupgdconss"]
nchgcoefs[0] = result_dict["nchgcoefs"]
nchgsides[0] = result_dict["nchgsides"]
return SCIP_OKAY
cdef SCIP_RETCODE PyConsResprop (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, SCIP_VAR* infervar, int inferinfo,
SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX* bdchgidx, SCIP_Real relaxedbd, SCIP_RESULT* result):
PyConshdlr = getPyConshdlr(conshdlr)
PyConshdlr.consresprop()
return SCIP_OKAY
cdef SCIP_RETCODE PyConsLock (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, SCIP_LOCKTYPE locktype, int nlockspos, int nlocksneg):
PyConshdlr = getPyConshdlr(conshdlr)
if cons == NULL:
PyConshdlr.conslock(None, locktype, nlockspos, nlocksneg)
else:
PyCons = getPyCons(cons)
PyConshdlr.conslock(PyCons, locktype, nlockspos, nlocksneg)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsActive (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons):
PyConshdlr = getPyConshdlr(conshdlr)
PyCons = getPyCons(cons)
PyConshdlr.consactive(PyCons)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsDeactive (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons):
PyConshdlr = getPyConshdlr(conshdlr)
PyCons = getPyCons(cons)
PyConshdlr.consdeactive(PyCons)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsEnable (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons):
PyConshdlr = getPyConshdlr(conshdlr)
PyCons = getPyCons(cons)
PyConshdlr.consenable(PyCons)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsDisable (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons):
PyConshdlr = getPyConshdlr(conshdlr)
PyCons = getPyCons(cons)
PyConshdlr.consdisable(PyCons)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsDelvars (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss):
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consdelvars(constraints)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsPrint (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, FILE* file):
PyConshdlr = getPyConshdlr(conshdlr)
PyCons = getPyCons(cons)
# TODO: pass file
PyConshdlr.consprint(PyCons)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsCopy (SCIP* scip, SCIP_CONS** cons, const char* name, SCIP* sourcescip, SCIP_CONSHDLR* sourceconshdlr,
SCIP_CONS* sourcecons, SCIP_HASHMAP* varmap, SCIP_HASHMAP* consmap, SCIP_Bool initial,
SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local,
SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode,
SCIP_Bool isglobal, SCIP_Bool* valid):
# TODO everything!
PyConshdlr = getPyConshdlr(sourceconshdlr)
PyConshdlr.conscopy()
valid[0] = False
return SCIP_OKAY
cdef SCIP_RETCODE PyConsParse (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** cons, const char* name, const char* str,
SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate,
SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable,
SCIP_Bool stickingatnode, SCIP_Bool* success):
# TODO everything!
PyConshdlr = getPyConshdlr(conshdlr)
PyConshdlr.consparse()
success[0] = False
return SCIP_OKAY
cdef SCIP_RETCODE PyConsGetvars (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, SCIP_VAR** vars, int varssize, SCIP_Bool* success):
# TODO
PyConshdlr = getPyConshdlr(conshdlr)
PyCons = getPyCons(cons)
PyConshdlr.consgetvars(PyCons)
success[0] = False
return SCIP_OKAY
cdef SCIP_RETCODE PyConsGetnvars (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, int* nvars, SCIP_Bool* success):
PyConshdlr = getPyConshdlr(conshdlr)
PyCons = getPyCons(cons)
result_dict = PyConshdlr.consgetnvars(PyCons)
nvars[0] = result_dict.get("nvars", 0)
success[0] = result_dict.get("success", False)
return SCIP_OKAY
cdef SCIP_RETCODE PyConsGetdivebdchgs (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_DIVESET* diveset, SCIP_SOL* sol,
SCIP_Bool* success, SCIP_Bool* infeasible):
# TODO
PyConshdlr = getPyConshdlr(conshdlr)
PyConshdlr.consgetdivebdchgs()
success[0] = False
infeasible[0] = False
return SCIP_OKAY