Scippy

SCIP

Solving Constraint Integer Programs

scip_certificate.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file scip_certificate.c
26 * @brief public methods for certified solving
27 * @author Leon Eifler
28 * @author Ambros Gleixner
29 *
30 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
31 */
32
33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34
35#include <ctype.h>
36#include <stdarg.h>
37#include <assert.h>
38#include <string.h>
39#ifndef _WIN32
40#include <strings.h> /*lint --e{766}*/
41#endif
42
43
44#include "lpi/lpi.h"
45#include "scip/exprinterpret.h"
46#include "scip/nlpi.h"
47#include "scip/benders.h"
48#include "scip/benderscut.h"
49#include "scip/branch.h"
51#include "scip/certificate.h"
52#include "scip/clock.h"
53#include "scip/compr.h"
54#include "scip/concsolver.h"
55#include "scip/concurrent.h"
56#include "scip/conflict.h"
57#include "scip/conflictstore.h"
58#include "scip/cons.h"
59#include "scip/cons_linear.h"
60#include "scip/cutpool.h"
61#include "scip/cuts.h"
62#include "scip/debug.h"
63#include "scip/def.h"
64#include "scip/dialog.h"
65#include "scip/dialog_default.h"
66#include "scip/disp.h"
67#include "scip/event.h"
68#include "scip/heur.h"
69#include "scip/heur_ofins.h"
70#include "scip/heur_reoptsols.h"
72#include "scip/heuristics.h"
73#include "scip/history.h"
74#include "scip/implics.h"
75#include "scip/interrupt.h"
76#include "scip/lp.h"
78#include "scip/mem.h"
80#include "scip/misc.h"
81#include "scip/nlp.h"
82#include "scip/nodesel.h"
83#include "scip/paramset.h"
84#include "scip/presol.h"
85#include "scip/presolve.h"
86#include "scip/pricer.h"
87#include "scip/pricestore.h"
88#include "scip/primal.h"
89#include "scip/prob.h"
90#include "scip/prop.h"
91#include "scip/reader.h"
92#include "scip/relax.h"
93#include "scip/reopt.h"
94#include "scip/retcode.h"
95#include "scip/sepastoreexact.h"
96#include "scip/scipbuildflags.h"
98#include "scip/scipgithash.h"
99#include "scip/sepa.h"
100#include "scip/sepastore.h"
101#include "scip/set.h"
102#include "scip/sol.h"
103#include "scip/solve.h"
104#include "scip/stat.h"
105#include "scip/syncstore.h"
106#include "scip/table.h"
107#include "scip/tree.h"
108#include "scip/var.h"
109#include "scip/visual.h"
110#include "xml/xml.h"
111
113#include "scip/scip_cons.h"
114#include "scip/scip_copy.h"
115#include "scip/scip_general.h"
116#include "scip/scip_mem.h"
117#include "scip/scip_message.h"
118#include "scip/scip_nlp.h"
119#include "scip/scip_numerics.h"
120#include "scip/scip_param.h"
121#include "scip/scip_prob.h"
122#include "scip/scip_sol.h"
123#include "scip/scip_solve.h"
125#include "scip/scip_var.h"
126
127#include "scip/pub_cons.h"
128#include "scip/pub_fileio.h"
129#include "scip/pub_message.h"
130#include "scip/pub_misc.h"
131#include "scip/pub_sol.h"
132#include "scip/pub_var.h"
133#include "scip/pub_lpexact.h"
135#include "scip/struct_lpexact.h"
136
137
138/* In debug mode, we include the SCIP's structure in scip.c, such that no one can access
139 * this structure except the interface methods in scip.c.
140 * In optimized mode, the structure is included in scip.h, because some of the methods
141 * are implemented as defines for performance reasons (e.g. the numerical comparisons)
142 */
143#ifndef NDEBUG
144#include "scip/struct_scip.h"
145#endif
146
147/** returns the sense of an inequality */
148static
150 SCIP_Bool isgreaterthan /**< is the inequality a greater than inequality? */
151 )
152{
153 return isgreaterthan ? 'G' : 'L';
154}
155
156/** returns whether certificate output is activated
157 *
158 * @todo add a flag set->certificate_enabled to store the return value of this method for easier and faster access
159 */
161 SCIP* scip /**< certificate information */
162 )
163{
164 assert(scip != NULL);
165 assert(scip->set != NULL);
166 assert(scip->stat != NULL);
167
168 if( !(scip->set->exact_enable) )
169 return FALSE;
170 else if( scip->set->stage == SCIP_STAGE_SOLVING )
171 return SCIPcertificateIsEnabled(scip->stat->certificate);
172 else
173 return !(scip->set->certificate_filename[0] == '-' && scip->set->certificate_filename[1] == '\0');
174}
175
176/** should the certificate track bound changes?
177 *
178 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
179 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
180 *
181 * @pre This method can be called if @p scip is in one of the following stages:
182 * - \ref SCIP_STAGE_SOLVING
183 *
184 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
185 */
187 SCIP* scip /**< SCIP data structure */
188 )
189{
190 return SCIPisCertified(scip) && scip->set->stage >= SCIP_STAGE_INITSOLVE && !SCIPinProbing(scip);
191}
192
193/** prints constraint to certificate
194 *
195 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
196 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
197 *
198 * @pre This method can be called if @p scip is in one of the following stages:
199 * - \ref SCIP_STAGE_INITSOLVE
200 *
201 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
202 */
204 SCIP* scip, /**< certificate information */
205 SCIP_Bool isorigfile, /**< should the original solution be printed or in transformed space */
206 const char* consname, /**< name of the constraint */
207 const char sense, /**< sense of the constraint, i.e., G, L, or E */
208 SCIP_RATIONAL* side, /**< left/right-hand side */
209 int len, /**< number of nonzeros */
210 int* ind, /**< index array */
211 SCIP_RATIONAL** val /**< coefficient array */
212 )
213{
214 assert(scip != NULL);
215 assert(scip->stat != NULL);
216 assert(scip->stat->certificate != NULL);
217
219
220 SCIP_CALL( SCIPcertificatePrintCons(scip->stat->certificate, isorigfile, consname, sense, side, len, ind, val) );
221
222 return SCIP_OKAY;
223}
224
225/** prints activity bound to proof section
226 *
227 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
228 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
229 *
230 * @pre This method can be called if @p scip is in one of the following stages:
231 * - \ref SCIP_STAGE_SOLVING
232 *
233 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
234 */
236 SCIP* scip, /**< SCIP data structure */
237 const char* linename, /**< name of the unsplitting line */
238 SCIP_BOUNDTYPE boundtype, /**< type of bound (upper/lower) */
239 SCIP_Real newbound, /**< pointer to lower bound on the objective, NULL indicating infeasibility */
240 SCIP_Bool ismaxactivity, /**< TRUE for maxactivity, FALSE for minactivity */
241 SCIP_CONS* constraint, /**< the constraint */
242 SCIP_VAR* variable, /**< the variable */
243 SCIP_ROWEXACT* row, /**< the corresponding row, or NULL if constraint has no row representation */
244 SCIP_RATIONAL** vals, /**< value array */
245 SCIP_RATIONAL* lhs, /**< lhs of the constraint */
246 SCIP_RATIONAL* rhs, /**< rhs of the constraint */
247 SCIP_VAR** vars, /**< variable array */
248 int nvars /**< number of values */
249 )
250{
251 /* It would be more efficient if we could do this all in fp artihmetic. However, this is not trivial because the
252 * translations between aggregate variables need to be done exactly.
253 */
254 SCIP_RATIONAL* newboundex;
255
256 SCIP_CALL( SCIPcheckStage(scip, "SCIPcertifyActivityVarBound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
257
259 SCIPrationalSetReal(newboundex, newbound);
260 (void) SCIPcertifyActivityVarBoundExact(scip, linename, boundtype,
261 newboundex, ismaxactivity, constraint, variable, row, vals, lhs, rhs, vars, nvars);
263
264 return SCIP_OKAY;
265}
266
267/** prints activity bound to proof section
268 *
269 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
270 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
271 *
272 * @pre This method can be called if @p scip is in one of the following stages:
273 * - \ref SCIP_STAGE_SOLVING
274 *
275 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
276 */
278 SCIP* scip, /**< SCIP data structure */
279 const char* linename, /**< name of the unsplitting line */
280 SCIP_BOUNDTYPE boundtype, /**< type of bound (upper/lower) */
281 SCIP_RATIONAL* newbound, /**< pointer to lower bound on the objective, NULL indicating infeasibility */
282 SCIP_Bool ismaxactivity, /**< TRUE for maxactivity, FALSE for minactivity */
283 SCIP_CONS* constraint, /**< the constraint */
284 SCIP_VAR* variable, /**< the variable */
285 SCIP_ROWEXACT* row, /**< the corresponding row, or NULL if constraint has no row representation */
286 SCIP_RATIONAL** vals, /**< value array */
287 SCIP_RATIONAL* lhs, /**< lhs of the constraint */
288 SCIP_RATIONAL* rhs, /**< rhs of the constraint */
289 SCIP_VAR** vars, /**< variable array */
290 int nvars /**< number of values */
291 )
292{
293 SCIP_CERTIFICATE* certificate;
294 SCIP_Longint res;
296 SCIP_RATIONAL* val;
297 SCIP_Bool upperboundcontribution;
298
299 SCIP_CALL( SCIPcheckStage(scip, "SCIPcertifyActivityVarBoundExact", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
300
301 assert(scip != NULL);
302 assert(scip->stat != NULL);
303 assert(scip->stat != NULL);
304 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(constraint)), "exactlinear") == 0);
305
306 certificate = scip->stat->certificate;
307
308 switch( variable->varstatus )
309 {
313 SCIPABORT();
314 return SCIP_ERROR;
316
317 SCIPrationalMultReal(newbound, newbound, -1.0);
318 assert( SCIPvarGetNegationConstant(variable) == 1 );
319 SCIPrationalAddReal(newbound, newbound, 1.0);
322 newbound, ismaxactivity, constraint, variable->negatedvar, row, vals, lhs, rhs, vars, nvars);
323 SCIPrationalAddReal(newbound, newbound, -1.0);
324 SCIPrationalMultReal(newbound, newbound, -1.0);
325 return ret;
326 break;
328 SCIPrationalAddProdReal(newbound, variable->exactdata->aggregate.constant, -1.0);
329 SCIPrationalDiv(newbound, newbound, variable->exactdata->aggregate.scalar);
332 newbound, ismaxactivity, constraint, variable->data.aggregate.var, row, vals, lhs, rhs, vars, nvars);
333 SCIPrationalMult(newbound, newbound, variable->exactdata->aggregate.scalar);
334 return ret;
335 break;
337 break;
338 default:
339 SCIPABORT();
340 return SCIP_ERROR;
341 }
342
343 /* check if certificate output should be created */
344 if( certificate->transfile == NULL )
345 return ret;
346
347 certificate->indexcounter++;
348
349 if( linename == NULL )
350 {
351 SCIPcertificatePrintProofMessage(certificate, "ACT_L%d ", certificate->indexcounter - 1);
352 }
353 else
354 {
355 SCIPcertificatePrintProofMessage(certificate, "%s ", linename);
356 }
357
358 /* find the correct value in the constraint */
359 val = NULL;
360 for( int i = 0; i < nvars; i++ )
361 {
362 if( vars[i] == variable )
363 {
364 val = vals[i];
365 break;
366 }
367 }
368
369 assert(val != NULL);
370
371 /* Do we need an upper bound on the contribution val[i]*x_i? (otherwise a lowerbound) */
372 upperboundcontribution = (boundtype == SCIP_BOUNDTYPE_UPPER) == SCIPrationalIsPositive(val);
373 SCIPcertificatePrintProofMessage(certificate, "%c ", getInequalitySense(upperboundcontribution));
374
375 /* new bound = -newbound * val for now, we print a second line where we scale with 1/val */
376 SCIPrationalMult(newbound, newbound, val);
377 SCIPrationalNegate(newbound, newbound);
378 SCIP_CALL_ABORT( SCIPcertificatePrintProofRational(certificate, newbound) );
379
380 /* print coeffictent of variable -> val */
381 SCIPrationalNegate(newbound, newbound);
382 SCIPrationalDiv(newbound, newbound, val);
383 SCIPcertificatePrintProofMessage(certificate, " 1 %d ", SCIPvarGetCertificateIndex(variable));
384
385 /* negate val, print it and reset it again */
386 SCIPrationalNegate(val, val);
388 SCIPrationalNegate(val, val);
389
390 if(row != NULL)
391 res = SCIPcertificateGetRowIndex(certificate, row, !ismaxactivity);
392 else
393 res = SCIPcertificateGetConsIndex(certificate, constraint, lhs, rhs, !ismaxactivity);
394
395 SCIPcertificatePrintProofMessage(certificate, " { lin %d %d -1", nvars, res);
396
397 /* print all other variables with their correct bounds */
398 for( int i = 0; i < nvars; i++ )
399 {
400 SCIP_VAR* ivar;
401 bool is_upper_bound;
402 SCIP_Longint certificateindex;
403
404 assert(!SCIPrationalIsAbsInfinity(vals[i]));
405
406 ivar = vars[i];
407 if( ivar == variable )
408 continue;
409
410 is_upper_bound = upperboundcontribution != SCIPrationalIsPositive(vals[i]);
411
412 assert(upperboundcontribution != ismaxactivity);
413
414 certificateindex = is_upper_bound ? SCIPvarGetUbCertificateIndexLocal(ivar) : SCIPvarGetLbCertificateIndexLocal(ivar);
415 SCIPcertificatePrintProofMessage(certificate, " %d ", certificateindex);
416 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, vals[i]) );
417 }
418 SCIPcertificatePrintProofMessage(certificate, " } -1\n");
419
420 /* now scale with 1/val */
421 certificate->indexcounter++;
422 SCIPcertificatePrintProofMessage(certificate, "ACT_L%d %c ", certificate->indexcounter - 1, getInequalitySense(boundtype == SCIP_BOUNDTYPE_LOWER));
423 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, newbound) );
424 SCIPcertificatePrintProofMessage(certificate, " 1 %d 1 { lin 1 %d ", SCIPvarGetCertificateIndex(variable), certificate->indexcounter - 2);
425 SCIPrationalInvert(val, val);
426 SCIPrationalNegate(val, val);
427 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, val) );
428
429 /* Return val to its original state: */
430 SCIPrationalNegate(val, val);
431 SCIPrationalInvert(val, val);
432 SCIPcertificatePrintProofMessage(certificate, " } -1\n", SCIPvarGetCertificateIndex(variable), certificate->indexcounter - 2);
433
434 /* if variable is integer, round the new bound */
436 {
437 certificate->indexcounter++;
438
439 SCIPcertificatePrintProofMessage(certificate, "ACT_R%d %c ", certificate->indexcounter - 1, getInequalitySense(boundtype == SCIP_BOUNDTYPE_LOWER));
441
442 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, newbound) );
443
444 SCIPcertificatePrintProofMessage(certificate, " 1 %d 1", SCIPvarGetCertificateIndex(variable));
445 SCIPcertificatePrintProofMessage(certificate, " { rnd 1 %d 1 } -1\n", certificate->indexcounter - 2);
446 }
447
448#ifndef NDEBUG
449 certificate->lastinfo->isbound = TRUE;
450 certificate->lastinfo->boundtype = boundtype;
451 certificate->lastinfo->varindex = SCIPvarGetCertificateIndex(variable);
452 certificate->lastinfo->isglobal = FALSE;
453 certificate->lastinfo->certificateindex = certificate->indexcounter - 1;
454 SCIPrationalSetRational(certificate->lastinfo->boundval, newbound);
455#endif
456 (void) SCIPcertificateSetLastBoundIndex(certificate, certificate->indexcounter - 1);
457
458 return SCIP_OKAY;
459}
460
461/** prints activity conflict to certificate file
462 *
463 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
464 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
465 *
466 * @pre This method can be called if @p scip is in one of the following stages:
467 * - \ref SCIP_STAGE_SOLVING
468 *
469 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
470 */
472 SCIP* scip, /**< SCIP data structure */
473 SCIP_CONS* cons, /**< constraint */
474 SCIP_ROWEXACT* row, /**< corresponding row, or NULL if constraint does not have representation as row */
475 SCIP_RATIONAL* lhs, /**< lhs of the constraint */
476 SCIP_RATIONAL* rhs, /**< rhs of the constraint */
477 int nvals, /**< number of values */
478 SCIP_RATIONAL** vals, /**< value array */
479 SCIP_VAR** vars, /**< variable array */
480 SCIP_RATIONAL* diff, /**< difference between min/max activity as lhs/rhs */
481 SCIP_Bool userhs /**< is rhs or lhs used */
482 )
483{
484 SCIP_CERTIFICATE* certificate;
485 SCIP_Longint conscertificateindex;
486
487 SCIP_CALL( SCIPcheckStage(scip, "SCIPcertifyActivityConflict", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
488
489 if( !SCIPisCertified(scip) )
490 return SCIP_OKAY;
491
492 certificate = SCIPgetCertificate(scip);
493
494 if( row != NULL )
495 conscertificateindex = SCIPcertificateGetRowIndex(SCIPgetCertificate(scip), row, userhs);
496 else
497 conscertificateindex = SCIPcertificateGetConsIndex(certificate, cons, lhs, rhs, userhs);
498
499 assert(conscertificateindex != LONG_MAX);
500
501 SCIPcertificatePrintProofMessage(certificate, "ActivityConflict%d ", certificate->indexcounter);
502 SCIPcertificatePrintProofMessage(certificate, userhs ? "G " : "L ");
503
504 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, diff) );
505 SCIPcertificatePrintProofMessage(certificate, " 0 { lin %d %d -1", nvals + 1, conscertificateindex);
506 for( int i = 0; i < nvals; i++ )
507 {
508 SCIP_VAR* var;
509 bool is_upper_bound;
510 SCIP_Longint certificateindex;
511 var = row == NULL ? vars[i] : row->cols[i]->var;
512 is_upper_bound = userhs != SCIPrationalIsPositive(vals[i]);
513 certificateindex = is_upper_bound ? SCIPvarGetUbCertificateIndexLocal(var) : SCIPvarGetLbCertificateIndexLocal(var);
514 SCIPcertificatePrintProofMessage(certificate, " %d ", certificateindex);
515 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, vals[i]) );
516 }
517 SCIPcertificatePrintProofMessage(certificate, " } -1\n");
518
520 certificate->indexcounter++;
521 return SCIP_OKAY;
522}
523
524/** adds aggregation information to certificate for one row
525 *
526 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
527 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
528 *
529 * @pre This method can be called if @p scip is in one of the following stages:
530 * - \ref SCIP_STAGE_SOLVING
531 *
532 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
533 */
535 SCIP* scip, /**< SCIP data structure */
536 SCIP_AGGRROW* aggrrow, /**< agrrrow that results from the aggregation */
537 SCIP_ROW** aggrrows, /**< array of rows used fo the aggregation */
538 SCIP_Real* weights, /**< array of weights */
539 int naggrrows, /**< length of the arrays */
540 SCIP_ROW** negslackrows, /**< array of rows that are added implicitly with negative slack */
541 SCIP_Real* negslackweights, /**< array of negative slack weights */
542 int nnegslackrows /**< length of the negative slack array */
543 )
544{
545 assert(scip != NULL);
546 assert(scip->stat != NULL);
547
548 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCertificateAggrInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
549
550 SCIP_CALL( SCIPcertificateNewAggrInfo(scip, aggrrow, aggrrows, weights, naggrrows, negslackrows, negslackweights, nnegslackrows) );
551
552 return SCIP_OKAY;
553}
554
555/** stores the active aggregation information in the certificate data structures for a row
556 *
557 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
558 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
559 *
560 * @pre This method can be called if @p scip is in one of the following stages:
561 * - \ref SCIP_STAGE_SOLVING
562 *
563 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
564 */
566 SCIP* scip, /**< SCIP data structure */
567 SCIP_ROW* row /**< row that aggregation-info is stored for */
568 )
569{
570 SCIP_CERTIFICATE* certificate;
571 SCIP_AGGREGATIONINFO* aggrinfo;
572
573 SCIP_CALL( SCIPcheckStage(scip, "SCIPstoreCertificateActiveAggrInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
574
576 return SCIP_OKAY;
577
578 certificate = SCIPgetCertificate(scip);
579
580 assert(certificate != NULL);
581 assert(certificate->workingaggrinfo);
582
583 aggrinfo = certificate->aggrinfo[certificate->naggrinfos - 1];
584 certificate->workingaggrinfo = FALSE;
585
586 assert(aggrinfo != NULL);
587
588 SCIP_CALL( SCIPhashmapSetImage(certificate->aggrinfohash, (void*) row, (void*) aggrinfo) );
589
590 return SCIP_OKAY;
591}
592
593/** frees the active aggregation information
594 *
595 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
596 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
597 *
598 * @pre This method can be called if @p scip is in one of the following stages:
599 * - \ref SCIP_STAGE_SOLVING
600 *
601 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
602 */
604 SCIP* scip /**< SCIP data structure */
605 )
606{
607 SCIP_CERTIFICATE* certificate;
608 SCIP_AGGREGATIONINFO* aggrinfo;
609
610 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeCertificateActiveAggrInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
611
613 return SCIP_OKAY;
614
615 certificate = SCIPgetCertificate(scip);
616
617 assert(certificate != NULL);
618
619 /* if the mirinfo is used it gets tranformed into sparse format, don't free it in that case */
620 if( !certificate->workingaggrinfo )
621 return SCIP_OKAY;
622
623 aggrinfo = certificate->aggrinfo[certificate->naggrinfos - 1];
624
625 assert(aggrinfo != NULL);
626
627 SCIP_CALL( SCIPcertificateFreeAggrInfo(scip->set, certificate, scip->lp, aggrinfo, NULL) );
628
629 certificate->workingaggrinfo = FALSE;
630
631 return SCIP_OKAY;
632}
633
634/** adds aggregation information to certificate for one row
635 *
636 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
637 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
638 *
639 * @pre This method can be called if @p scip is in one of the following stages:
640 * - \ref SCIP_STAGE_SOLVING
641 *
642 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
643 */
645 SCIP* scip /**< SCIP data structure */
646 )
647{
648 assert(scip != NULL);
649 assert(scip->stat != NULL);
650
651 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCertificateMirInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
652
654
655 return SCIP_OKAY;
656}
657
658/** stores the active mir information in the certificate data structures for a row
659 *
660 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
661 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
662 *
663 * @pre This method can be called if @p scip is in one of the following stages:
664 * - \ref SCIP_STAGE_SOLVING
665 *
666 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
667 */
669 SCIP* scip, /**< SCIP data structure */
670 SCIP_ROW* row /**< row that mirinfo is stored for */
671 )
672{
673 SCIP_CERTIFICATE* certificate;
674 SCIP_MIRINFO* mirinfo;
675 int i;
676 int csplit;
677
678 SCIP_CALL( SCIPcheckStage(scip, "SCIPstoreCertificateActiveMirInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
679
681 return SCIP_OKAY;
682
683 certificate = SCIPgetCertificate(scip);
684
685 assert(certificate != NULL);
686 assert(certificate->workingmirinfo);
687
688 certificate->workingmirinfo = FALSE;
689
690 mirinfo = certificate->mirinfo[certificate->nmirinfos - 1];
691
692 assert(mirinfo != NULL);
693
694 assert(mirinfo->nsplitvars == SCIPgetNVars(scip));
695
696 csplit = 0;
697
698 /* make the mirinfo sparse again */
699 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(mirinfo->varinds), mirinfo->nsplitvars) );
700
701 for( i = 0; i < mirinfo->nsplitvars; i++ )
702 {
703 if( mirinfo->splitcoefficients[i] != 0.0 || mirinfo->upperused[i] || mirinfo->localbdused[i] )
704 {
705 mirinfo->splitcoefficients[csplit] = mirinfo->splitcoefficients[i];
706 mirinfo->upperused[csplit] = mirinfo->upperused[i];
707 mirinfo->localbdused[csplit] = mirinfo->localbdused[i];
708 mirinfo->varinds[csplit] = i;
709 csplit++;
710 }
711 }
712
713 mirinfo->nsplitvars = csplit;
718
726
727 SCIP_CALL( SCIPhashmapSetImage(certificate->mirinfohash, (void*) row, (void*) mirinfo) );
728
729 return SCIP_OKAY;
730}
731
732/** print MIR cut to certificate file
733 *
734 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
735 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
736 *
737 * @pre This method can be called if @p scip is in one of the following stages:
738 * - \ref SCIP_STAGE_SOLVING
739 *
740 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
741 */
743 SCIP* scip, /**< SCIP data structure */
744 SCIP_ROW* row /**< row that needs to be certified */
745 )
746{
747 SCIP_CERTIFICATE* certificate;
748
750
752 return SCIP_OKAY;
753
754 certificate = SCIPgetCertificate(scip);
755 SCIP_CALL( SCIPcertificatePrintMirCut(scip->set, scip->lp, certificate, scip->transprob, row, 'L') );
756
757 return SCIP_OKAY;
758}
759
760/** frees the active mir information
761 *
762 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
763 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
764 *
765 * @pre This method can be called if @p scip is in one of the following stages:
766 * - \ref SCIP_STAGE_SOLVING
767 *
768 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
769 */
771 SCIP* scip /**< SCIP data structure */
772 )
773{
774 SCIP_CERTIFICATE* certificate;
775 SCIP_MIRINFO* mirinfo;
776 int i;
777
778 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeCertificateActiveMirInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
779
781 return SCIP_OKAY;
782
783 certificate = SCIPgetCertificate(scip);
784
785 assert(certificate != NULL);
786
787 if( certificate->nmirinfos == 0 )
788 return SCIP_OKAY;
789
790 mirinfo = certificate->mirinfo[certificate->nmirinfos - 1];
791
792 assert(mirinfo != NULL);
793
794 /* if the mirinfo is used it gets tranformed into sparse format, don't free it in that case */
795 if( !certificate->workingmirinfo )
796 return SCIP_OKAY;
797
798 for(i = 0; i < mirinfo->nslacks; ++i)
799 {
800 SCIP_CALL( SCIPreleaseRow(scip, &(mirinfo->slackrows[i])) );
801 }
802
803 assert(mirinfo->varinds == NULL);
804
807
818 SCIPfreeBlockMemory(scip, &mirinfo);
819 certificate->nmirinfos--;
820 certificate->workingmirinfo = FALSE;
821
822 return SCIP_OKAY;
823}
internal methods for Benders' decomposition cuts
internal methods for branching rules and branching candidate storage
nodereopt branching rule
SCIP_CERTIFICATE * SCIPgetCertificate(SCIP *scip)
SCIP_Longint SCIPcertificateGetRowIndex(SCIP_CERTIFICATE *certificate, SCIP_ROWEXACT *row, SCIP_Bool rhs)
SCIP_RETCODE SCIPcertificatePrintMirCut(SCIP_SET *set, SCIP_LP *lp, SCIP_CERTIFICATE *certificate, SCIP_PROB *prob, SCIP_ROW *row, const char sense)
SCIP_RETCODE SCIPcertificateUpdateParentData(SCIP_CERTIFICATE *certificate, SCIP_NODE *node, SCIP_Longint fileindex, SCIP_RATIONAL *newbound)
SCIP_RETCODE SCIPcertificateSetLastBoundIndex(SCIP_CERTIFICATE *certificate, SCIP_Longint index)
SCIP_RETCODE SCIPcertificatePrintProofRational(SCIP_CERTIFICATE *certificate, SCIP_RATIONAL *val)
SCIP_Bool SCIPcertificateIsEnabled(SCIP_CERTIFICATE *certificate)
SCIP_Longint SCIPcertificateGetConsIndex(SCIP_CERTIFICATE *certificate, SCIP_CONS *cons, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool useRhs)
SCIP_RETCODE SCIPcertificateFreeAggrInfo(SCIP_SET *set, SCIP_CERTIFICATE *certificate, SCIP_LP *lp, SCIP_AGGREGATIONINFO *aggrinfo, SCIP_ROW *row)
SCIP_RETCODE SCIPcertificatePrintCons(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, const char *consname, const char sense, SCIP_RATIONAL *side, int len, int *ind, SCIP_RATIONAL **val)
void SCIPcertificatePrintProofMessage(SCIP_CERTIFICATE *certificate, const char *formatstr,...)
SCIP_RETCODE SCIPcertificateNewAggrInfo(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_ROW **aggrrows, SCIP_Real *weights, int naggrrows, SCIP_ROW **negslackrows, SCIP_Real *negslackweights, int nnegslackrows)
SCIP_RETCODE SCIPcertificateNewMirInfo(SCIP *scip)
methods for certificate output
internal methods for clocks and timing issues
internal methods for tree compressions
datastructures for concurrent solvers
helper functions for concurrent scip solvers
internal methods for conflict analysis
internal methods for storing conflicts
internal methods for constraints and constraint handlers
Constraint handler for linear constraints in their most general form, .
internal methods for storing cuts in a cut pool
methods for the aggregation rows
methods for debugging
#define SCIPcheckStage(scip, method, init, problem, transforming, transformed, initpresolve, presolving, exitpresolve, presolved, initsolve, solving, solved, exitsolve, freetrans, freescip)
Definition: debug.h:364
common defines and data types used in all packages of SCIP
#define NULL
Definition: def.h:248
#define SCIP_Longint
Definition: def.h:141
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL_ABORT(x)
Definition: def.h:334
#define SCIPABORT()
Definition: def.h:327
#define SCIP_CALL(x)
Definition: def.h:355
internal methods for user interface dialog
default user interface dialog
internal methods for displaying runtime statistics
internal methods for managing events
methods to interpret (evaluate) an expression "fast"
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2246
SCIP_RETCODE SCIPhashmapSetImage(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3366
SCIP_RETCODE SCIPcertifyCons(SCIP *scip, SCIP_Bool isorigfile, const char *consname, const char sense, SCIP_RATIONAL *side, int len, int *ind, SCIP_RATIONAL **val)
SCIP_RETCODE SCIPaddCertificateMirInfo(SCIP *scip)
SCIP_RETCODE SCIPfreeCertificateActiveMirInfo(SCIP *scip)
SCIP_RETCODE SCIPstoreCertificateActiveAggrInfo(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPcertifyActivityVarBound(SCIP *scip, const char *linename, SCIP_BOUNDTYPE boundtype, SCIP_Real newbound, SCIP_Bool ismaxactivity, SCIP_CONS *constraint, SCIP_VAR *variable, SCIP_ROWEXACT *row, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_VAR **vars, int nvars)
SCIP_RETCODE SCIPcertifyActivityConflict(SCIP *scip, SCIP_CONS *cons, SCIP_ROWEXACT *row, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, int nvals, SCIP_RATIONAL **vals, SCIP_VAR **vars, SCIP_RATIONAL *diff, SCIP_Bool userhs)
SCIP_Bool SCIPisCertified(SCIP *scip)
SCIP_RETCODE SCIPcertifyActivityVarBoundExact(SCIP *scip, const char *linename, SCIP_BOUNDTYPE boundtype, SCIP_RATIONAL *newbound, SCIP_Bool ismaxactivity, SCIP_CONS *constraint, SCIP_VAR *variable, SCIP_ROWEXACT *row, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_VAR **vars, int nvars)
SCIP_RETCODE SCIPaddCertificateAggrInfo(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_ROW **aggrrows, SCIP_Real *weights, int naggrrows, SCIP_ROW **negslackrows, SCIP_Real *negslackweights, int nnegslackrows)
SCIP_Bool SCIPshouldCertificateTrackBounds(SCIP *scip)
SCIP_RETCODE SCIPfreeCertificateActiveAggrInfo(SCIP *scip)
SCIP_RETCODE SCIPcertifyMirCut(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPstoreCertificateActiveMirInfo(SCIP *scip, SCIP_ROW *row)
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4316
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8409
SCIP_Bool SCIPisExact(SCIP *scip)
Definition: scip_exact.c:193
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
BMS_BUFMEM * SCIPbuffer(SCIP *scip)
Definition: scip_mem.c:72
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:98
void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1066
void SCIPrationalInvert(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
Definition: rational.cpp:1323
void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
Definition: rational.cpp:461
void SCIPrationalRoundInteger(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_ROUNDMODE_RAT roundmode)
Definition: rational.cpp:2158
void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1132
SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1680
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition: rational.cpp:603
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:473
SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
Definition: rational.cpp:1640
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:123
void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
Definition: rational.cpp:569
SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
Definition: rational.cpp:1691
void SCIPrationalNegate(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
Definition: rational.cpp:1297
void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
Definition: rational.cpp:1097
void SCIPrationalAddReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
Definition: rational.cpp:961
void SCIPrationalAddProdReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
Definition: rational.cpp:1210
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1508
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_Longint SCIPvarGetUbCertificateIndexLocal(SCIP_VAR *var)
Definition: var.c:25188
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:23889
int SCIPvarGetCertificateIndex(SCIP_VAR *var)
Definition: var.c:25098
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:23453
SCIP_Longint SCIPvarGetLbCertificateIndexLocal(SCIP_VAR *var)
Definition: var.c:25176
internal methods for primal heuristics
OFINS - Objective Function Induced Neighborhood Search - a primal heuristic for reoptimization.
reoptsols primal heuristic
trivialnegation primal heuristic
methods commonly used by primal heuristics
internal methods for branching and inference history
methods for implications, variable bounds, and cliques
methods for catching the user CTRL-C interrupt
internal methods for LP management
safe exact rational bounding methods
interface methods for specific LP solvers
methods for block memory pools and memory buffers
default message handler
internal miscellaneous methods
internal methods for NLP management
internal methods for NLP solver interfaces
internal methods for node selectors and node priority queues
internal methods for handling parameter settings
internal methods for presolvers
methods commonly used for presolving
internal methods for variable pricers
internal methods for storing priced variables
internal methods for collecting primal CIP solutions and primal informations
internal methods for storing and manipulating the main problem
internal methods for propagators
public methods for managing constraints
wrapper functions to map file i/o to standard or zlib file i/o
public methods for LP management
public methods for message output
public data structures and miscellaneous methods
public methods for primal CIP solutions
public methods for problem variables
internal methods for input file readers
internal methods for relaxators
data structures and methods for collecting reoptimization information
internal methods for return codes for SCIP methods
static char getInequalitySense(SCIP_Bool isgreaterthan)
public methods for certified solving
public methods for constraint handler plugins and constraints
public methods for problem copies
general public methods
public methods for memory management
public methods for message handling
public methods for nonlinear relaxation
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for solutions
public solving methods
public methods for querying solving statistics
public methods for SCIP variables
build flags methods
register additional core functionality that is designed as plugins
git hash methods
internal methods for separators
internal methods for storing separated cuts
internal methods for storing separated exact cuts
internal methods for global SCIP settings
internal methods for storing primal CIP solutions
internal methods for main solving loop and node processing
internal methods for Benders' decomposition
internal methods for problem statistics
SCIP_RATIONAL * scalar
Definition: struct_var.h:218
SCIP_RATIONAL * constant
Definition: struct_var.h:219
SCIP_VAR * var
Definition: struct_var.h:212
SCIP_RATIONAL * boundval
SCIP_Longint indexcounter
SCIP_Longint nmirinfos
SCIP_MIRINFO ** mirinfo
SCIP_CERTIFICATEBOUND * lastinfo
SCIP_HASHMAP * mirinfohash
SCIP_Longint naggrinfos
SCIP_AGGREGATIONINFO ** aggrinfo
SCIP_HASHMAP * aggrinfohash
SCIP_VAR * var
SCIP_Real * slackscale
SCIP_Real * slackcoefficients
SCIP_RATIONAL * frac
SCIP_ROW ** slackrows
SCIP_Real * slackweight
SCIP_Bool * upperused
SCIP_Real * splitcoefficients
SCIP_RATIONAL * rhs
SCIP_Real * slackusedcoef
SCIP_Bool * localbdused
SCIP_Bool * slackroundeddown
SCIP_COLEXACT ** cols
SCIP_AGGREGATEEXACT aggregate
Definition: struct_var.h:253
SCIP_AGGREGATE aggregate
Definition: struct_var.h:286
SCIP_VAR * negatedvar
Definition: struct_var.h:298
unsigned int varstatus
Definition: struct_var.h:338
SCIP_VARDATAEXACT * exactdata
Definition: struct_var.h:290
union SCIP_Var::@24 data
data structures for certificate output
data structures for exact LP management
SCIP main data structure.
the function declarations for the synchronization store
internal methods for displaying statistics tables
internal methods for branch and bound tree
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:58
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:57
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:60
@ SCIP_R_ROUND_UPWARDS
Definition: type_rational.h:58
@ SCIP_R_ROUND_DOWNWARDS
Definition: type_rational.h:57
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_INITSOLVE
Definition: type_set.h:52
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARSTATUS_ORIGINAL
Definition: type_var.h:51
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:54
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:53
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:57
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:55
@ SCIP_VARSTATUS_LOOSE
Definition: type_var.h:52
internal methods for problem variables
methods for creating output for visualization tools (VBC, BAK)
declarations for XML parsing