SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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-2026 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#ifndef _WIN32
38#include <strings.h> /*lint --e{766}*/
39#endif
40
41
42#include "lpi/lpi.h"
43#include "scip/exprinterpret.h"
44#include "scip/nlpi.h"
45#include "scip/benders.h"
46#include "scip/benderscut.h"
47#include "scip/branch.h"
49#include "scip/certificate.h"
50#include "scip/clock.h"
51#include "scip/compr.h"
52#include "scip/concsolver.h"
53#include "scip/concurrent.h"
54#include "scip/conflict.h"
55#include "scip/conflictstore.h"
56#include "scip/cons.h"
57#include "scip/cons_linear.h"
58#include "scip/cutpool.h"
59#include "scip/cuts.h"
60#include "scip/debug.h"
61#include "scip/def.h"
62#include "scip/dialog.h"
63#include "scip/dialog_default.h"
64#include "scip/disp.h"
65#include "scip/event.h"
66#include "scip/heur.h"
67#include "scip/heur_ofins.h"
68#include "scip/heur_reoptsols.h"
70#include "scip/heuristics.h"
71#include "scip/history.h"
72#include "scip/implics.h"
73#include "scip/interrupt.h"
74#include "scip/lp.h"
76#include "scip/mem.h"
78#include "scip/misc.h"
79#include "scip/nlp.h"
80#include "scip/nodesel.h"
81#include "scip/paramset.h"
82#include "scip/presol.h"
83#include "scip/presolve.h"
84#include "scip/pricer.h"
85#include "scip/pricestore.h"
86#include "scip/primal.h"
87#include "scip/prob.h"
88#include "scip/prop.h"
89#include "scip/reader.h"
90#include "scip/relax.h"
91#include "scip/reopt.h"
92#include "scip/retcode.h"
93#include "scip/sepastoreexact.h"
94#include "scip/scipbuildflags.h"
96#include "scip/scipgithash.h"
97#include "scip/sepa.h"
98#include "scip/sepastore.h"
99#include "scip/set.h"
100#include "scip/sol.h"
101#include "scip/solve.h"
102#include "scip/stat.h"
103#include "scip/syncstore.h"
104#include "scip/table.h"
105#include "scip/tree.h"
106#include "scip/var.h"
107#include "scip/visual.h"
108#include "xml/xml.h"
109
111#include "scip/scip_cons.h"
112#include "scip/scip_copy.h"
113#include "scip/scip_general.h"
114#include "scip/scip_mem.h"
115#include "scip/scip_message.h"
116#include "scip/scip_nlp.h"
117#include "scip/scip_numerics.h"
118#include "scip/scip_param.h"
119#include "scip/scip_prob.h"
120#include "scip/scip_sol.h"
121#include "scip/scip_solve.h"
123#include "scip/scip_var.h"
124
125#include "scip/pub_cons.h"
126#include "scip/pub_fileio.h"
127#include "scip/pub_message.h"
128#include "scip/pub_misc.h"
129#include "scip/pub_sol.h"
130#include "scip/pub_var.h"
131#include "scip/pub_lpexact.h"
133#include "scip/struct_lpexact.h"
134
135
136/* In debug mode, we include the SCIP's structure in scip.c, such that no one can access
137 * this structure except the interface methods in scip.c.
138 * In optimized mode, the structure is included in scip.h, because some of the methods
139 * are implemented as defines for performance reasons (e.g. the numerical comparisons)
140 */
141#ifndef NDEBUG
142#include "scip/struct_scip.h"
143#endif
144
145/** returns the sense of an inequality */
146static
148 SCIP_Bool isgreaterthan /**< is the inequality a greater than inequality? */
149 )
150{
151 return isgreaterthan ? 'G' : 'L';
152}
153
154/** returns whether certificate output is activated
155 *
156 * @todo add a flag set->certificate_enabled to store the return value of this method for easier and faster access
157 */
159 SCIP* scip /**< certificate information */
160 )
161{
162 assert(scip != NULL);
163 assert(scip->set != NULL);
164 assert(scip->stat != NULL);
165
166 if( !(scip->set->exact_enable) )
167 return FALSE;
168 else if( scip->set->stage == SCIP_STAGE_SOLVING )
169 return SCIPcertificateIsEnabled(scip->stat->certificate);
170 else
171 return !(scip->set->certificate_filename[0] == '-' && scip->set->certificate_filename[1] == '\0');
172}
173
174/** should the certificate track bound changes?
175 *
176 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
177 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
178 *
179 * @pre This method can be called if @p scip is in one of the following stages:
180 * - \ref SCIP_STAGE_SOLVING
181 *
182 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
183 */
185 SCIP* scip /**< SCIP data structure */
186 )
187{
188 return SCIPisCertified(scip) && scip->set->stage >= SCIP_STAGE_INITSOLVE && !SCIPinProbing(scip);
189}
190
191/** prints constraint to certificate
192 *
193 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
194 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
195 *
196 * @pre This method can be called if @p scip is in one of the following stages:
197 * - \ref SCIP_STAGE_INITSOLVE
198 *
199 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
200 */
202 SCIP* scip, /**< certificate information */
203 SCIP_Bool isorigfile, /**< should the original solution be printed or in transformed space */
204 const char* consname, /**< name of the constraint */
205 const char sense, /**< sense of the constraint, i.e., G, L, or E */
206 SCIP_RATIONAL* side, /**< left/right-hand side */
207 int len, /**< number of nonzeros */
208 int* ind, /**< index array */
209 SCIP_RATIONAL** val /**< coefficient array */
210 )
211{
212 assert(scip != NULL);
213 assert(scip->stat != NULL);
214 assert(scip->stat->certificate != NULL);
215
217
218 SCIP_CALL( SCIPcertificatePrintCons(scip->stat->certificate, isorigfile, consname, sense, side, len, ind, val) );
219
220 return SCIP_OKAY;
221}
222
223/** prints activity bound to proof section
224 *
225 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
226 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
227 *
228 * @pre This method can be called if @p scip is in one of the following stages:
229 * - \ref SCIP_STAGE_SOLVING
230 *
231 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
232 */
234 SCIP* scip, /**< SCIP data structure */
235 const char* linename, /**< name of the unsplitting line */
236 SCIP_BOUNDTYPE boundtype, /**< type of bound (upper/lower) */
237 SCIP_Real newbound, /**< pointer to lower bound on the objective, NULL indicating infeasibility */
238 SCIP_Bool ismaxactivity, /**< TRUE for maxactivity, FALSE for minactivity */
239 SCIP_CONS* constraint, /**< the constraint */
240 SCIP_VAR* variable, /**< the variable */
241 SCIP_ROWEXACT* row, /**< the corresponding row, or NULL if constraint has no row representation */
242 SCIP_RATIONAL** vals, /**< value array */
243 SCIP_RATIONAL* lhs, /**< lhs of the constraint */
244 SCIP_RATIONAL* rhs, /**< rhs of the constraint */
245 SCIP_VAR** vars, /**< variable array */
246 int nvars /**< number of values */
247 )
248{
249 /* It would be more efficient if we could do this all in fp artihmetic. However, this is not trivial because the
250 * translations between aggregate variables need to be done exactly.
251 */
252 SCIP_RATIONAL* newboundex;
253
254 SCIP_CALL( SCIPcheckStage(scip, "SCIPcertifyActivityVarBound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
255
257 SCIPrationalSetReal(newboundex, newbound);
258 (void) SCIPcertifyActivityVarBoundExact(scip, linename, boundtype,
259 newboundex, ismaxactivity, constraint, variable, row, vals, lhs, rhs, vars, nvars);
261
262 return SCIP_OKAY;
263}
264
265/** prints activity bound to proof section
266 *
267 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
268 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
269 *
270 * @pre This method can be called if @p scip is in one of the following stages:
271 * - \ref SCIP_STAGE_SOLVING
272 *
273 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
274 */
276 SCIP* scip, /**< SCIP data structure */
277 const char* linename, /**< name of the unsplitting line */
278 SCIP_BOUNDTYPE boundtype, /**< type of bound (upper/lower) */
279 SCIP_RATIONAL* newbound, /**< pointer to lower bound on the objective, NULL indicating infeasibility */
280 SCIP_Bool ismaxactivity, /**< TRUE for maxactivity, FALSE for minactivity */
281 SCIP_CONS* constraint, /**< the constraint */
282 SCIP_VAR* variable, /**< the variable */
283 SCIP_ROWEXACT* row, /**< the corresponding row, or NULL if constraint has no row representation */
284 SCIP_RATIONAL** vals, /**< value array */
285 SCIP_RATIONAL* lhs, /**< lhs of the constraint */
286 SCIP_RATIONAL* rhs, /**< rhs of the constraint */
287 SCIP_VAR** vars, /**< variable array */
288 int nvars /**< number of values */
289 )
290{
291 SCIP_CERTIFICATE* certificate;
292 SCIP_Longint res;
294 SCIP_RATIONAL* val;
295 SCIP_Bool upperboundcontribution;
296
297 SCIP_CALL( SCIPcheckStage(scip, "SCIPcertifyActivityVarBoundExact", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
298
299 assert(scip != NULL);
300 assert(scip->stat != NULL);
301 assert(scip->stat != NULL);
302
304
305 certificate = scip->stat->certificate;
306
307 switch( variable->varstatus )
308 {
312 SCIPABORT();
313 return SCIP_ERROR;
315
316 SCIPrationalMultReal(newbound, newbound, -1.0);
317 assert( SCIPvarGetNegationConstant(variable) == 1 );
318 SCIPrationalAddReal(newbound, newbound, 1.0);
321 newbound, ismaxactivity, constraint, variable->negatedvar, row, vals, lhs, rhs, vars, nvars);
322 SCIPrationalAddReal(newbound, newbound, -1.0);
323 SCIPrationalMultReal(newbound, newbound, -1.0);
324 return ret;
325 break;
327 SCIPrationalAddProdReal(newbound, variable->exactdata->aggregate.constant, -1.0);
328 SCIPrationalDiv(newbound, newbound, variable->exactdata->aggregate.scalar);
331 newbound, ismaxactivity, constraint, variable->data.aggregate.var, row, vals, lhs, rhs, vars, nvars);
332 SCIPrationalMult(newbound, newbound, variable->exactdata->aggregate.scalar);
333 return ret;
334 break;
336 break;
337 default:
338 SCIPABORT();
339 return SCIP_ERROR;
340 }
341
342 /* check if certificate output should be created */
343 if( certificate->transfile == NULL )
344 return ret;
345
346 certificate->indexcounter++;
347
348 if( linename == NULL )
349 {
350 SCIPcertificatePrintProofMessage(certificate, "ACT_L%d ", certificate->indexcounter - 1);
351 }
352 else
353 {
354 SCIPcertificatePrintProofMessage(certificate, "%s ", linename);
355 }
356
357 /* find the correct value in the constraint */
358 val = NULL;
359 for( int i = 0; i < nvars; i++ )
360 {
361 if( vars[i] == variable )
362 {
363 val = vals[i];
364 break;
365 }
366 }
367
368 assert(val != NULL);
369
370 /* Do we need an upper bound on the contribution val[i]*x_i? (otherwise a lowerbound) */
371 upperboundcontribution = (boundtype == SCIP_BOUNDTYPE_UPPER) == SCIPrationalIsPositive(val);
372 SCIPcertificatePrintProofMessage(certificate, "%c ", getInequalitySense(upperboundcontribution));
373
374 /* new bound = -newbound * val for now, we print a second line where we scale with 1/val */
375 SCIPrationalMult(newbound, newbound, val);
376 SCIPrationalNegate(newbound, newbound);
377 SCIP_CALL_ABORT( SCIPcertificatePrintProofRational(certificate, newbound) );
378
379 /* print coeffictent of variable -> val */
380 SCIPrationalNegate(newbound, newbound);
381 SCIPrationalDiv(newbound, newbound, val);
382 SCIPcertificatePrintProofMessage(certificate, " 1 %d ", SCIPvarGetCertificateIndex(variable));
383
384 /* negate val, print it and reset it again */
385 SCIPrationalNegate(val, val);
387 SCIPrationalNegate(val, val);
388
389 if(row != NULL)
390 res = SCIPcertificateGetRowIndex(certificate, row, !ismaxactivity);
391 else
392 res = SCIPcertificateGetConsIndex(certificate, constraint, lhs, rhs, !ismaxactivity);
393
394 SCIPcertificatePrintProofMessage(certificate, " { lin %d %d -1", nvars, res);
395
396 /* print all other variables with their correct bounds */
397 for( int i = 0; i < nvars; i++ )
398 {
399 SCIP_VAR* ivar;
400 bool is_upper_bound;
401 SCIP_Longint certificateindex;
402
404
405 ivar = vars[i];
406 if( ivar == variable )
407 continue;
408
409 is_upper_bound = upperboundcontribution != SCIPrationalIsPositive(vals[i]);
410
411 assert(upperboundcontribution != ismaxactivity);
412
413 certificateindex = is_upper_bound ? SCIPvarGetUbCertificateIndexLocal(ivar) : SCIPvarGetLbCertificateIndexLocal(ivar);
414 SCIPcertificatePrintProofMessage(certificate, " %d ", certificateindex);
415 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, vals[i]) );
416 }
417 SCIPcertificatePrintProofMessage(certificate, " } -1\n");
418
419 /* now scale with 1/val */
420 certificate->indexcounter++;
421 SCIPcertificatePrintProofMessage(certificate, "ACT_L%d %c ", certificate->indexcounter - 1, getInequalitySense(boundtype == SCIP_BOUNDTYPE_LOWER));
422 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, newbound) );
423 SCIPcertificatePrintProofMessage(certificate, " 1 %d 1 { lin 1 %d ", SCIPvarGetCertificateIndex(variable), certificate->indexcounter - 2);
424 SCIPrationalInvert(val, val);
425 SCIPrationalNegate(val, val);
426 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, val) );
427
428 /* Return val to its original state: */
429 SCIPrationalNegate(val, val);
430 SCIPrationalInvert(val, val);
431 SCIPcertificatePrintProofMessage(certificate, " } -1\n", SCIPvarGetCertificateIndex(variable), certificate->indexcounter - 2);
432
433 /* if variable is integer, round the new bound */
435 {
436 certificate->indexcounter++;
437
438 SCIPcertificatePrintProofMessage(certificate, "ACT_R%d %c ", certificate->indexcounter - 1, getInequalitySense(boundtype == SCIP_BOUNDTYPE_LOWER));
440
441 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, newbound) );
442
443 SCIPcertificatePrintProofMessage(certificate, " 1 %d 1", SCIPvarGetCertificateIndex(variable));
444 SCIPcertificatePrintProofMessage(certificate, " { rnd 1 %d 1 } -1\n", certificate->indexcounter - 2);
445 }
446
447#ifndef NDEBUG
448 certificate->lastinfo->isbound = TRUE;
449 certificate->lastinfo->boundtype = boundtype;
450 certificate->lastinfo->varindex = SCIPvarGetCertificateIndex(variable);
451 certificate->lastinfo->isglobal = FALSE;
452 certificate->lastinfo->certificateindex = certificate->indexcounter - 1;
453 SCIPrationalSetRational(certificate->lastinfo->boundval, newbound);
454#endif
455 (void) SCIPcertificateSetLastBoundIndex(certificate, certificate->indexcounter - 1);
456
457 return SCIP_OKAY;
458}
459
460/** prints activity conflict to certificate file
461 *
462 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
463 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
464 *
465 * @pre This method can be called if @p scip is in one of the following stages:
466 * - \ref SCIP_STAGE_SOLVING
467 *
468 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
469 */
471 SCIP* scip, /**< SCIP data structure */
472 SCIP_CONS* cons, /**< constraint */
473 SCIP_ROWEXACT* row, /**< corresponding row, or NULL if constraint does not have representation as row */
474 SCIP_RATIONAL* lhs, /**< lhs of the constraint */
475 SCIP_RATIONAL* rhs, /**< rhs of the constraint */
476 int nvals, /**< number of values */
477 SCIP_RATIONAL** vals, /**< value array */
478 SCIP_VAR** vars, /**< variable array */
479 SCIP_RATIONAL* diff, /**< difference between min/max activity as lhs/rhs */
480 SCIP_Bool userhs /**< is rhs or lhs used */
481 )
482{
483 SCIP_CERTIFICATE* certificate;
484 SCIP_Longint conscertificateindex;
485
486 SCIP_CALL( SCIPcheckStage(scip, "SCIPcertifyActivityConflict", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
487
488 if( !SCIPisCertified(scip) )
489 return SCIP_OKAY;
490
491 certificate = SCIPgetCertificate(scip);
492
493 if( row != NULL )
494 conscertificateindex = SCIPcertificateGetRowIndex(SCIPgetCertificate(scip), row, userhs);
495 else
496 conscertificateindex = SCIPcertificateGetConsIndex(certificate, cons, lhs, rhs, userhs);
497
498 assert(conscertificateindex != LONG_MAX);
499
500 SCIPcertificatePrintProofMessage(certificate, "ActivityConflict%d ", certificate->indexcounter);
501 SCIPcertificatePrintProofMessage(certificate, userhs ? "G " : "L ");
502
503 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, diff) );
504 SCIPcertificatePrintProofMessage(certificate, " 0 { lin %d %d -1", nvals + 1, conscertificateindex);
505 for( int i = 0; i < nvals; i++ )
506 {
507 SCIP_VAR* var;
508 bool is_upper_bound;
509 SCIP_Longint certificateindex;
510 var = row == NULL ? vars[i] : row->cols[i]->var;
511 is_upper_bound = userhs != SCIPrationalIsPositive(vals[i]);
512 certificateindex = is_upper_bound ? SCIPvarGetUbCertificateIndexLocal(var) : SCIPvarGetLbCertificateIndexLocal(var);
513 SCIPcertificatePrintProofMessage(certificate, " %d ", certificateindex);
514 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, vals[i]) );
515 }
516 SCIPcertificatePrintProofMessage(certificate, " } -1\n");
517
519 certificate->indexcounter++;
520 return SCIP_OKAY;
521}
522
523/** adds aggregation information to certificate for one row
524 *
525 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
526 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
527 *
528 * @pre This method can be called if @p scip is in one of the following stages:
529 * - \ref SCIP_STAGE_SOLVING
530 *
531 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
532 */
534 SCIP* scip, /**< SCIP data structure */
535 SCIP_AGGRROW* aggrrow, /**< agrrrow that results from the aggregation */
536 SCIP_ROW** aggrrows, /**< array of rows used fo the aggregation */
537 SCIP_Real* weights, /**< array of weights */
538 int naggrrows, /**< length of the arrays */
539 SCIP_ROW** negslackrows, /**< array of rows that are added implicitly with negative slack */
540 SCIP_Real* negslackweights, /**< array of negative slack weights */
541 int nnegslackrows /**< length of the negative slack array */
542 )
543{
544 assert(scip != NULL);
545 assert(scip->stat != NULL);
546
547 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCertificateAggrInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
548
549 SCIP_CALL( SCIPcertificateNewAggrInfo(scip, aggrrow, aggrrows, weights, naggrrows, negslackrows, negslackweights, nnegslackrows) );
550
551 return SCIP_OKAY;
552}
553
554/** stores the active aggregation information in the certificate data structures for a row
555 *
556 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
557 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
558 *
559 * @pre This method can be called if @p scip is in one of the following stages:
560 * - \ref SCIP_STAGE_SOLVING
561 *
562 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
563 */
565 SCIP* scip, /**< SCIP data structure */
566 SCIP_ROW* row /**< row that aggregation-info is stored for */
567 )
568{
569 SCIP_CERTIFICATE* certificate;
570 SCIP_AGGREGATIONINFO* aggrinfo;
571
572 SCIP_CALL( SCIPcheckStage(scip, "SCIPstoreCertificateActiveAggrInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
573
575 return SCIP_OKAY;
576
577 certificate = SCIPgetCertificate(scip);
578
579 assert(certificate != NULL);
580 assert(certificate->workingaggrinfo);
581
582 aggrinfo = certificate->aggrinfo[certificate->naggrinfos - 1];
583 certificate->workingaggrinfo = FALSE;
584
585 assert(aggrinfo != NULL);
586
587 SCIP_CALL( SCIPhashmapSetImage(certificate->aggrinfohash, (void*) row, (void*) aggrinfo) );
588
589 return SCIP_OKAY;
590}
591
592/** frees the active aggregation information
593 *
594 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
595 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
596 *
597 * @pre This method can be called if @p scip is in one of the following stages:
598 * - \ref SCIP_STAGE_SOLVING
599 *
600 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
601 */
603 SCIP* scip /**< SCIP data structure */
604 )
605{
606 SCIP_CERTIFICATE* certificate;
607 SCIP_AGGREGATIONINFO* aggrinfo;
608
609 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeCertificateActiveAggrInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
610
612 return SCIP_OKAY;
613
614 certificate = SCIPgetCertificate(scip);
615
616 assert(certificate != NULL);
617
618 /* if the mirinfo is used it gets tranformed into sparse format, don't free it in that case */
619 if( !certificate->workingaggrinfo )
620 return SCIP_OKAY;
621
622 aggrinfo = certificate->aggrinfo[certificate->naggrinfos - 1];
623
624 assert(aggrinfo != NULL);
625
626 SCIP_CALL( SCIPcertificateFreeAggrInfo(scip->set, certificate, scip->lp, aggrinfo, NULL) );
627
628 certificate->workingaggrinfo = FALSE;
629
630 return SCIP_OKAY;
631}
632
633/** adds aggregation information to certificate for one row
634 *
635 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
636 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
637 *
638 * @pre This method can be called if @p scip is in one of the following stages:
639 * - \ref SCIP_STAGE_SOLVING
640 *
641 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
642 */
644 SCIP* scip /**< SCIP data structure */
645 )
646{
647 assert(scip != NULL);
648 assert(scip->stat != NULL);
649
650 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCertificateMirInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
651
653
654 return SCIP_OKAY;
655}
656
657/** stores the active mir information in the certificate data structures for a row
658 *
659 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
660 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
661 *
662 * @pre This method can be called if @p scip is in one of the following stages:
663 * - \ref SCIP_STAGE_SOLVING
664 *
665 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
666 */
668 SCIP* scip, /**< SCIP data structure */
669 SCIP_ROW* row /**< row that mirinfo is stored for */
670 )
671{
672 SCIP_CERTIFICATE* certificate;
673 SCIP_MIRINFO* mirinfo;
674 int i;
675 int csplit;
676
677 SCIP_CALL( SCIPcheckStage(scip, "SCIPstoreCertificateActiveMirInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
678
680 return SCIP_OKAY;
681
682 certificate = SCIPgetCertificate(scip);
683
684 assert(certificate != NULL);
685 assert(certificate->workingmirinfo);
686
687 certificate->workingmirinfo = FALSE;
688
689 mirinfo = certificate->mirinfo[certificate->nmirinfos - 1];
690
691 assert(mirinfo != NULL);
692
693 assert(mirinfo->nsplitvars == SCIPgetNVars(scip));
694
695 csplit = 0;
696
697 /* make the mirinfo sparse again */
698 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(mirinfo->varinds), mirinfo->nsplitvars) );
699
700 for( i = 0; i < mirinfo->nsplitvars; i++ )
701 {
702 if( mirinfo->splitcoefficients[i] != 0.0 || mirinfo->upperused[i] || mirinfo->localbdused[i] )
703 {
704 mirinfo->splitcoefficients[csplit] = mirinfo->splitcoefficients[i];
705 mirinfo->upperused[csplit] = mirinfo->upperused[i];
706 mirinfo->localbdused[csplit] = mirinfo->localbdused[i];
707 mirinfo->varinds[csplit] = i;
708 csplit++;
709 }
710 }
711
712 mirinfo->nsplitvars = csplit;
717
725
726 SCIP_CALL( SCIPhashmapSetImage(certificate->mirinfohash, (void*) row, (void*) mirinfo) );
727
728 return SCIP_OKAY;
729}
730
731/** print MIR cut to certificate file
732 *
733 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
734 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
735 *
736 * @pre This method can be called if @p scip is in one of the following stages:
737 * - \ref SCIP_STAGE_SOLVING
738 *
739 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
740 */
742 SCIP* scip, /**< SCIP data structure */
743 SCIP_ROW* row /**< row that needs to be certified */
744 )
745{
746 SCIP_CERTIFICATE* certificate;
747
749
751 return SCIP_OKAY;
752
753 certificate = SCIPgetCertificate(scip);
754 SCIP_CALL( SCIPcertificatePrintMirCut(scip->set, scip->lp, certificate, scip->transprob, row, 'L') );
755
756 return SCIP_OKAY;
757}
758
759/** frees the active mir information
760 *
761 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
762 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
763 *
764 * @pre This method can be called if @p scip is in one of the following stages:
765 * - \ref SCIP_STAGE_SOLVING
766 *
767 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
768 */
770 SCIP* scip /**< SCIP data structure */
771 )
772{
773 SCIP_CERTIFICATE* certificate;
774 SCIP_MIRINFO* mirinfo;
775 int i;
776
777 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeCertificateActiveMirInfo", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
778
780 return SCIP_OKAY;
781
782 certificate = SCIPgetCertificate(scip);
783
784 assert(certificate != NULL);
785
786 if( certificate->nmirinfos == 0 )
787 return SCIP_OKAY;
788
789 mirinfo = certificate->mirinfo[certificate->nmirinfos - 1];
790
791 assert(mirinfo != NULL);
792
793 /* if the mirinfo is used it gets tranformed into sparse format, don't free it in that case */
794 if( !certificate->workingmirinfo )
795 return SCIP_OKAY;
796
797 for(i = 0; i < mirinfo->nslacks; ++i)
798 {
799 SCIP_CALL( SCIPreleaseRow(scip, &(mirinfo->slackrows[i])) );
800 }
801
802 assert(mirinfo->varinds == NULL);
803
806
817 SCIPfreeBlockMemory(scip, &mirinfo);
818 certificate->nmirinfos--;
819 certificate->workingmirinfo = FALSE;
820
821 return SCIP_OKAY;
822}
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
data structures 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:365
common defines and data types used in all packages of SCIP
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_CALL_ABORT(x)
Definition def.h:343
#define SCIPABORT()
Definition def.h:336
#define SCIP_CALL(x)
Definition def.h:364
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:4320
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition cons.c:8413
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)
void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
void SCIPrationalInvert(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
Definition rational.cpp:462
void SCIPrationalRoundInteger(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_ROUNDMODE_RAT roundmode)
void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition rational.cpp:604
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:474
SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:124
void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
Definition rational.cpp:570
SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
void SCIPrationalNegate(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
void SCIPrationalAddReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
Definition rational.cpp:962
void SCIPrationalAddProdReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
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:25220
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition var.c:23921
int SCIPvarGetCertificateIndex(SCIP_VAR *var)
Definition var.c:25130
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23485
SCIP_Longint SCIPvarGetLbCertificateIndexLocal(SCIP_VAR *var)
Definition var.c:25208
internal methods for primal heuristics
return SCIP_OKAY
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
OFINS - Objective Function Induced Neighborhood Search - a primal heuristic for reoptimization.
reoptsols primal heuristic
static SCIP_VAR ** vars
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_Longint indexcounter
SCIP_MIRINFO ** mirinfo
SCIP_CERTIFICATEBOUND * lastinfo
SCIP_HASHMAP * mirinfohash
SCIP_AGGREGATIONINFO ** aggrinfo
SCIP_HASHMAP * aggrinfohash
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
union SCIP_Var::@062351145146014100220174313010263165251013276204 data
SCIP_VARDATAEXACT * exactdata
Definition struct_var.h:290
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
struct SCIP_Certificate SCIP_CERTIFICATE
struct SCIP_MirInfo SCIP_MIRINFO
struct SCIP_AggregationInfo SCIP_AGGREGATIONINFO
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
struct SCIP_AggrRow SCIP_AGGRROW
Definition type_cuts.h:37
struct SCIP_Row SCIP_ROW
Definition type_lp.h:105
@ 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
struct SCIP_RowExact SCIP_ROWEXACT
struct SCIP_Rational SCIP_RATIONAL
@ SCIP_R_ROUND_UPWARDS
@ SCIP_R_ROUND_DOWNWARDS
@ SCIP_INVALIDCALL
@ SCIP_ERROR
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_INITSOLVE
Definition type_set.h:52
@ SCIP_STAGE_SOLVING
Definition type_set.h:53
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ 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