SCIP Doxygen Documentation
Loading...
Searching...
No Matches
cons_countsols.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 cons_countsols.c
26 * @ingroup DEFPLUGINS_CONS
27 * @brief constraint handler for counting feasible solutions
28 * @author Stefan Heinz
29 * @author Michael Winkler
30 *
31 * If this constraint handler is activated then it counts or collects all feasible solutions. We refer to \ref COUNTER for
32 * more details about using SCIP for counting feasible solutions.
33 *
34 * @todo In the last round of presolving we should check if variables exist, which have up and down lock one. In this
35 * case we know that these locks are coming from this constraint handler. Therefore, they are totally free and can
36 * be ignored in the branch and bound process. To get this result we have to store these variables in the
37 * constraint handler data structure (to remember this free dimensions) and fix them to any feasible value.
38 */
39
40/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
41
44#include "scip/cons_countsols.h"
45#include "scip/cons_knapsack.h"
46#include "scip/cons_logicor.h"
47#include "scip/cons_setppc.h"
48#include "scip/cons_varbound.h"
49#include "scip/dialog_default.h"
50#include "scip/pub_cons.h"
51#include "scip/pub_dialog.h"
52#include "scip/pub_disp.h"
53#include "scip/pub_heur.h"
54#include "scip/pub_message.h"
55#include "scip/pub_misc.h"
56#include "scip/pub_misc_sort.h"
57#include "scip/pub_sol.h"
58#include "scip/pub_var.h"
59#include "scip/scip_branch.h"
60#include "scip/scip_cons.h"
61#include "scip/scip_dialog.h"
62#include "scip/scip_disp.h"
63#include "scip/scip_general.h"
64#include "scip/scip_heur.h"
65#include "scip/scip_mem.h"
66#include "scip/scip_message.h"
67#include "scip/scip_numerics.h"
68#include "scip/scip_param.h"
69#include "scip/scip_prob.h"
70#include "scip/scip_sol.h"
71#include "scip/scip_solve.h"
72#include "scip/scip_var.h"
74
75
76/* depending on whether the GMP library is available we use a GMP data type or a SCIP_Longint */
77#ifdef SCIP_WITH_GMP
78#include <gmp.h>
79typedef mpz_t Int;
80#else
82#endif
83
84/* constraint handler properties */
85#define CONSHDLR_NAME "countsols"
86#define CONSHDLR_DESC "constraint to count feasible solutions"
87#define CONSHDLR_ENFOPRIORITY -9999999 /**< priority of the constraint handler for constraint enforcing */
88#define CONSHDLR_CHECKPRIORITY -9999999 /**< priority of the constraint handler for checking feasibility */
89#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
90 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
91#define CONSHDLR_NEEDSCONS FALSE /**< should the constraint handler be skipped, if no constraints are available? */
92
93/* default parameter settings */
94#define DEFAULT_SPARSETEST TRUE /**< sparse test on or off */
95#define DEFAULT_DISCARDSOLS TRUE /**< is it allowed to discard solutions */
96#define DEFAULT_ACTIVE FALSE /**< is the constraint handler active */
97#define DEFAULT_COLLECT FALSE /**< should the solutions be collected */
98#define DEFAULT_SOLLIMIT -1LL /**< counting stops, if the given number of solutions were found (-1: no limit) */
99
100/* default column settings */
101#define DISP_SOLS_NAME "sols"
102#define DISP_SOLS_DESC "number of detected feasible solutions"
103#define DISP_SOLS_HEADER " sols "
104#define DISP_SOLS_WIDTH 7
105#define DISP_SOLS_PRIORITY 110000
106#define DISP_SOLS_POSITION 100000
107#define DISP_SOLS_STRIPLINE TRUE
108
109#define DISP_CUTS_NAME "feasST"
110#define DISP_CUTS_DESC "number of detected non trivial feasible subtrees"
111#define DISP_CUTS_HEADER "feasST"
112#define DISP_CUTS_WIDTH 6
113#define DISP_CUTS_PRIORITY 110000
114#define DISP_CUTS_POSITION 110000
115#define DISP_CUTS_STRIPLINE TRUE
116
117/** creates and adds a constraint which cuts off the solution from the feasibility region
118 *
119 * input:
120 * - scip : SCIP main data structure
121 * - sol : solution to cut off
122 * - conshdlrdata : constraint handler data
123 */
124#define CUTOFF_CONSTRAINT(x) SCIP_RETCODE x (SCIP* scip, SCIP_SOL* sol, SCIP_CONSHDLRDATA* conshdlrdata)
125
126
127/** constraint handler data */
128struct SCIP_ConshdlrData
129{
130 /* solution data and statistic variables */
131 SCIP_SPARSESOL** solutions; /**< array to store all solutions */
132 int nsolutions; /**< number of solution stored */
133 int ssolutions; /**< size of the solution array */
134 int feasST; /**< number of non trivial feasible subtrees */
135 int nDiscardSols; /**< number of discarded solutions */
136 int nNonSparseSols; /**< number of non sparse solutions */
137 Int nsols; /**< number of solutions */
138 CUTOFF_CONSTRAINT((*cutoffSolution)); /**< method for cutting of a solution */
139
140 /* constraint handler parameters */
141 SCIP_Longint sollimit; /**< counting stops, if the given number of solutions have been found (-1: no limit) */
142 SCIP_Bool active; /**< constraint handler active */
143 SCIP_Bool discardsols; /**< allow to discard solutions */
144 SCIP_Bool sparsetest; /**< allow to check for sparse solutions */
145 SCIP_Bool collect; /**< should the solutions be collected */
146
147 SCIP_Bool warning; /**< has the warning message already been posted? */
148
149 /* specific problem data */
150 SCIP_HASHMAP* hashmap; /**< hashmap to store position of active transformed problem variable in our vars array */
151 SCIP_VAR** allvars; /**< array containing a copy of all variables before presolving */
152 SCIP_VAR** vars; /**< array containing a copy of all active variables (after presolving) */
153 int nallvars; /**< number of all variables in the problem */
154 int nvars; /**< number of all active variables in the problem */
155 SCIP_Bool continuous; /**< are there continuous variables */
156};
157
158
159/*
160 * Local methods for handling the <Int> data structure
161 */
162
163/** allocates memory for the value pointer */
164static
166 Int* value /**< pointer to the value to allocate memory */
167 )
168{ /*lint --e{715}*/
169#ifdef SCIP_WITH_GMP
170 mpz_init(*value);
171#endif
172}
173
174
175/** sets the value pointer to the new value */
176static
178 Int* value, /**< pointer to the value to initialize */
179 SCIP_Longint newvalue /**< new value */
180 )
181{
182 assert(newvalue < LONG_MAX);
183
184#ifdef SCIP_WITH_GMP
185 mpz_set_si(*value, (long) newvalue);
186#else
187 (*value) = newvalue;
188#endif
189}
190
191
192/** sets a power of 2 to the given value */
193static
195 Int* value, /**< pointer to the value to increase */
196 SCIP_Longint exponent /**< exponent for the base 2 */
197 )
198{
199 assert(0 <= exponent && exponent < LONG_MAX);
200
201#ifdef SCIP_WITH_GMP
202 mpz_ui_pow_ui(*value, 2UL, (unsigned long) exponent);
203#else
204 assert(exponent < 64);
205 (*value) = (SCIP_Longint)1 << exponent;
206#endif
207}
208
209
210/** free memory */
211static
213 Int* value /**< pointer to the value to free */
214 )
215{ /*lint --e{715}*/
216#ifdef SCIP_WITH_GMP
217 mpz_clear(*value);
218#endif
219}
220
221
222/** adds one to the given value */
223static
225 Int* value /**< pointer to the value to increase */
226 )
227{
228#ifdef SCIP_WITH_GMP
229 mpz_add_ui(*value, *value, 1UL);
230#else
231 (*value)++;
232#endif
233}
234
235
236/** adds the summand to the given value */
237static
239 Int* value, /**< pointer to the value to increase */
240 Int* summand /**< summand to add on */
241 )
242{
243#ifdef SCIP_WITH_GMP
244 mpz_add(*value, *value, *summand);
245#else
246 (*value) += (*summand);
247#endif
248}
249
250
251/** multiplies the factor by the given value */
252static
254 Int* value, /**< pointer to the value to increase */
255 SCIP_Longint factor /**< factor to multiply with */
256 )
257{
258 assert(0 <= factor && factor < LONG_MAX);
259
260#ifdef SCIP_WITH_GMP
261 mpz_mul_ui(*value, *value, (unsigned long) factor);
262#else
263 (*value) *= factor;
264#endif
265}
266
267
268/** method for creating a string out of an Int which is a mpz_t or SCIP_Longint */ /*lint -e{715}*/
269static
271 Int value, /**< number */
272 char** buffer, /**< pointer to buffer for storing the string */
273 int buffersize /**< length of the buffer */
274 )
275{ /*lint --e{715}*/
276#ifdef SCIP_WITH_GMP
277 (void) mpz_get_str(*buffer, 10, value);
278#else
279 (void) SCIPsnprintf (*buffer, buffersize, "%" SCIP_LONGINT_FORMAT "", value);
280#endif
281}
282
283
284/** method for creating a SCIP_Longing out of an Int */
285static
287 Int value, /**< number to convert */
288 SCIP_Bool* valid /**< pointer to store if the return value is valid */
289 )
290{
291#ifdef SCIP_WITH_GMP
292 *valid = FALSE;
293 if( 0 != mpz_fits_sint_p(value) )
294 (*valid) = TRUE;
295
296 return mpz_get_si(value);
297#else
298 *valid = TRUE;
299 return value;
300#endif
301}
302
303
304/*
305 * Local methods
306 */
307
308
309/** returns whether a given integer variable is unfixed in the local domain */
310static
312 SCIP_VAR* var /**< integer variable */
313 )
314{
315 assert( var != NULL );
318
319 return ( SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var) > 0.5 );
320}
321
322
323/** creates the constraint handler data */
324static
326 SCIP* scip, /**< SCIP data structure */
327 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to store constraint handler data */
328 )
329{
330 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
331
332 (*conshdlrdata)->feasST = 0;
333 (*conshdlrdata)->nDiscardSols = 0;
334 (*conshdlrdata)->nNonSparseSols = 0;
335 (*conshdlrdata)->solutions = NULL;
336 (*conshdlrdata)->nsolutions = 0;
337 (*conshdlrdata)->ssolutions = 0;
338
339 allocInt(&(*conshdlrdata)->nsols); /*lint !e545*/
340
341 (*conshdlrdata)->cutoffSolution = NULL;
342 (*conshdlrdata)->warning = FALSE;
343 (*conshdlrdata)->hashmap = NULL;
344 (*conshdlrdata)->allvars = NULL;
345 (*conshdlrdata)->vars = NULL;
346 (*conshdlrdata)->nallvars = 0;
347 (*conshdlrdata)->nvars = 0;
348 (*conshdlrdata)->continuous = FALSE;
349
350 return SCIP_OKAY;
351}
352
353
354#ifndef NDEBUG
355/** check solution in original space */
356static
358 SCIP* scip, /**< SCIP data structure */
359 SCIP_SOL* sol, /**< solution to add */
360 SCIP_CONSHDLRDATA* conshdlrdata /**< constraint handler data */
361 )
362{
363 SCIP_Bool feasible;
364 SCIP_RETCODE retcode;
365
366 /* turn off solution counting to be able to check the solution */
367 conshdlrdata->active = FALSE;
368
369 SCIPdebugMsg(scip, "check solution in original space before counting\n");
370
371 feasible = FALSE;
372
373 /* check solution in original space */
374 retcode = SCIPcheckSolOrig(scip, sol, &feasible, TRUE, TRUE);
375 assert(feasible);
376
377 /* check return code manually */
378 if( retcode != SCIP_OKAY )
379 {
380 SCIPprintError(retcode);
381 SCIPABORT();
382 }
383
384 /* turn on solution counting to continue */
385 conshdlrdata->active = TRUE;
386}
387#else
388#define checkSolutionOrig(scip, sol, conshdlrdata) /**/
389#endif
390
391/** check if the current parameter setting is correct for a safe counting process */
392static
394 SCIP* scip /**< SCIP data structure */
395 )
396{
397 SCIP_HEUR** heuristics;
398 int nheuristics;
399 int h;
400 int intvalue;
402
403 assert( scip != NULL );
404
405 valid = TRUE;
406
407 /* check if all heuristics are turned off */
408 heuristics = SCIPgetHeurs(scip);
409 nheuristics = SCIPgetNHeurs(scip);
410
411 for( h = 0; h < nheuristics && valid; ++h )
412 {
413 if( SCIPheurGetFreq(heuristics[h]) != -1 )
414 valid = FALSE;
415 }
416
417 if( !valid )
418 {
420 "At least one heuristic is not turned off! Heuristic solutions are currently not accepted while couting.\n");
421 }
422
423 /* check if restart is turned off */
424 SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrestarts", &intvalue) );
425 if( intvalue != 0 )
426 {
427 /* need to disable restarts, since collecting solutions won't work, but also the capturing for variables is not
428 * correctly handled
429 */
430 SCIPwarningMessage(scip, "counting forces parameter <presolving/maxrestarts> to 0.\n");
431 if( SCIPisParamFixed(scip, "presolving/maxrestarts") )
432 {
433 SCIP_CALL( SCIPunfixParam(scip, "presolving/maxrestarts") );
434 }
435
436 SCIP_CALL( SCIPsetIntParam(scip, "presolving/maxrestarts", 0) );
437 }
438
439 /* check if symmetry handling is turned off */
440 SCIP_CALL( SCIPgetIntParam(scip, "misc/usesymmetry", &intvalue) );
441 if ( intvalue != 0 )
442 {
443 /* need to disable symmetry handling, since counting is not supported if symmetry handling is enabled */
444 SCIPwarningMessage(scip, "counting forces parameter <misc/usesymmetry> to 0.\n");
445 if( SCIPisParamFixed(scip, "misc/usesymmetry") )
446 {
447 SCIP_CALL( SCIPunfixParam(scip, "misc/usesymmetry") );
448 }
449
450 SCIP_CALL( SCIPsetIntParam(scip, "misc/usesymmetry", 0) );
451 }
452
453 return SCIP_OKAY;
454}
455
456/** creates and adds a constraints which cuts off the current solution from the feasibility region in the case there are
457 * only binary variables
458 */
459static
460CUTOFF_CONSTRAINT(addBinaryCons)
461{
462 int v;
463 SCIP_VAR** consvars;
464 SCIP_VAR** vars;
465 int nvars;
466 SCIP_Real value;
467 SCIP_VAR* var;
468 SCIP_CONS* cons;
469
470 assert( scip != NULL );
471 assert( sol != NULL );
472 assert( conshdlrdata != NULL );
473
474 vars = conshdlrdata->vars;
475 nvars = conshdlrdata->nvars;
476
477 /* allocate buffer memory */
479
480 for( v = 0; v < nvars; ++v )
481 {
482 var = vars[v];
483
484 assert( var != NULL );
486
487 value = SCIPgetSolVal(scip, sol, var);
488 assert( SCIPisFeasIntegral(scip, value) );
489
490 if( value > 0.5 )
491 {
492 SCIP_CALL( SCIPgetNegatedVar(scip, var, &consvars[v]) );
493 }
494 else
495 consvars[v] = var;
496 }
497
498 /* create constraint */
499 SCIP_CALL( SCIPcreateConsSetcover(scip, &cons, "Setcovering created by countsols", nvars, consvars,
501
502 /* add and release constraint */
503 SCIP_CALL( SCIPaddCons(scip, cons) );
504 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
505
506 /* free buffer array */
507 SCIPfreeBufferArray(scip, &consvars);
508
509 return SCIP_OKAY;
510}
511
512
513/** creates and adds a bound disjunction constraints which cuts off the current solution from the feasibility region; if
514 * only binary variables are involved, then a set covering constraint is created which is a special case of a bound
515 * disjunction constraint
516 */
517static
518CUTOFF_CONSTRAINT(addIntegerCons)
519{
520 int v;
521 SCIP_VAR** consvars;
522 SCIP_VAR** vars;
523 SCIP_Real* bounds;
524 SCIP_BOUNDTYPE* boundtypes;
525 int nvars;
526 int nbinvars = 0;
527 int nconsvars;
528 SCIP_VAR* var;
529 SCIP_Real value;
530 SCIP_CONS* cons;
531
532 assert( scip != NULL );
533 assert( sol != NULL );
534 assert( conshdlrdata != NULL );
535
536 vars = conshdlrdata->vars;
537 nvars = conshdlrdata->nvars;
538
539 nconsvars = nvars * 2;
540 assert( nvars > 0 );
541
542 /* allocate buffer memory */
543 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
544 SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nconsvars) );
545 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nconsvars) );
546
547 nconsvars = 0;
548
549 for( v = nvars - 1; v >= 0; --v )
550 {
551 var = vars[v];
552
554
555 if( SCIPvarIsBinary(var) )
556 {
557 ++nbinvars;
558 value = SCIPgetSolVal(scip, sol, var);
559 assert( SCIPisFeasIntegral(scip, value) );
560
561 if( value < 0.5 )
562 {
563 boundtypes[nconsvars] = SCIP_BOUNDTYPE_LOWER;
564 bounds[nconsvars] = 1;
565 }
566 else
567 {
568 boundtypes[nconsvars] = SCIP_BOUNDTYPE_UPPER;
569 bounds[nconsvars] = 0;
570 }
571 }
572 else
573 {
574 SCIP_Real lb;
575 SCIP_Real ub;
576 SCIP_Real valueInt;
577
581
584 valueInt = SCIPgetSolVal(scip, sol, var);
585
586 if( SCIPisFeasEQ(scip, valueInt, lb) )
587 {
588 boundtypes[nconsvars] = SCIP_BOUNDTYPE_LOWER;
589 bounds[nconsvars] = lb + 1.0;
590 }
591 else if( SCIPisFeasEQ(scip, valueInt, ub) )
592 {
593 boundtypes[nconsvars] = SCIP_BOUNDTYPE_UPPER;
594 bounds[nconsvars] = ub - 1.0;
595 }
596 else
597 {
598 boundtypes[nconsvars] = SCIP_BOUNDTYPE_LOWER;
599 bounds[nconsvars] = valueInt + 1.0;
600 consvars[nconsvars] = var;
601 ++nconsvars;
602 boundtypes[nconsvars] = SCIP_BOUNDTYPE_UPPER;
603 bounds[nconsvars] = valueInt - 1.0;
604 }
605 }
606
607 consvars[nconsvars] = var;
608 ++nconsvars;
609 }
610
611 /* check if only binary variables appear in the constraint; if this is the case, we
612 * create a set covering constraint instead of a bound disjunction constraint
613 */
614 if( nvars == nbinvars )
615 {
616 for( v = nbinvars - 1; v >= 0; --v )
617 {
618 /* in the case the bound is zero we have use the negated variable */
619 if( bounds[v] == 0)
620 {
621 SCIP_CALL( SCIPgetNegatedVar(scip, consvars[v], &consvars[v]) );
622 }
623 }
624
625 SCIP_CALL( SCIPcreateConsSetcover(scip, &cons, "Setcovering created by countsols", nbinvars, consvars,
627 }
628 else
629 {
630 SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, "Bounddisjunction created by countsols",
631 nconsvars, consvars, boundtypes, bounds,
633 }
634
635 /* add and release constraint locally */
636 SCIP_CALL( SCIPaddCons(scip, cons) );
637 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
638
639 /* free buffer memory */
640 SCIPfreeBufferArray(scip, &consvars);
641 SCIPfreeBufferArray(scip, &bounds);
642 SCIPfreeBufferArray(scip, &boundtypes);
643
644 return SCIP_OKAY;
645}
646
647/** collect given solution or local domains as sparse solution */
648static
650 SCIP* scip, /**< SCIP data structure */
651 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
652 SCIP_SOL* sol /**< solution, or NULL if local domains */
653 )
654{
655 SCIP_SPARSESOL* solution;
656 SCIP_Longint* lbvalues;
657 SCIP_Longint* ubvalues;
658 int nvars;
659 int v;
660
661 /* ensure size of solution array
662 *
663 * we use normal memory instead of block memory because this plugin is rarely used, the size of 'solutions'
664 * can be arbitrary large, and the change that the other blocks can be used is quite small
665 */
666 if( conshdlrdata->nsolutions == conshdlrdata->ssolutions )
667 {
668 if( conshdlrdata->ssolutions == 0 )
669 {
670 conshdlrdata->ssolutions = 100;
671 SCIP_CALL( SCIPallocMemoryArray(scip, &conshdlrdata->solutions, conshdlrdata->ssolutions) );
672 }
673 else
674 {
675 assert( conshdlrdata->ssolutions < INT_MAX / 2);
676 conshdlrdata->ssolutions *= 2;
677 SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->solutions, conshdlrdata->ssolutions) );
678 }
679 }
680 assert( conshdlrdata->nsolutions < conshdlrdata->ssolutions );
681
682 /* get number of active variables */
683 nvars = conshdlrdata->nvars;
684
685 SCIPdebugMsg(scip, "creating solution number %d\n", conshdlrdata->nsolutions);
686
687 /* create a solution */
688 SCIP_CALL_FINALLY( SCIPsparseSolCreate(&solution, conshdlrdata->vars, nvars, FALSE), SCIPsparseSolFree(&solution) );
689 assert(solution != NULL);
690
691 lbvalues = SCIPsparseSolGetLbs(solution);
692 ubvalues = SCIPsparseSolGetUbs(solution);
693 assert(ubvalues != NULL);
694 assert(lbvalues != NULL);
695
696 for( v = nvars - 1; v >= 0; --v )
697 {
698 SCIP_VAR* var;
699
700 var = conshdlrdata->vars[v];
701 assert(var != NULL);
702
703 if( sol == NULL )
704 {
707 }
708 else
709 {
711 ubvalues[v] = lbvalues[v];
712 }
713
714 SCIPdebugMsg(scip, "variable <%s> [%" SCIP_LONGINT_FORMAT ",%" SCIP_LONGINT_FORMAT "]\n",
715 SCIPvarGetName(var), lbvalues[v], ubvalues[v]);
716 }
717
718 conshdlrdata->solutions[conshdlrdata->nsolutions] = solution;
719 conshdlrdata->nsolutions++;
720
721 return SCIP_OKAY;
722}
723
724
725/** counts the number of solutions represented by sol */
726static
728 SCIP* scip, /**< SCIP data structure */
729 SCIP_SOL* sol, /**< solution */
730 SCIP_Bool feasible, /**< is solution feasible? */
731 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
732 SCIP_RESULT* result /**< pointer to store the result of the checking process */
733 )
734{
735 assert( scip != NULL );
736 assert( sol != NULL );
737 assert( conshdlrdata != NULL );
738 assert( result != NULL );
739
740 /* the result should be infeasible since we reject any solution; however, if the solution passes the sparse test, the
741 * result is set to SCIP_CUTOFF which cuts off the subtree initialized through the current node
742 */
744
745 if( feasible )
746 {
747 int v;
748 Int newsols;
749 SCIP_VAR** vars;
750 int nvars;
751 SCIP_VAR* var;
752 SCIP_Real lb;
753 SCIP_Real ub;
754
755 SCIPdebugMsg(scip, "counts number of solutions represented through the given one\n");
756
757 /**@note aggregations and multi aggregations: we do not have to care about these things
758 * since we count solutions from the transformed problem and therefore, SCIP does
759 * it for us
760 */
762
763 allocInt(&newsols); /*lint !e545*/
764
765 /* set newsols to one */
766 setInt(&newsols, 1LL); /*lint !e545*/
767
769 {
770 int npseudocands;
771
772 npseudocands = SCIPgetNPseudoBranchCands(scip);
773
774 /* sets a power of 2 to the number of solutions */
775 setPowerOfTwo(&newsols, (SCIP_Longint) npseudocands); /*lint !e545*/
776 }
777 else
778 {
779 SCIP_VAR* origvar;
780 SCIP_Real scalar = 1.0;
781 SCIP_Real constant = 0.0;
782
784
785 for( v = 0; v < nvars; ++v )
786 {
787 var = vars[v];
788 origvar = var;
789
790 /* get original variable to decide if we will count the domain; continuous variables aren't counted */
791 SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
792
793 if( origvar != NULL && SCIPvarIsIntegral(origvar) )
794 {
797
798 SCIPdebugMsg(scip, "variable <%s> Local Bounds are [%g,%g]\n", SCIPvarGetName(var), lb, ub);
799
803 assert( SCIPisFeasIntegral(scip, ub - lb) );
804 assert( SCIPisFeasLT(scip, lb, ub) );
805
806 /* the number of integers lying in the interval [lb,ub] is (ub - lb + 1); to make everything integral we
807 * add another 0.5 and cut the fractional part off
808 */
809 multInt(&newsols, (SCIP_Longint)(ub - lb + 1.5) ); /*lint !e545*/
810 }
811 }
812 }
813
815 conshdlrdata->feasST++;
816
817 if( conshdlrdata->collect )
818 {
819 SCIP_CALL( collectSolution(scip, conshdlrdata, NULL) );
820 }
821
822 addInt(&conshdlrdata->nsols, &newsols); /*lint !e545*/
823 freeInt(&newsols); /*lint !e545*/
824 }
825 else if(!conshdlrdata->discardsols)
826 {
827 SCIP_CALL( conshdlrdata->cutoffSolution(scip, sol, conshdlrdata) );
828 addOne(&conshdlrdata->nsols); /*lint !e545*/
829 conshdlrdata->nNonSparseSols++;
830 if( conshdlrdata->collect )
831 {
832 SCIP_CALL( collectSolution(scip, conshdlrdata, sol) );
833 }
834 }
835 else
836 conshdlrdata->nDiscardSols++;
837
838 return SCIP_OKAY;
839}
840
841
842/** checks if the new solution is feasible for the logicor constraints */
843static
845 SCIP* scip, /**< SCIP data structure */
846 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
847 int nconss, /**< number of enabled constraints */
848 SCIP_Bool* satisfied /**< pointer to store if the logicor constraints a satisfied */
849 )
850{
851 /**@note the logicor constraints are not fully propagated; therefore, we have to check
852 * them by hand if they are satisfied or not; if a constraint is satisfied we
853 * delete it locally from the branch and bound tree.
854 */
855
856 SCIP_CONS** conss;
857 SCIP_VAR** vars;
858 SCIP_Bool fixedone;
859 int nvars;
860 int c;
861 int v;
862
863 SCIPdebugMsg(scip, "check logicor %d constraints\n", nconss);
864
865 assert( scip != NULL );
866 assert( conshdlr != NULL );
867 assert( nconss == SCIPconshdlrGetNEnabledConss(conshdlr) );
868
869 SCIP_STRINGEQ( SCIPconshdlrGetName(conshdlr), "logicor", SCIP_INVALIDCALL );
870
871 conss = SCIPconshdlrGetConss(conshdlr);
872 assert( conss != NULL );
873
874 (*satisfied) = TRUE;
875 c = SCIPconshdlrGetNActiveConss(conshdlr) - 1;
876
877 for( ; c >= 0 && nconss > 0 && (*satisfied); --c )
878 {
879 SCIPdebugMsg(scip, "logicor constraint %d\n", c);
880
881 if( !SCIPconsIsEnabled(conss[c]) )
882 continue;
883
884 nconss--;
885
886 nvars = SCIPgetNVarsLogicor(scip, conss[c]);
887 vars = SCIPgetVarsLogicor(scip, conss[c]);
888
889 /* calculate the constraint's activity */
890 fixedone = FALSE;
891 for( v = 0; v < nvars && !fixedone; ++v )
892 {
894
895 if( !varIsUnfixedLocal(vars[v] ) )
896 fixedone = SCIPvarGetLbLocal(vars[v]) > 0.5;
897 }
898
899 if( !fixedone )
900 {
901 SCIPdebugMsg(scip, "constraint <%s> cannot be disabled\n", SCIPconsGetName(conss[c]));
902 SCIPdebugPrintCons(scip, conss[c], NULL);
903 (*satisfied) = FALSE;
904 }
905 else
906 {
907 /* delete constraint from the problem locally since it is satisfied */
908 SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
909 }
910 }
911
912 return SCIP_OKAY;
913}
914
915
916/** checks if the new solution is feasible for the knapsack constraints */
917static
919 SCIP* scip, /**< SCIP data structure */
920 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
921 int nconss, /**< number of enabled constraints */
922 SCIP_Bool* satisfied /**< pointer to store if the logicor constraints a satisfied */
923 )
924{
925 /**@note the knapsack constraints are not fully propagated; therefore, we have to check
926 * them by hand if they are satisfied or not; if a constraint is satisfied we
927 * delete it locally from the branch and bound tree.
928 */
929
930 SCIP_CONS** conss;
931 SCIP_VAR** vars;
932 SCIP_Longint* weights;
933 SCIP_Longint capacity;
934 SCIP_Real capa;
935 int nvars;
936 int c;
937 int v;
938
939 SCIPdebugMsg(scip, "check knapsack %d constraints\n", nconss);
940
941 assert( scip != NULL );
942 assert( conshdlr != NULL );
943 assert( nconss == SCIPconshdlrGetNEnabledConss(conshdlr) );
944
945 SCIP_STRINGEQ( SCIPconshdlrGetName(conshdlr), "knapsack", SCIP_INVALIDCALL );
946
947 conss = SCIPconshdlrGetConss(conshdlr);
948 assert( conss != NULL );
949
950 (*satisfied) = TRUE;
951 c = SCIPconshdlrGetNActiveConss(conshdlr) - 1;
952
953 for( ; c >= 0 && nconss > 0 && (*satisfied); --c )
954 {
955 SCIPdebugMsg(scip, "knapsack constraint %d\n", c);
956
957 if( !SCIPconsIsEnabled(conss[c]) )
958 continue;
959
960 nconss--;
961
962 nvars = SCIPgetNVarsKnapsack(scip, conss[c]);
963 vars = SCIPgetVarsKnapsack(scip, conss[c]);
964 capacity = SCIPgetCapacityKnapsack(scip, conss[c]);
965 weights = SCIPgetWeightsKnapsack(scip,conss[c]);
966
967 SCIPdebugMsg(scip, "knapsack capacity = %" SCIP_LONGINT_FORMAT "\n", capacity);
968
969 capa = capacity + 0.1;
970
971 for( v = nvars - 1; v >= 0 && capa >= 0 ; --v )
972 {
974 SCIPdebugMsg(scip, "weight = %" SCIP_LONGINT_FORMAT " :\n", weights[v]);
976
977 /* the weights should be greater or equal to zero */
978 assert( weights[v] >= 0);
979
980 if( !varIsUnfixedLocal(vars[v]) )
981 {
982 /* variable is fixed locally; therefore, subtract fixed variable value multiplied by
983 * the weight;
984 */
985 capa -= weights[v] * SCIPvarGetLbLocal(vars[v]);
986 }
987 else if( weights[v] >= 1 )
988 {
989 /* variable is unfixed and weight is greater than 0; therefore, subtract upper bound
990 * value multiplied by the weight
991 */
992 capa -= weights[v] * SCIPvarGetUbLocal(vars[v]);
993 }
994 }
995
996 if( SCIPisFeasLT(scip, capa, 0.0) )
997 {
998 SCIPdebugMsg(scip, "constraint %s cannot be disabled\n", SCIPconsGetName(conss[c]));
999 SCIPdebugPrintCons(scip, conss[c], NULL);
1000 (*satisfied) = FALSE;
1001 }
1002 else
1003 {
1004 /* delete constraint from the problem locally since it is satisfied */
1005 SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
1006 }
1007 }
1008 return SCIP_OKAY;
1009}
1010
1011
1012/** checks if the new solution is feasible for the bounddisjunction constraints */
1013static
1015 SCIP* scip, /**< SCIP data structure */
1016 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1017 int nconss, /**< number of enabled constraints */
1018 SCIP_Bool* satisfied /**< pointer to store if the logicor constraints a satisfied */
1019 )
1020{
1021 /**@note the bounddisjunction constraints are not fully propagated; therefore, we have to check
1022 * them by hand if they are satisfied or not; if a constraint is satisfied we
1023 * delete it locally from the branch and bound tree
1024 */
1025
1026 SCIP_CONS** conss;
1027 SCIP_VAR** vars;
1028 SCIP_BOUNDTYPE* boundtypes;
1029 SCIP_Real* bounds;
1030 SCIP_Bool satisfiedbound;
1031 int nvars;
1032 int c;
1033 int v;
1034
1035 assert( scip != NULL );
1036 assert( conshdlr != NULL );
1037 assert( nconss == SCIPconshdlrGetNEnabledConss(conshdlr) );
1038
1039 SCIP_STRINGEQ( SCIPconshdlrGetName(conshdlr), "bounddisjunction", SCIP_INVALIDCALL );
1040
1041 conss = SCIPconshdlrGetConss(conshdlr);
1042 assert( conss != NULL );
1043
1044 (*satisfied) = TRUE;
1045 c = SCIPconshdlrGetNActiveConss(conshdlr) - 1;
1046
1047 for( ; c >= 0 && nconss > 0 && (*satisfied); --c )
1048 {
1049 if( !SCIPconsIsEnabled(conss[c]) )
1050 continue;
1051
1052 nconss--;
1053 satisfiedbound = FALSE;
1054
1057
1058 boundtypes = SCIPgetBoundtypesBounddisjunction(scip, conss[c]);
1059 bounds = SCIPgetBoundsBounddisjunction(scip, conss[c]);
1060
1061 for( v = nvars-1; v >= 0 && !satisfiedbound; --v )
1062 {
1064
1065 /* variable should be in right bounds to delete constraint */
1066 if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
1067 satisfiedbound = SCIPisFeasGE(scip, SCIPvarGetLbLocal(vars[v]), bounds[v]);
1068 else
1069 {
1070 assert( boundtypes[v] == SCIP_BOUNDTYPE_UPPER );
1071 satisfiedbound = SCIPisFeasLE(scip, SCIPvarGetUbLocal(vars[v]), bounds[v]);
1072 }
1073 }
1074
1075 if( !satisfiedbound )
1076 {
1077 SCIPdebugMsg(scip, "constraint %s cannot be disabled\n", SCIPconsGetName(conss[c]));
1078 SCIPdebugPrintCons(scip, conss[c], NULL);
1079 (*satisfied) = FALSE;
1080 }
1081 else
1082 {
1083 /* delete constraint from the problem locally since it is satisfied */
1084 SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
1085 }
1086 }
1087 return SCIP_OKAY;
1088}
1089
1090
1091/** checks if the new solution is feasible for the varbound constraints */
1092static
1094 SCIP* scip, /**< SCIP data structure */
1095 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1096 int nconss, /**< number of enabled constraints */
1097 SCIP_Bool* satisfied /**< pointer to store if the logicor constraints a satisfied */
1098 )
1099{
1100 /**@note the varbound constraints are not fully propagated; therefore, we have to check
1101 * them by hand if they are satisfied or not; if a constraint is satisfied we
1102 * delete it locally from the branch and bound tree.
1103 */
1104
1105 SCIP_CONS** conss;
1106 SCIP_VAR* var;
1107 SCIP_VAR* vbdvar;
1108 SCIP_Real lhs;
1109 SCIP_Real rhs;
1110 SCIP_Real coef;
1111 int c;
1112
1113 SCIPdebugMsg(scip, "check varbound %d constraints\n", nconss);
1114
1115 assert( scip != NULL );
1116 assert( conshdlr != NULL );
1117 assert( nconss == SCIPconshdlrGetNEnabledConss(conshdlr) );
1118
1119 SCIP_STRINGEQ( SCIPconshdlrGetName(conshdlr), "varbound", SCIP_INVALIDCALL );
1120
1121 conss = SCIPconshdlrGetConss(conshdlr);
1122 assert( conss != NULL );
1123
1124 (*satisfied) = TRUE;
1125 c = SCIPconshdlrGetNActiveConss(conshdlr) - 1;
1126
1127 for( ; c >= 0 && nconss > 0 && (*satisfied); --c )
1128 {
1129 SCIPdebugMsg(scip, "varbound constraint %d\n", c);
1130
1131 if( !SCIPconsIsEnabled(conss[c]) )
1132 continue;
1133
1134 nconss--;
1135
1136 var = SCIPgetVarVarbound(scip, conss[c]);
1137 vbdvar = SCIPgetVbdvarVarbound(scip, conss[c]);
1138
1139 assert(SCIPvarIsIntegral(vbdvar));
1140
1141 coef = SCIPgetVbdcoefVarbound(scip, conss[c]);
1142 lhs = SCIPgetLhsVarbound(scip, conss[c]);
1143 rhs = SCIPgetRhsVarbound(scip, conss[c]);
1144
1145 /* variables y is fixed locally; therefore, subtract fixed variable value multiplied by
1146 * the coefficient;
1147 */
1148 if(SCIPisGT(scip, SCIPvarGetUbLocal(var), rhs - SCIPvarGetUbLocal(vbdvar) * coef )
1149 || !SCIPisGE(scip, SCIPvarGetLbLocal(var), lhs - SCIPvarGetLbLocal(vbdvar) * coef ) )
1150 {
1151 SCIPdebugMsg(scip, "constraint %s cannot be disabled\n", SCIPconsGetName(conss[c]));
1152 SCIPdebugPrintCons(scip, conss[c], NULL);
1153 SCIPdebugMsg(scip, "<%s> lb: %.15g\t ub: %.15g\n", SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var));
1154 SCIPdebugMsg(scip, "<%s> lb: %.15g\t ub: %.15g\n", SCIPvarGetName(vbdvar), SCIPvarGetLbLocal(vbdvar), SCIPvarGetUbLocal(vbdvar));
1155 (*satisfied) = FALSE;
1156 }
1157 else
1158 {
1159 /* delete constraint from the problem locally since it is satisfied */
1160 SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
1161 }
1162 }
1163
1164 return SCIP_OKAY;
1165}
1166
1167
1168/** check if the current node initializes a non trivial unrestricted subtree */
1169static
1171 SCIP* scip, /**< SCIP main data structure */
1172 SCIP_SOL* sol, /**< solution to check */
1173 SCIP_Bool* feasible /**< pointer to store the result of the check */
1174 )
1175{
1176 int h;
1177
1178 SCIP_CONSHDLR** conshdlrs;
1179 int nconshdlrs;
1180
1181 SCIP_CONSHDLR* conshdlr;
1182 int nconss;
1183
1184 SCIPdebugMsg(scip, "check if the sparse solution is feasible\n");
1185
1186 assert( scip != NULL );
1187 assert( sol != NULL );
1188 assert( feasible != NULL );
1189
1191
1192 *feasible = FALSE;
1193
1194 nconshdlrs = SCIPgetNConshdlrs(scip) - 1;
1195 conshdlrs = SCIPgetConshdlrs(scip);
1196 assert(conshdlrs != NULL);
1197
1198 /* check each constraint handler if there are constraints which are not enabled */
1199 for( h = nconshdlrs ; h >= 0 ; --h )
1200 {
1201 conshdlr = conshdlrs[h];
1202 assert( conshdlr != NULL );
1203
1204 /* skip this constraints handler */
1205 if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 )
1206 continue;
1207
1208 nconss = SCIPconshdlrGetNEnabledConss(conshdlr);
1209
1210 if( nconss > 0 )
1211 {
1212 SCIP_Bool satisfied;
1213
1214 SCIPdebugMsg(scip, "constraint handler %s has %d active constraint(s)\n",
1215 SCIPconshdlrGetName(conshdlr), nconss );
1216
1217 if( strcmp(SCIPconshdlrGetName(conshdlr), "logicor") == 0 )
1218 {
1219 SCIP_CALL( checkLogicor(scip, conshdlr, nconss, &satisfied) );
1220 if( !satisfied )
1221 {
1222 SCIPdebugMsg(scip, "a <logicor> constraint cannot be disabled\n");
1223 return SCIP_OKAY;
1224 }
1225 }
1226 else if( strcmp(SCIPconshdlrGetName(conshdlr), "knapsack") == 0 )
1227 {
1228 SCIP_CALL( checkKnapsack(scip, conshdlr, nconss, &satisfied) );
1229 if( !satisfied )
1230 {
1231 SCIPdebugMsg(scip, "a <knapsack> constraint cannot be disabled\n");
1232 return SCIP_OKAY;
1233 }
1234 }
1235 else if( strcmp(SCIPconshdlrGetName(conshdlr), "bounddisjunction") == 0 )
1236 {
1237 SCIP_CALL( checkBounddisjunction(scip, conshdlr, nconss, &satisfied) );
1238 if( !satisfied )
1239 {
1240 SCIPdebugMsg(scip, "a <bounddisjunction> constraint cannot be disabled\n");
1241 return SCIP_OKAY;
1242 }
1243 }
1244 else if( strcmp(SCIPconshdlrGetName(conshdlr), "varbound") == 0 )
1245 {
1246 SCIP_CALL( checkVarbound(scip, conshdlr, nconss, &satisfied) );
1247 if( !satisfied )
1248 {
1249 SCIPdebugMsg(scip, "a <varbound> constraint cannot be disabled\n");
1250 return SCIP_OKAY;
1251 }
1252 }
1253 else
1254 {
1255 SCIPdebugMsg(scip, "sparse solution is infeasible since the following constraint (and maybe more) is(/are) enabled\n");
1257 return SCIP_OKAY;
1258 }
1259 }
1260 }
1261
1262 *feasible = TRUE;
1263 SCIPdebugMsg(scip, "sparse solution is feasible\n");
1264
1265 return SCIP_OKAY;
1266}
1267
1268
1269/** check the given solution */
1270static
1272 SCIP* scip, /**< SCIP data structure */
1273 SCIP_SOL* sol, /**< solution to add */
1274 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
1275 SCIP_RESULT* result /**< pointer to store the result of the checking process */
1276 )
1277{
1278 SCIP_Longint nsols;
1279 SCIP_Bool feasible;
1281
1282 SCIPdebugMsg(scip, "start to add sparse solution\n");
1283
1284 assert( scip != NULL );
1285 assert( sol != NULL );
1286 assert( conshdlrdata != NULL );
1287 assert( result != NULL );
1288
1289 /* the solution should not be found through a heuristic since in this case the information of SCIP is not valid for
1290 * this solution
1291 */
1292
1293 /**@todo it might be not necessary to check this assert since we can check in general all solutions of feasibility
1294 * independently of the origin; however, the locally fixed technique does only work if the solution comes from
1295 * the branch and bound tree; in case the solution comes from a heuristic we should try to sequentially fix the
1296 * variables in the branch and bound tree and check after every fixing if all constraints are disabled; at the
1297 * point where all constraints are disabled the unfixed variables are "stars" (arbitrary);
1298 */
1300
1301 /* setting result to infeasible since we reject any solution; however, if the solution passes the sparse test or is
1302 * completely fixed, the result is set to SCIP_CUTOFF which cuts off the subtree initialized through the current node
1303 */
1305
1306#ifdef SCIP_DEBUG
1307 {
1308 SCIP_VAR* var;
1309 SCIP_VAR** vars;
1310 int v;
1311 int nvars;
1312
1315
1316 for( v = 0; v < nvars; ++v )
1317 {
1318 var = vars[v];
1319 SCIPdebugMsg(scip, "variables <%s> Local Bounds are [%g,%g] Global Bounds are [%g,%g]\n",
1321 }
1322 }
1323#endif
1324
1325 /* check if integer variables are completely fixed */
1327 {
1328 /* check solution original space */
1329 checkSolutionOrig(scip, sol, conshdlrdata);
1330
1331 addOne(&conshdlrdata->nsols); /*lint !e545*/
1332 conshdlrdata->nNonSparseSols++;
1333
1334 SCIPdebugMsg(scip, "-> add one to number of solutions\n");
1335
1336 if( conshdlrdata->collect )
1337 {
1338 SCIP_CALL( collectSolution(scip, conshdlrdata, sol) );
1339 }
1340
1341 /* in case of continuous variables are present we explicitly cutoff the integer assignment since in case of
1342 * nonlinear constraint we want to avoid to count that integer assignment again
1343 */
1344 if( conshdlrdata->continuous )
1345 {
1346 SCIP_CALL( conshdlrdata->cutoffSolution(scip, sol, conshdlrdata) );
1347 }
1348
1349 /* since all integer are fixed, we cut off the subtree */
1351 }
1352 else if( conshdlrdata->sparsetest )
1353 {
1354 SCIP_CALL( checkFeasSubtree(scip, sol, &feasible) ) ;
1355 SCIP_CALL( countSparseSol(scip, sol, feasible, conshdlrdata, result) );
1356 }
1357
1358 /* transform the current number of solutions into a SCIP_Longint */
1359 nsols = getNCountedSols(conshdlrdata->nsols, &valid);
1360
1361 /* check if the solution limit is hit and stop SCIP if this is the case */
1362 if( conshdlrdata->sollimit > -1 && (!valid || conshdlrdata->sollimit <= nsols) )
1363 {
1365 }
1366
1368 SCIPdebugMsg(scip, "result is %s\n", *result == SCIP_INFEASIBLE ? "SCIP_INFEASIBLE" : "SCIP_CUTOFF" );
1369
1370 return SCIP_OKAY;
1371}
1372
1373/*
1374 * Callback methods of constraint handler
1375 */
1376
1377/** creates the handler for countsols constraints and includes it in SCIP */
1378static
1380 SCIP* scip, /**< SCIP data structure */
1381 SCIP_Bool dialogs /**< sould count dialogs be added */
1382 );
1383
1384/** copy method for constraint handler plugins (called when SCIP copies plugins) */
1385static
1386SCIP_DECL_CONSHDLRCOPY(conshdlrCopyCountsols)
1387{ /*lint --e{715}*/
1388 SCIP_CONSHDLRDATA* conshdlrdata;
1389
1390 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1391 assert(conshdlrdata != NULL);
1392
1393 /* in case the countsols constraint handler is active we avoid copying to ensure a safe count */
1394 if( conshdlrdata->active )
1395 *valid = FALSE;
1396 else
1397 {
1398 assert(scip != NULL);
1399 assert(conshdlr != NULL);
1400
1402
1403 /* call inclusion method of constraint handler and do not add counting dialogs */
1405
1406 *valid = TRUE;
1407 }
1408
1409 return SCIP_OKAY;
1410}
1411
1412#define consCopyCountsols NULL
1413
1414/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
1415static
1416SCIP_DECL_CONSFREE(consFreeCountsols)
1417{ /*lint --e{715}*/
1418 SCIP_CONSHDLRDATA* conshdlrdata;
1419
1420 assert(conshdlr != NULL);
1421
1423
1424 /* free constraint handler data */
1425 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1426 assert(conshdlrdata != NULL);
1427
1428 /* free conshdlrdata */
1429 freeInt(&conshdlrdata->nsols); /*lint !e545*/
1430
1431 assert( conshdlrdata->solutions == NULL );
1432 assert( conshdlrdata->nsolutions == 0 );
1433 assert( conshdlrdata->ssolutions == 0 );
1434
1435 SCIPfreeBlockMemory(scip, &conshdlrdata);
1436 SCIPconshdlrSetData(conshdlr, NULL);
1437
1438 return SCIP_OKAY;
1439}
1440
1441/** initialization method of constraint handler (called after problem was transformed) */
1442static
1443SCIP_DECL_CONSINIT(consInitCountsols)
1444{ /*lint --e{715}*/
1445 SCIP_CONSHDLRDATA* conshdlrdata;
1446
1447 assert( conshdlr != NULL );
1448
1450
1451 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1452 assert(conshdlrdata != NULL );
1453
1454 /* reset counting variables */
1455 conshdlrdata->feasST = 0; /* number of non trivial unrestricted subtrees */
1456 conshdlrdata->nDiscardSols = 0; /* number of discard solutions */
1457 conshdlrdata->nNonSparseSols = 0; /* number of non sparse solutions */
1458 setInt(&conshdlrdata->nsols, 0LL); /* number of solutions */ /*lint !e545*/
1459
1460 conshdlrdata->solutions = NULL;
1461 conshdlrdata->nsolutions = 0;
1462 conshdlrdata->ssolutions = 0;
1463
1464 if( conshdlrdata->active )
1465 {
1466 SCIP_VAR** origvars;
1467 int norigvars;
1468 int nallvars;
1469 int v;
1470
1471 origvars = SCIPgetOrigVars(scip);
1472 norigvars = SCIPgetNOrigVars(scip);
1473
1474 /* get number of integral variables */
1475 conshdlrdata->nallvars = SCIPgetNVars(scip) - SCIPgetNContVars(scip);
1476
1477 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &conshdlrdata->allvars, conshdlrdata->nallvars) );
1478
1479 nallvars = 0;
1480
1481 /* capture and lock all variables */
1482 for( v = 0; v < norigvars; ++v )
1483 {
1484 if( SCIPvarIsIntegral(origvars[v]) )
1485 {
1486 assert(nallvars < conshdlrdata->nallvars);
1487
1488 SCIP_CALL( SCIPgetTransformedVar(scip, origvars[v], &conshdlrdata->allvars[nallvars]) );
1489 assert(conshdlrdata->allvars[nallvars] != NULL);
1490
1491 /* capture variable to ensure that the variable will not be deleted */
1492 SCIP_CALL( SCIPcaptureVar(scip, conshdlrdata->allvars[nallvars]) );
1493
1494 if( strncmp(SCIPvarGetName(conshdlrdata->allvars[nallvars]), "t_andresultant_", strlen("t_andresultant_")) != 0 )
1495 {
1496 /* lock variable to avoid dual reductions */
1497 SCIP_CALL( SCIPaddVarLocksType(scip, conshdlrdata->allvars[nallvars], SCIP_LOCKTYPE_MODEL, 1, 1) );
1498 }
1499
1500 nallvars++;
1501 }
1502 }
1503 assert(nallvars == conshdlrdata->nallvars);
1504
1505 /* check if continuous variables are present */
1506 conshdlrdata->continuous = SCIPgetNContVars(scip) > 0;
1507 }
1508
1509 return SCIP_OKAY;
1510}
1511
1512/** deinitialization method of constraint handler (called before transformed problem is freed) */
1513static
1514SCIP_DECL_CONSEXIT(consExitCountsols)
1515{ /*lint --e{715}*/
1516 SCIP_CONSHDLRDATA* conshdlrdata;
1517 int s;
1518 int v;
1519
1520 assert( conshdlr != NULL );
1521
1523
1524 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1525 assert(conshdlrdata != NULL );
1526
1527 /* release variables to hashmap */
1528 for( v = conshdlrdata->nvars - 1; v >= 0; --v )
1529 {
1530 SCIP_CALL( SCIPreleaseVar(scip, &(conshdlrdata->vars[v])) );
1531 }
1532
1533 if( conshdlrdata->hashmap != NULL)
1534 {
1535 /* free hashmap of active variables to pistions */
1536 SCIPhashmapFree(&(conshdlrdata->hashmap));
1537 }
1538
1539 /* free active variables */
1540 SCIPfreeBlockMemoryArrayNull(scip, &(conshdlrdata->vars), conshdlrdata->nvars);
1541 conshdlrdata->nvars = 0;
1542
1543 if( conshdlrdata->allvars != NULL )
1544 {
1545 /* release and unlock all variables */
1546 for( v = 0; v < conshdlrdata->nallvars; ++v )
1547 {
1548 if( strncmp(SCIPvarGetName(conshdlrdata->allvars[v]), "t_andresultant_", strlen("t_andresultant_")) != 0 )
1549 {
1550 /* remove the previously added variable locks */
1551 SCIP_CALL( SCIPaddVarLocksType(scip, conshdlrdata->allvars[v], SCIP_LOCKTYPE_MODEL, -1, -1) );
1552 }
1553
1554 SCIP_CALL( SCIPreleaseVar(scip, &conshdlrdata->allvars[v]) );
1555 }
1556
1557 SCIPfreeBlockMemoryArrayNull(scip, &conshdlrdata->allvars, conshdlrdata->nallvars);
1558 conshdlrdata->nallvars = 0;
1559 }
1560
1561 if( conshdlrdata->nsolutions > 0 )
1562 {
1563 for( s = conshdlrdata->nsolutions - 1; s >= 0 ; --s )
1564 {
1565 SCIPsparseSolFree(&(conshdlrdata->solutions[s]));
1566 }
1567
1568 SCIPfreeMemoryArrayNull(scip, &conshdlrdata->solutions);
1569 conshdlrdata->nsolutions = 0;
1570 conshdlrdata->ssolutions = 0;
1571
1572 assert( conshdlrdata->solutions == NULL );
1573 }
1574 conshdlrdata->continuous = FALSE;
1575
1576 assert( conshdlrdata->solutions == NULL );
1577 assert( conshdlrdata->nsolutions == 0 );
1578 assert( conshdlrdata->ssolutions == 0 );
1579
1580 return SCIP_OKAY;
1581}
1582
1583
1584/** solving process initialization method of constraint handler (called when branch and bound process is about to begin)
1585 *
1586 * This method is called when the presolving was finished and the branch and bound process is about to begin.
1587 * The constraint handler may use this call to initialize its branch and bound specific data.
1588 */
1589static
1590SCIP_DECL_CONSINITSOL(consInitsolCountsols)
1591{ /*lint --e{715}*/
1592 SCIP_CONSHDLRDATA* conshdlrdata;
1593
1594 assert( conshdlr != NULL );
1595
1597
1598 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1599 assert(conshdlrdata != NULL );
1600
1601 if( conshdlrdata->active && SCIPgetNVars(scip) >= 1 )
1602 {
1603 SCIP_VAR** vars;
1604 int v;
1605
1606 assert(conshdlrdata->nsolutions == 0);
1607 assert(conshdlrdata->solutions == NULL);
1608
1609 conshdlrdata->nvars = SCIPgetNVars(scip) - SCIPgetNContVars(scip);
1611
1612 /* exclude upgrade continuous original variables */
1613 for( v = conshdlrdata->nvars - 1; v >= 0; --v )
1614 {
1615 SCIP_VAR* origvar;
1616 SCIP_Real scalar = 1.0;
1617 SCIP_Real constant = 0.0;
1618
1619 origvar = vars[v];
1620
1621 /* get original variable to decide if we will count the domain; continuous variables aren't counted */
1622 SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
1623
1624 if( origvar != NULL && SCIPvarIsIntegral(origvar) )
1625 break;
1626 }
1627 conshdlrdata->nvars = v + 1;
1628
1629 /* @todo we need to forbid variable downgrading, from integer type to implicit integer type, e.g. done in
1630 * cons_linear
1631 */
1632#ifndef NDEBUG
1633 for( v = conshdlrdata->nvars - 1; v >= 0; --v )
1634 {
1635 SCIP_VAR* origvar;
1636 SCIP_Real scalar = 1.0;
1637 SCIP_Real constant = 0.0;
1638
1639 origvar = vars[v];
1640
1641 /* get original variable to decide if we will count the domain; continuous variables aren't counted */
1642 SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
1643
1644 assert(origvar != NULL && SCIPvarIsIntegral(origvar));
1645 }
1646#endif
1647
1648 /* copy array of active variables */
1649 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(conshdlrdata->vars), vars, conshdlrdata->nvars) );
1650
1651 /* store mapping from all active variables to their position afetr presolving because during solving new variables
1652 * might be added and therefore could destroy writing collected solutions
1653 */
1654 SCIP_CALL( SCIPhashmapCreate(&(conshdlrdata->hashmap), SCIPblkmem(scip), conshdlrdata->nvars + 1) );
1655
1656 /* add variables to hashmap */
1657 for( v = conshdlrdata->nvars - 1; v >= 0; --v )
1658 {
1659 assert(SCIPvarGetProbindex(conshdlrdata->vars[v]) == v);
1660 SCIP_CALL( SCIPhashmapInsertInt(conshdlrdata->hashmap, conshdlrdata->vars[v], v+1) );
1661 SCIP_CALL( SCIPcaptureVar(scip, conshdlrdata->vars[v]) );
1662 }
1663
1664 /* check if the problem is binary (ignoring continuous variables) */
1666 conshdlrdata->cutoffSolution = addBinaryCons;
1667 else
1668 conshdlrdata->cutoffSolution = addIntegerCons;
1669 }
1670
1671 return SCIP_OKAY;
1672}
1673
1674/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
1675static
1676SCIP_DECL_CONSEXITSOL(consExitsolCountsols)
1677{ /*lint --e{715}*/
1678 SCIP_CONSHDLRDATA* conshdlrdata;
1679
1680 assert(scip != NULL);
1681 assert(conshdlr != NULL);
1682 assert(nconss == 0);
1683
1685
1686 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1687 assert(conshdlrdata != NULL );
1688
1689 if( conshdlrdata->active && restart )
1690 {
1691 SCIPerrorMessage("When collecting and counting solutions restarts need to be disabled (presolving/maxrestarts = 0).\n");
1692 SCIPABORT();
1693 return SCIP_INVALIDCALL; /*lint !e527*/
1694 }
1695
1696 return SCIP_OKAY;
1697}
1698
1699/** constraint enforcing method of constraint handler for LP solutions */
1700static
1701SCIP_DECL_CONSENFOLP(consEnfolpCountsols)
1702{ /*lint --e{715}*/
1703 SCIP_CONSHDLRDATA* conshdlrdata;
1704
1705 SCIPdebugMsg(scip, "method SCIP_DECL_CONSENFOLP(consEnfolpCountsols)\n");
1706
1707 assert( scip != NULL );
1708 assert( conshdlr != NULL );
1709 assert( nconss == 0 );
1710
1711 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1712 assert( conshdlrdata != NULL );
1713
1714 if( conshdlrdata->active )
1715 {
1716 if( !solinfeasible )
1717 {
1718 SCIP_SOL* sol;
1719
1721
1722 SCIP_CALL( checkSolution(scip, sol, conshdlrdata, result) );
1724 }
1725 else
1727 }
1728 else
1730
1731 assert( !conshdlrdata->active || *result == SCIP_INFEASIBLE || *result == SCIP_CUTOFF );
1732
1733 return SCIP_OKAY;
1734}
1735
1736/** constraint enforcing method of constraint handler for relaxation solutions */
1737static
1738SCIP_DECL_CONSENFORELAX(consEnforelaxCountsols)
1739{ /*lint --e{715}*/
1740 SCIP_CONSHDLRDATA* conshdlrdata;
1741
1742 SCIPdebugMsg(scip, "method SCIP_DECL_CONSENFORELAX(consEnfolpCountsols)\n");
1743
1744 assert( scip != NULL );
1745 assert( conshdlr != NULL );
1746 assert( nconss == 0 );
1747
1748 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1749 assert( conshdlrdata != NULL );
1750
1751 if( conshdlrdata->active )
1752 {
1753 if( !solinfeasible )
1754 {
1755 SCIP_CALL( checkSolution(scip, sol, conshdlrdata, result) );
1756 }
1757 else
1759 }
1760 else
1762
1763 assert( !conshdlrdata->active || *result == SCIP_INFEASIBLE || *result == SCIP_CUTOFF );
1764
1765 return SCIP_OKAY;
1766}
1767
1768/** constraint enforcing method of constraint handler for pseudo solutions */
1769static
1770SCIP_DECL_CONSENFOPS(consEnfopsCountsols)
1771{ /*lint --e{715}*/
1772 SCIP_CONSHDLRDATA* conshdlrdata;
1773
1774 SCIPdebugMsg(scip, "method SCIP_DECL_CONSENFOPS(consEnfopsCountsols)\n");
1775
1776 assert( scip != NULL );
1777 assert( conshdlr != NULL );
1778 assert( nconss == 0 );
1779
1780 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1781 assert( conshdlrdata != NULL );
1782
1783 if( conshdlrdata->active )
1784 {
1785 if( !solinfeasible )
1786 {
1787 SCIP_SOL* sol;
1788
1790
1791 SCIP_CALL( checkSolution(scip, sol, conshdlrdata, result) );
1793 }
1794 else
1796 }
1797 else
1799
1800 assert( !conshdlrdata->active || *result == SCIP_INFEASIBLE || *result == SCIP_CUTOFF );
1801
1802 return SCIP_OKAY;
1803}
1804
1805
1806/** feasibility check method of constraint handler for integral solutions */
1807static
1808SCIP_DECL_CONSCHECK(consCheckCountsols)
1809{ /*lint --e{715}*/
1810 /**@todo non-trivial solutions which are only checked have to be ignored since it is unknown how they are generated;
1811 * calculating heuristic solutions should be avoided */
1812 SCIP_CONSHDLRDATA* conshdlrdata;
1813
1814 SCIPdebugMsg(scip, "method SCIP_DECL_CONSCHECK(consCheckCountsols)\n");
1815
1816 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1817 assert( conshdlrdata != NULL );
1818
1819 if( conshdlrdata->active )
1820 {
1821 /* count empty solution */
1822 if( SCIPgetNVars(scip) == 0 )
1823 SCIP_CALL( checkSolution(scip, sol, conshdlrdata, result) );
1824 else if( !conshdlrdata->warning )
1825 {
1826 SCIPwarningMessage(scip, "a non-trivial solution comes in over <SCIP_DECL_CONSCHECK(consCheckCountsols)>; currently these solutions are ignored.\n");
1827 conshdlrdata->warning = TRUE;
1828 }
1829
1831 }
1832 else
1834
1835 return SCIP_OKAY;
1836}
1837
1838
1839/** variable rounding lock method of constraint handler */
1840static
1841SCIP_DECL_CONSLOCK(consLockCountsols)
1842{ /*lint --e{715}*/
1843 return SCIP_OKAY;
1844}
1845
1846
1847/*
1848 * Callback methods and local method for dialogs
1849 */
1850
1851/** dialog execution method for the count command */
1852SCIP_DECL_DIALOGEXEC(SCIPdialogExecCountPresolve)
1853{ /*lint --e{715}*/
1855 int usesymmetry;
1856
1857 SCIP_CALL( SCIPgetIntParam(scip, "misc/usesymmetry", &usesymmetry) );
1858
1859 if ( usesymmetry != 0 )
1860 {
1861 int symcomptiming = 2;
1862
1863 /* get timing of symmetry computation */
1864 if ( ((unsigned) usesymmetry & SYM_HANDLETYPE_SYMCONS) != 0 )
1865 {
1866 SCIP_CALL( SCIPgetIntParam(scip, "propagating/symmetry/addconsstiming", &symcomptiming) );
1867 }
1868 else if ( usesymmetry == 2 )
1869 {
1870 SCIP_CALL( SCIPgetIntParam(scip, "propagating/symmetry/ofsymcomptiming", &symcomptiming) );
1871 }
1872
1873 if ( symcomptiming < SYM_TIMING_AFTERPRESOL &&
1875 {
1876 SCIPerrorMessage("Symmetry handling and solution counting are not compatible. " \
1877 "You might want to disable symmetry by setting parameter <misc/usesymmetry> to 0.\n");
1878
1879 return SCIP_INVALIDCALL;
1880 }
1881
1882 SCIPwarningMessage(scip, "Symmetry handling has been deactivated since it is not compatible with counting.\n");
1883 SCIPwarningMessage(scip, "=> counting forces parameter <misc/usesymmetry> to 0.\n");
1884
1885 SCIP_CALL( SCIPsetIntParam(scip, "misc/usesymmetry", 0) );
1886 }
1887
1888 SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
1889 SCIPdialogMessage(scip, NULL, "\n");
1890 SCIP_CALL( SCIPgetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", &active) );
1891
1892 switch( SCIPgetStage(scip) )
1893 {
1894 case SCIP_STAGE_INIT:
1895 SCIPdialogMessage(scip, NULL, "no problem exists\n");
1896 break;
1897
1898 case SCIP_STAGE_PROBLEM:
1899 /* activate constraint handler cons_countsols */
1900 if( !active )
1901 {
1902 SCIP_CALL( SCIPsetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", TRUE) );
1903 }
1904 /*lint -fallthrough*/
1907 /* presolve problem */
1909
1910 /* reset cons_countsols activation */
1911 if( !active )
1912 {
1913 SCIP_CALL( SCIPsetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", FALSE) );
1914 }
1915 break;
1916
1918 case SCIP_STAGE_SOLVING:
1919 SCIPdialogMessage(scip, NULL, "problem is already presolved\n");
1920 break;
1921
1922 case SCIP_STAGE_SOLVED:
1923 SCIPdialogMessage(scip, NULL, "problem is already (pre)solved\n");
1924 break;
1925
1932 case SCIP_STAGE_FREE:
1933 default:
1934 SCIPerrorMessage("invalid SCIP stage\n");
1935 return SCIP_INVALIDCALL;
1936 } /*lint --e{616}*/
1937
1938 SCIPdialogMessage(scip, NULL, "\n");
1939 *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
1940
1941 return SCIP_OKAY;
1942}
1943
1944/** dialog execution method for the count command */
1945SCIP_DECL_DIALOGEXEC(SCIPdialogExecCount)
1946{ /*lint --e{715}*/
1947 SCIP_RETCODE retcode;
1949
1951 SCIP_Longint nsols;
1952 int displayprimalbound;
1953 int displaygap;
1954 int displaysols;
1955 int displayfeasST;
1956 int nrestarts;
1957 int usesymmetry;
1958
1959 SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
1960 SCIPdialogMessage(scip, NULL, "\n");
1961 SCIP_CALL( SCIPgetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", &active) );
1962 SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrestarts", &nrestarts) );
1963
1964 if( nrestarts != 0 )
1965 {
1966 /* need to disable restarts, since collecting solutions won't work, but also the capturing for variables is not
1967 * correctly handled
1968 */
1969 SCIPwarningMessage(scip, "counting forces parameter <presolving/maxrestarts> to 0.\n");
1970 if( SCIPisParamFixed(scip, "presolving/maxrestarts") )
1971 {
1972 SCIP_CALL( SCIPunfixParam(scip, "presolving/maxrestarts") );
1973 }
1974 SCIP_CALL( SCIPsetIntParam(scip, "presolving/maxrestarts", 0) );
1975 }
1976
1977 SCIP_CALL( SCIPgetIntParam(scip, "misc/usesymmetry", &usesymmetry) );
1978
1979 if ( usesymmetry != 0 )
1980 {
1981 int symcomptiming = 2;
1982
1983 /* get timing of symmetry computation */
1984 if ( ((unsigned) usesymmetry & SYM_HANDLETYPE_SYMCONS) != 0 )
1985 {
1986 SCIP_CALL( SCIPgetIntParam(scip, "propagating/symmetry/addconsstiming", &symcomptiming) );
1987 }
1988 else if ( usesymmetry == 2 )
1989 {
1990 SCIP_CALL( SCIPgetIntParam(scip, "propagating/symmetry/ofsymcomptiming", &symcomptiming) );
1991 }
1992
1993 if ( symcomptiming < SYM_TIMING_AFTERPRESOL &&
1995 {
1996 SCIPerrorMessage("Symmetry handling and solution counting are not compatible. " \
1997 "You might want to disable symmetry by setting parameter <misc/usesymmetry> to 0.\n");
1998
1999 return SCIP_INVALIDCALL;
2000 }
2001
2002 SCIPwarningMessage(scip, "Symmetry handling has been deactivated since it is not compatible with counting.\n");
2003 SCIPwarningMessage(scip, "=> counting forces parameter <misc/usesymmetry> to 0.\n");
2004
2005 SCIP_CALL( SCIPsetIntParam(scip, "misc/usesymmetry", 0) );
2006 }
2007
2008 switch( SCIPgetStage(scip) )
2009 {
2010 case SCIP_STAGE_INIT:
2011 SCIPdialogMessage(scip, NULL, "no problem exists\n");
2012 break;
2013
2014 case SCIP_STAGE_PROBLEM:
2015 /* activate constraint handler cons_countsols */
2016 if( !active )
2017 {
2018 SCIP_CALL( SCIPsetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", TRUE) );
2019 }
2020 /*lint -fallthrough*/
2023 /* presolve problem */
2025 /*lint -fallthrough*/
2027 /* reset activity status of constraint handler cons_countsols */
2028 if( !active )
2029 {
2030 SCIP_CALL( SCIPsetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", FALSE) );
2031 }
2032 /*lint -fallthrough*/
2033 case SCIP_STAGE_SOLVING:
2034 /* check if the problem contains continuous variables */
2035 if( SCIPgetNContVars(scip) != 0 )
2036 {
2038 "Problem contains continuous variables (after presolving). Counting projection to integral variables!\n");
2039 }
2040
2041 /* turn off primal bound and gap column */
2042 SCIP_CALL( SCIPgetIntParam(scip, "display/primalbound/active", &displayprimalbound) );
2043 if( displayprimalbound != 0 )
2044 {
2045 SCIP_CALL( SCIPsetIntParam(scip, "display/primalbound/active", 0) );
2046 }
2047 SCIP_CALL( SCIPgetIntParam(scip, "display/gap/active", &displaygap) );
2048 if( displaygap != 0 )
2049 {
2050 SCIP_CALL( SCIPsetIntParam(scip, "display/gap/active", 0) );
2051 }
2052
2053 /* turn on sols and feasST column */
2054 SCIP_CALL( SCIPgetIntParam(scip, "display/sols/active", &displaysols) );
2055 if( displayprimalbound != 2 )
2056 {
2057 SCIP_CALL( SCIPsetIntParam(scip, "display/sols/active", 2) );
2058 }
2059 SCIP_CALL( SCIPgetIntParam(scip, "display/feasST/active", &displayfeasST) );
2060 if( displayprimalbound != 2 )
2061 {
2062 SCIP_CALL( SCIPsetIntParam(scip, "display/feasST/active", 2) );
2063 }
2064
2065 /* find the countsols constraint handler */
2067
2068 retcode = SCIPcount(scip);
2069
2070 valid = FALSE;
2071 nsols = SCIPgetNCountedSols(scip, &valid);
2072
2073 if( valid )
2074 SCIPdialogMessage(scip, NULL, "Feasible Solutions : %" SCIP_LONGINT_FORMAT "", nsols);
2075 else
2076 {
2077 char* buffer;
2078 int buffersize = SCIP_MAXSTRLEN;
2079 int requiredsize;
2080
2081 SCIP_CALL( SCIPallocBufferArray(scip, &buffer, buffersize) );
2082 SCIPgetNCountedSolsstr(scip, &buffer, buffersize, &requiredsize);
2083
2084 if( requiredsize > buffersize )
2085 {
2086 SCIP_CALL( SCIPreallocBufferArray(scip, &buffer, requiredsize) );
2087 SCIPgetNCountedSolsstr(scip, &buffer, buffersize, &requiredsize);
2088 }
2089
2090 assert( buffersize >= requiredsize );
2091 SCIPdialogMessage(scip, NULL, "Feasible Solutions : %s", buffer);
2092
2093 SCIPfreeBufferArray(scip, &buffer);
2094 }
2095
2096 SCIPdialogMessage(scip, NULL, " (%" SCIP_LONGINT_FORMAT " non-trivial feasible subtrees)\n", SCIPgetNCountedFeasSubtrees(scip));
2097
2098 *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
2099
2100 /* reset display columns */
2101 if( displayprimalbound != 0 )
2102 {
2103 SCIP_CALL( SCIPsetIntParam(scip, "display/primalbound/active", displayprimalbound) );
2104 }
2105 if( displaygap != 0 )
2106 {
2107 SCIP_CALL( SCIPsetIntParam(scip, "display/gap/active", displaygap) );
2108 }
2109
2110 /* reset sols and feasST column */
2111 if( displaysols != 2 )
2112 {
2113 SCIP_CALL( SCIPsetIntParam(scip, "display/sols/active", displaysols) );
2114 }
2115 if( displayfeasST != 2 )
2116 {
2117 SCIP_CALL( SCIPsetIntParam(scip, "display/feasST/active", displayfeasST) );
2118 }
2119
2120 /* reset cons_countsols activation */
2121 if( !active )
2122 {
2123 SCIP_CALL( SCIPsetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", FALSE) );
2124 }
2125
2126 /* evaluate retcode */
2127 SCIP_CALL( retcode );
2128 break;
2129
2130 case SCIP_STAGE_SOLVED:
2131 SCIPdialogMessage(scip, NULL, "problem is already solved\n");
2132 break;
2133
2140 case SCIP_STAGE_FREE:
2141 default:
2142 SCIPerrorMessage("invalid SCIP stage\n");
2143 return SCIP_INVALIDCALL;
2144 } /*lint --e{616}*/
2145
2146 SCIPdialogMessage(scip, NULL, "\n");
2147 *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
2148
2149 return SCIP_OKAY;
2150}
2151
2152/** comparison method for sorting variables by non-decreasing w.r.t. problem index */
2153static
2154SCIP_DECL_SORTPTRCOMP(varCompProbindex)
2155{
2156 SCIP_VAR* var1;
2157 SCIP_VAR* var2;
2158
2159 var1 = (SCIP_VAR*)elem1;
2160 var2 = (SCIP_VAR*)elem2;
2161
2162 assert(var1 != NULL);
2163 assert(var2 != NULL);
2164
2165 if( SCIPvarGetProbindex(var1) < SCIPvarGetProbindex(var2) )
2166 return -1;
2167 else if( SCIPvarGetProbindex(var1) > SCIPvarGetProbindex(var2) )
2168 return +1;
2169 else
2170 {
2171 assert(var1 == var2 || (SCIPvarGetProbindex(var1) == -1 && SCIPvarGetProbindex(var2) == -1));
2172 return 0;
2173 }
2174}
2175
2176/** expands the sparse solutions and writes them to the file */
2177static
2179 SCIP* scip, /**< SCIP data structure */
2180 FILE* file, /**< file handler */
2181 SCIP_VAR** allvars, /**< SCIP variables */
2182 int nallvars, /**< number of all variables */
2183 SCIP_VAR** activevars, /**< SCIP variables */
2184 int nactivevars, /**< number of active variables */
2185 SCIP_HASHMAP* hashmap, /**< hashmap from active solution variable to the position in the active
2186 * variables array
2187 */
2188 SCIP_SPARSESOL** sols, /**< sparse solutions to expands and write */
2189 int nsols /**< number of sparse solutions */
2190 )
2191{
2192 SCIP_SPARSESOL* sparsesol;
2193 SCIP_VAR** vars;
2196 SCIP_Longint solcnt;
2197 int s;
2198 int v;
2199
2200 assert(scip != NULL);
2201 assert(file != NULL);
2202 assert(hashmap != NULL);
2203 assert(allvars != NULL || nallvars == 0);
2204 assert(activevars != NULL || nactivevars == 0);
2205 assert(sols != NULL || nsols == 0);
2206
2207 solcnt = 0;
2208
2209 /* get memory to store active solution */
2210 SCIP_CALL( SCIPallocBufferArray(scip, &sol, nactivevars) );
2211 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nactivevars) );
2212 SCIP_CALL( SCIPallocBufferArray(scip, &scalars, nactivevars) );
2213
2214 /* loop over all sparse solutions */
2215 for( s = 0; s < nsols; ++s )
2216 {
2217 sparsesol = sols[s]; /*lint !e613*/
2218 assert(sparsesol != NULL);
2219 assert(SCIPsparseSolGetNVars(sparsesol) == nactivevars);
2220
2221 /* get first solution of the sparse solution */
2222 SCIPsparseSolGetFirstSol(sparsesol, sol, nactivevars);
2223
2224 do
2225 {
2227
2228 solcnt++;
2229
2230 /* print solution number */
2231 SCIPinfoMessage(scip, file, "%d(%" SCIP_LONGINT_FORMAT "), ", s+1, solcnt);
2232
2233 objval = 0.0;
2234
2235 /* write none active variables */
2236 for( v = 0; v < nallvars; ++v )
2237 {
2238 SCIP_Real constant;
2239 SCIP_Real realvalue;
2240 int requiredsize;
2241 int nvars;
2242 int idx;
2243 int i;
2244
2245 vars[0] = allvars[v]; /*lint !e613*/
2246 scalars[0] = 1.0;
2247 nvars = 1;
2248 constant = 0.0;
2249
2250 SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, &nvars, nallvars, &constant, &requiredsize) );
2251 assert(requiredsize <= nallvars);
2252 assert(nvars <= nactivevars);
2253
2254 realvalue = constant;
2255
2256 for( i = 0; i < nvars; ++i )
2257 {
2258 assert(SCIPhashmapExists(hashmap, vars[i]));
2259 idx = SCIPhashmapGetImageInt(hashmap, vars[i]) - 1;
2260 assert(0 <= idx && idx < nactivevars);
2261 assert(activevars[idx] == vars[i]); /*lint !e613*/
2262
2263 objval += SCIPvarGetObj(vars[i]) * sol[idx];
2264 realvalue += scalars[i] * sol[idx];
2265 }
2266 assert(SCIPisIntegral(scip, realvalue));
2267
2268 SCIPinfoMessage(scip, file, "%g, ", realvalue);
2269 }
2270
2271 /* transform objective value into original problem space */
2273
2274 /* output the objective value of the solution */
2275 SCIPinfoMessage(scip, file, "%g\n", objval);
2276 }
2277 while( SCIPsparseSolGetNextSol(sparsesol, sol, nactivevars) );
2278 }
2279
2280 /* free buffer arrays */
2284
2285 return SCIP_OKAY;
2286}
2287
2288/** execution method of dialog for writing all solutions */
2289SCIP_DECL_DIALOGEXEC(SCIPdialogExecWriteAllsolutions)
2290{ /*lint --e{715}*/
2291 FILE* file;
2292 SCIP_Longint nsols;
2293 char* filename;
2294 char* word;
2295 SCIP_Bool endoffile;
2297
2298 assert( scip != NULL );
2299
2300 SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
2301
2302 switch( SCIPgetStage(scip) )
2303 {
2304 case SCIP_STAGE_INIT:
2305 SCIPdialogMessage(scip, NULL, "no problem available\n");
2306 break;
2307 case SCIP_STAGE_PROBLEM:
2310 SCIPdialogMessage(scip, NULL, "the counting process was not started yet\n");
2311 break;
2318 case SCIP_STAGE_SOLVING:
2319 case SCIP_STAGE_SOLVED:
2321 {
2322 SCIP_CONSHDLR* conshdlr;
2323 SCIP_CONSHDLRDATA* conshdlrdata;
2324 int nsparsesols;
2325
2326 valid = FALSE;
2327 nsols = SCIPgetNCountedSols(scip, &valid);
2328
2329 /* find the countsols constraint handler */
2330 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2331 assert( conshdlr != NULL );
2332
2333 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2334 assert( conshdlrdata != NULL );
2335
2336 nsparsesols = conshdlrdata->nsolutions;
2337
2338 if( !valid )
2339 {
2340 /* too many solutions, output not "possible" */
2341 char* buffer;
2342 int buffersize;
2343 int requiredsize;
2344
2345 buffersize = SCIP_MAXSTRLEN;
2346
2347 SCIP_CALL( SCIPallocBufferArray(scip, &buffer, buffersize) );
2348 SCIPgetNCountedSolsstr(scip, &buffer, buffersize, &requiredsize);
2349
2350 if( requiredsize > buffersize )
2351 {
2352 buffersize = requiredsize;
2353 SCIP_CALL( SCIPreallocBufferArray(scip, &buffer, requiredsize) );
2354 SCIPgetNCountedSolsstr(scip, &buffer, buffersize, &requiredsize);
2355 }
2356
2357 assert( buffersize >= requiredsize );
2358 SCIPdialogMessage(scip, NULL, "no output, because of too many feasible solutions : %s\n", buffer);
2359
2360 SCIPfreeBufferArray(scip, &buffer);
2361 }
2362 else if( nsols == 0 )
2363 {
2364 SCIPdialogMessage(scip, NULL, "there are no counted solutions\n");
2365 }
2366 else if( nsparsesols == 0 )
2367 {
2368 SCIPdialogMessage(scip, NULL, "there is no solution collect (set parameter <constraints/countsols/collect> to TRUE)\n");
2369 }
2370 else
2371 {
2372 SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, "enter filename: ", &word, &endoffile) );
2373
2374 /* copy the filename for later use */
2375 SCIP_CALL( SCIPduplicateBufferArray(scip, &filename, word, (int)strlen(word)+1) );
2376
2377 if( endoffile )
2378 {
2379 *nextdialog = NULL;
2380 return SCIP_OKAY;
2381 }
2382
2383 SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, filename, TRUE) );
2384
2385 if( filename[0] != '\0' )
2386 {
2387 file = fopen(filename, "w");
2388
2389 if( file == NULL )
2390 {
2391 SCIPdialogMessage(scip, NULL, "error creating file <%s>\n", filename);
2392 SCIPdialoghdlrClearBuffer(dialoghdlr);
2393 }
2394 else
2395 {
2396 SCIP_SPARSESOL** sparsesols;
2397 SCIP_VAR** origvars;
2398 SCIP_VAR** allvars;
2399 int norigvars;
2400 int nvars;
2401 int v;
2402
2403 SCIP_RETCODE retcode;
2404
2405 /* get sparse solutions defined over the active variables */
2406 nvars = conshdlrdata->nvars;
2407 sparsesols = conshdlrdata->solutions;
2408
2409 /* get original problem variables */
2410 retcode = SCIPallocBufferArray(scip, &origvars, SCIPgetNOrigVars(scip));
2411 if( retcode != SCIP_OKAY )
2412 {
2413 fclose(file);
2414 SCIP_CALL( retcode );
2415 }
2416
2417 norigvars = 0;
2418
2419 for( v = 0; v < SCIPgetNOrigVars(scip); ++v )
2420 {
2422 {
2423 origvars[norigvars] = SCIPgetOrigVars(scip)[v];
2424 norigvars++;
2425 }
2426 }
2427 assert(norigvars == conshdlrdata->nallvars);
2428
2429 retcode = SCIPduplicateBufferArray(scip, &allvars, conshdlrdata->allvars, norigvars);
2430 if( retcode != SCIP_OKAY )
2431 {
2432 fclose(file); /*lint !e449*/
2433 SCIP_CALL( retcode );
2434 }
2435
2436 /* sort original variables array and the corresponding transformed variables w.r.t. the problem index */
2437 SCIPsortDownPtrPtr((void**)allvars, (void**)origvars, varCompProbindex, norigvars);
2438
2439 SCIPdialogMessage(scip, NULL, "saving %" SCIP_LONGINT_FORMAT " (%d) feasible solutions\n", nsols, nsparsesols);
2440
2441 /* first row: output the names of the variables in the given ordering */
2442 SCIPinfoMessage(scip, file, "#, ");
2443
2444 for( v = 0; v < norigvars; ++v )
2445 {
2446#ifndef NDEBUG
2447 {
2448 /* check if the original variable fits to the transformed variable the constraint handler has stored */
2449 SCIP_VAR* transvar;
2450 SCIP_CALL( SCIPgetTransformedVar(scip, origvars[v], &transvar) );
2451 assert(transvar != NULL);
2452 assert(transvar == allvars[v]);
2453 }
2454#endif
2455 SCIPinfoMessage(scip, file, "%s, ", SCIPvarGetName(origvars[v]));
2456 }
2457
2458 SCIPinfoMessage(scip, file, "objval\n");
2459
2460 /* expand and write solution */
2461 retcode = writeExpandedSolutions(scip, file, allvars, conshdlrdata->nallvars, conshdlrdata->vars, nvars, conshdlrdata->hashmap, sparsesols, nsparsesols);
2462 if( retcode != SCIP_OKAY )
2463 {
2464 fclose(file);
2465 SCIP_CALL( retcode );
2466 }
2467 SCIPdialogMessage(scip, NULL, "written solutions information to file <%s>\n", filename);
2468
2469 SCIPfreeBufferArray(scip, &allvars);
2470 SCIPfreeBufferArray(scip, &origvars);
2471
2472 fclose(file);
2473 }
2474
2475 /* free buffer array */
2476 SCIPfreeBufferArray(scip, &filename);
2477 }
2478 }
2479 break;
2480 }
2481 case SCIP_STAGE_FREE:
2482 SCIPerrorMessage("invalid call during SCIP_STAGE_FREE\n");
2483 return SCIP_ERROR;
2484 }
2485
2486 *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
2487
2488 return SCIP_OKAY;
2489}
2490
2491/** create the interactive shell dialogs for the counting process */
2492static
2494 SCIP* scip /**< SCIP data structure */
2495 )
2496{
2497 SCIP_DIALOG* root;
2498 SCIP_DIALOG* dialog;
2499 SCIP_DIALOG* submenu;
2500
2501 root = SCIPgetRootDialog(scip);
2502
2503 /* skip dialogs if they seem to be disabled */
2504 if( root == NULL )
2505 return SCIP_OKAY;
2506
2507 /* add dialog entry for counting */
2508 if( !SCIPdialogHasEntry(root, "count") )
2509 {
2510 SCIP_CALL( SCIPincludeDialog(scip, &dialog, NULL, SCIPdialogExecCount, NULL, NULL,
2511 "count", "count number of feasible solutions", FALSE, NULL) );
2512 SCIP_CALL( SCIPaddDialogEntry(scip, root, dialog) );
2513 SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
2514 }
2515
2516 /* add dialog entry for counting */
2517 if( !SCIPdialogHasEntry(root, "countpresolve") )
2518 {
2519 SCIP_CALL( SCIPincludeDialog(scip, &dialog, NULL, SCIPdialogExecCountPresolve, NULL, NULL,
2520 "countpresolve", "presolve instance before counting number of feasible solutions", FALSE, NULL) );
2521 SCIP_CALL( SCIPaddDialogEntry(scip, root, dialog) );
2522 SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
2523 }
2524
2525 /* search for the "write" sub menu to add "allsolutions" dialog */
2526 if( SCIPdialogFindEntry(root, "write", &submenu) != 1 )
2527 {
2528 SCIPerrorMessage("write sub menu not found\n");
2529 return SCIP_PLUGINNOTFOUND;
2530 }
2531 assert(submenu != NULL);
2532
2533 /* add dialog "allsolutions" to sub menu "write" */
2534 if( !SCIPdialogHasEntry(submenu, "allsolutions") )
2535 {
2536 SCIP_CALL( SCIPincludeDialog(scip, &dialog, NULL, SCIPdialogExecWriteAllsolutions, NULL, NULL,
2537 "allsolutions", "write all counted primal solutions to file", FALSE, NULL) );
2538 SCIP_CALL( SCIPaddDialogEntry(scip, submenu, dialog) );
2539 SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
2540 }
2541
2542 return SCIP_OKAY;
2543}
2544
2545/*
2546 * Callback methods for columns
2547 */
2548
2549/** output method of display column to output file stream 'file' */
2550static
2552{ /*lint --e{715}*/
2553#ifndef NDEBUG
2554 SCIP_CONSHDLR* conshdlr;
2555#endif
2556 SCIP_Longint sols;
2558
2559 assert(disp != NULL);
2560 assert(scip != NULL);
2561
2563
2564#ifndef NDEBUG
2565 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2566 assert( conshdlr != NULL );
2567 assert( SCIPconshdlrGetNConss(conshdlr) == 0 );
2568#endif
2569
2570 sols = SCIPgetNCountedSols(scip, &valid);
2571
2572 if( !valid )
2573 {
2574 SCIPinfoMessage(scip, file, "TooMany");
2575 }
2576 else
2577 {
2579 }
2580
2581 return SCIP_OKAY;
2582}
2583
2584
2585/** output method of display column to output file stream 'file' */
2586static
2587SCIP_DECL_DISPOUTPUT(dispOutputFeasSubtrees)
2588{ /*lint --e{715}*/
2589#ifndef NDEBUG
2590 SCIP_CONSHDLR* conshdlr;
2591#endif
2592
2593 assert(disp != NULL);
2594 assert(scip != NULL);
2595
2597
2598#ifndef NDEBUG
2599 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2600 assert( conshdlr != NULL );
2601 assert( SCIPconshdlrGetNConss(conshdlr) == 0 );
2602#endif
2603
2605
2606 return SCIP_OKAY;
2607}
2608
2609
2610/*
2611 * Interface methods of constraint handler
2612 */
2613
2614/** creates the handler for countsols constraints and includes it in SCIP */
2615static
2617 SCIP* scip, /**< SCIP data structure */
2618 SCIP_Bool dialogs /**< sould count dialogs be added */
2619 )
2620{
2621 /* create countsol constraint handler data */
2622 SCIP_CONSHDLRDATA* conshdlrdata;
2623 SCIP_CONSHDLR* conshdlr;
2624
2625#ifdef SCIP_WITH_GMP
2626 char gmpversion[20];
2627#endif
2628
2629 /* create constraint handler specific data here */
2630 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata) );
2631
2632 /* include constraint handler */
2635 consEnfolpCountsols, consEnfopsCountsols, consCheckCountsols, consLockCountsols,
2636 conshdlrdata) );
2637
2638 assert(conshdlr != NULL);
2639
2640 /* set non-fundamental callbacks via specific setter functions */
2641 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyCountsols, consCopyCountsols) );
2642 SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitCountsols) );
2643 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolCountsols) );
2644 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeCountsols) );
2645 SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitCountsols) );
2646 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolCountsols) );
2647 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxCountsols) );
2648
2649 /* add countsols constraint handler parameters */
2651 "constraints/" CONSHDLR_NAME "/active",
2652 "is the constraint handler active?",
2653 &conshdlrdata->active, FALSE, DEFAULT_ACTIVE, NULL, NULL));
2655 "constraints/" CONSHDLR_NAME "/sparsetest",
2656 "should the sparse solution test be turned on?",
2657 &conshdlrdata->sparsetest, FALSE, DEFAULT_SPARSETEST, NULL, NULL));
2659 "constraints/" CONSHDLR_NAME "/discardsols",
2660 "is it allowed to discard solutions?",
2661 &conshdlrdata->discardsols, FALSE, DEFAULT_DISCARDSOLS, NULL, NULL));
2663 "constraints/" CONSHDLR_NAME "/collect",
2664 "should the solutions be collected?",
2665 &conshdlrdata->collect, FALSE, DEFAULT_COLLECT, NULL, NULL));
2667 "constraints/" CONSHDLR_NAME "/sollimit",
2668 "counting stops, if the given number of solutions were found (-1: no limit)",
2669 &conshdlrdata->sollimit, FALSE, DEFAULT_SOLLIMIT, -1LL, SCIP_LONGINT_MAX, NULL, NULL));
2670
2671 /* create the interactive shell dialogs for the counting process */
2672 if( dialogs )
2673 {
2675 }
2676
2677 /* include display column */
2679 NULL, NULL, NULL, NULL, NULL, NULL, dispOutputSols,
2682 NULL, NULL, NULL, NULL, NULL, NULL, dispOutputFeasSubtrees,
2684
2685#ifdef SCIP_WITH_GMP
2686#ifdef mpir_version
2687 /* add info about using MPIR to external codes information */
2688 (void) SCIPsnprintf(gmpversion, (int) sizeof(gmpversion), "MPIR %s", mpir_version);
2689 SCIP_CALL( SCIPincludeExternalCodeInformation(scip, gmpversion, "Multiple Precision Integers and Rationals Library developed by W. Hart (mpir.org)") );
2690#else
2691 /* add info about using GMP to external codes information */
2692 (void) SCIPsnprintf(gmpversion, (int) sizeof(gmpversion), "GMP %s", gmp_version);
2693 SCIP_CALL( SCIPincludeExternalCodeInformation(scip, gmpversion, "GNU Multiple Precision Arithmetic Library developed by T. Granlund (gmplib.org)") );
2694#endif
2695#endif
2696
2697 return SCIP_OKAY;
2698}
2699
2700/** creates the handler for countsols constraints and includes it in SCIP */
2702 SCIP* scip /**< SCIP data structure */
2703 )
2704{
2705 /* include constraint handler including the count dialog */
2707
2708 return SCIP_OKAY;
2709}
2710
2711
2712/** execute counting */
2714 SCIP* scip /**< SCIP data structure */
2715 )
2716{
2718
2719 /* activate constraint handler cons_countsols */
2720 SCIP_CALL( SCIPgetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", &active) );
2721 if( !active )
2722 {
2723 SCIP_CALL( SCIPsetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", TRUE) );
2724 }
2725
2726 /* check if the parameter setting allows a valid counting process */
2728
2729 /* start the solving process */
2731
2732 /* reset activity status of constraint handler cons_countsols */
2733 if( !active )
2734 {
2735 SCIP_CALL( SCIPsetBoolParam(scip, "constraints/" CONSHDLR_NAME "/active", FALSE) );
2736 }
2737
2738 return SCIP_OKAY;
2739}
2740
2741
2742/** returns number of feasible solutions found as SCIP_Longint; if the number does not fit into
2743 * a SCIP_Longint the valid flag is set to FALSE
2744 */
2746 SCIP* scip, /**< SCIP data structure */
2747 SCIP_Bool* valid /**< pointer to store if the return value is valid */
2748 )
2749{
2750 SCIP_CONSHDLR* conshdlr;
2751 SCIP_CONSHDLRDATA* conshdlrdata;
2752
2753 /* find the countsols constraint handler */
2754 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2755 assert( conshdlr != NULL );
2756
2757 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2758 assert( conshdlrdata != NULL );
2759
2760 return getNCountedSols(conshdlrdata->nsols, valid);
2761}
2762
2763
2764/** puts the number of counted solutions in the given char* buffer */
2766 SCIP* scip, /**< SCIP data structure */
2767 char** buffer, /**< buffer to store the number for counted solutions */
2768 int buffersize, /**< buffer size */
2769 int* requiredsize /**< pointer to store the required size */
2770 )
2771{
2772 SCIP_CONSHDLR* conshdlr;
2773 SCIP_CONSHDLRDATA* conshdlrdata;
2774
2775 /* find the countsols constraint handler */
2776 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2777 assert( conshdlr != NULL );
2778
2779 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2780 assert( conshdlrdata != NULL );
2781
2782#ifdef SCIP_WITH_GMP
2783 /* size must be by two larger than the length of the string, since there need to be storage for a sign and a
2784 * null-termination
2785 */
2786 assert(0 <= (int) (mpz_sizeinbase( conshdlrdata->nsols, 10 ) + 2));
2787 *requiredsize = (int) (mpz_sizeinbase( conshdlrdata->nsols, 10 ) + 2);
2788 if( *requiredsize <= buffersize)
2789 toString(conshdlrdata->nsols, buffer, buffersize);
2790#else
2791 if( conshdlrdata->nsols < pow(10.0, (double)buffersize) )
2792 {
2793 toString(conshdlrdata->nsols, buffer, buffersize);
2794 *requiredsize = (int)strlen(*buffer);
2795 }
2796 else
2797 *requiredsize = 21;
2798#endif
2799}
2800
2801
2802/** returns number of counted non trivial feasible subtrees */
2804 SCIP* scip /**< SCIP data structure */
2805 )
2806{
2807 SCIP_CONSHDLR* conshdlr;
2808 SCIP_CONSHDLRDATA* conshdlrdata;
2809
2810 assert( scip != NULL );
2811
2812 /* find the countsols constraint handler */
2813 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2814 assert( conshdlr != NULL );
2815
2816 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2817 assert( conshdlrdata != NULL );
2818
2819 return conshdlrdata->feasST;
2820}
2821
2822
2823/** Method to get the sparse solution.
2824 *
2825 * @note You get the pointer to the sparse solutions stored in the constraint handler (not a copy).
2826 *
2827 * @note The sparse solutions are stored w.r.t. the active variables. There are the variables which have not been removed
2828 * during presolving. For none active variables the value has to be computed depending on their aggregation
2829 * type. See for more details about that \ref COLLECTALLFEASEBLES.
2830 */
2832 SCIP* scip, /**< SCIP data structure */
2833 SCIP_VAR*** vars, /**< pointer to active variable array defining to variable order */
2834 int* nvars, /**< number of active variables */
2835 SCIP_SPARSESOL*** sols, /**< pointer to the solutions */
2836 int* nsols /**< pointer to number of solutions */
2837 )
2838{
2839 SCIP_CONSHDLR* conshdlr;
2840 SCIP_CONSHDLRDATA* conshdlrdata;
2841
2842 assert( scip != NULL );
2843
2844 /* find the countsols constraint handler */
2845 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2846 assert( conshdlr != NULL );
2847
2848 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2849 assert( conshdlrdata != NULL );
2850
2851 *vars = conshdlrdata->vars;
2852 *nvars = conshdlrdata->nvars;
2853 *sols = conshdlrdata->solutions;
2854 *nsols = conshdlrdata->nsolutions;
2855}
2856
2857/** setting SCIP parameters for such that a valid counting process is possible */
2859 SCIP* scip /**< SCIP data structure */
2860 )
2861{
2863 return SCIP_OKAY;
2864}
static GRAPHNODE ** active
SCIP_VAR * h
#define CONSHDLR_NEEDSCONS
Definition cons_and.c:96
#define CONSHDLR_CHECKPRIORITY
Definition cons_and.c:88
#define CONSHDLR_DESC
Definition cons_and.c:85
#define CONSHDLR_EAGERFREQ
Definition cons_and.c:91
#define CONSHDLR_ENFOPRIORITY
Definition cons_and.c:87
#define CONSHDLR_NAME
Definition cons_and.c:84
#define DEFAULT_ACTIVE
constraint handler for bound disjunction constraints
#define DISP_CUTS_NAME
#define DISP_SOLS_STRIPLINE
static SCIP_Longint getNCountedSols(Int value, SCIP_Bool *valid)
static SCIP_RETCODE createCountDialog(SCIP *scip)
#define DEFAULT_DISCARDSOLS
static void toString(Int value, char **buffer, int buffersize)
#define DISP_SOLS_PRIORITY
static SCIP_RETCODE checkFeasSubtree(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible)
#define DISP_CUTS_POSITION
static SCIP_RETCODE writeExpandedSolutions(SCIP *scip, FILE *file, SCIP_VAR **allvars, int nallvars, SCIP_VAR **activevars, int nactivevars, SCIP_HASHMAP *hashmap, SCIP_SPARSESOL **sols, int nsols)
static SCIP_RETCODE checkLogicor(SCIP *scip, SCIP_CONSHDLR *conshdlr, int nconss, SCIP_Bool *satisfied)
static void multInt(Int *value, SCIP_Longint factor)
#define DISP_CUTS_WIDTH
#define DISP_CUTS_HEADER
static void addInt(Int *value, Int *summand)
static SCIP_RETCODE checkSolution(SCIP *scip, SCIP_SOL *sol, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_RESULT *result)
#define CUTOFF_CONSTRAINT(x)
#define DISP_SOLS_WIDTH
#define DISP_SOLS_NAME
static SCIP_RETCODE collectSolution(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_SOL *sol)
#define DEFAULT_SPARSETEST
static void setInt(Int *value, SCIP_Longint newvalue)
static SCIP_RETCODE checkParameters(SCIP *scip)
#define DISP_SOLS_HEADER
static void checkSolutionOrig(SCIP *scip, SCIP_SOL *sol, SCIP_CONSHDLRDATA *conshdlrdata)
static void allocInt(Int *value)
#define DEFAULT_COLLECT
#define DISP_CUTS_DESC
#define DISP_CUTS_PRIORITY
static void addOne(Int *value)
static void freeInt(Int *value)
static SCIP_RETCODE checkVarbound(SCIP *scip, SCIP_CONSHDLR *conshdlr, int nconss, SCIP_Bool *satisfied)
#define DISP_CUTS_STRIPLINE
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
static void setPowerOfTwo(Int *value, SCIP_Longint exponent)
static SCIP_RETCODE includeConshdlrCountsols(SCIP *scip, SCIP_Bool dialogs)
#define DEFAULT_SOLLIMIT
static SCIP_Bool varIsUnfixedLocal(SCIP_VAR *var)
#define DISP_SOLS_DESC
static SCIP_RETCODE checkBounddisjunction(SCIP *scip, SCIP_CONSHDLR *conshdlr, int nconss, SCIP_Bool *satisfied)
SCIP_Longint Int
static SCIP_RETCODE checkKnapsack(SCIP *scip, SCIP_CONSHDLR *conshdlr, int nconss, SCIP_Bool *satisfied)
#define consCopyCountsols
static SCIP_RETCODE countSparseSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool feasible, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_RESULT *result)
#define DISP_SOLS_POSITION
Constraint handler for counting feasible solutions.
Constraint handler for knapsack constraints of the form , x binary and .
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
Constraint handler for the set partitioning / packing / covering constraints .
Constraint handler for variable bound constraints .
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#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_LONGINT_FORMAT
Definition def.h:157
#define SCIPABORT()
Definition def.h:336
#define SCIP_LONGINT_MAX
Definition def.h:151
#define SCIP_CALL(x)
Definition def.h:364
#define SCIP_CALL_FINALLY(x, y)
Definition def.h:406
default user interface dialog
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPgetBoundsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
void SCIPgetNCountedSolsstr(SCIP *scip, char **buffer, int buffersize, int *requiredsize)
SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, 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)
int SCIPgetNVarsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_BOUNDTYPE * SCIPgetBoundtypesBounddisjunction(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Longint SCIPgetNCountedSols(SCIP *scip, SCIP_Bool *valid)
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Longint SCIPgetNCountedFeasSubtrees(SCIP *scip)
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsSetcover(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, 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_RETCODE SCIPsetParamsCountsols(SCIP *scip)
SCIP_VAR ** SCIPgetVarsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcount(SCIP *scip)
void SCIPgetCountedSparseSols(SCIP *scip, SCIP_VAR ***vars, int *nvars, SCIP_SPARSESOL ***sols, int *nsols)
SCIP_RETCODE SCIPincludeConshdlrCountsols(SCIP *scip)
SCIP_STAGE SCIPgetStage(SCIP *scip)
int SCIPgetNContVars(SCIP *scip)
Definition scip_prob.c:2569
SCIP_VAR ** SCIPgetOrigVars(SCIP *scip)
Definition scip_prob.c:2811
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3274
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:2201
int SCIPgetNOrigVars(SCIP *scip)
Definition scip_prob.c:2838
int SCIPgetNBinVars(SCIP *scip)
Definition scip_prob.c:2293
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3095
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3304
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3061
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3466
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition misc.c:3179
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:4067
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
#define SCIPdebugMsg
void SCIPdialogMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
void SCIPprintError(SCIP_RETCODE retcode)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition scip_param.c:250
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:111
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition scip_param.c:219
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition scip_param.c:487
SCIP_RETCODE SCIPunfixParam(SCIP *scip, const char *name)
Definition scip_param.c:385
SCIP_RETCODE SCIPsetEmphasis(SCIP *scip, SCIP_PARAMEMPHASIS paramemphasis, SCIP_Bool quiet)
Definition scip_param.c:882
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:57
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition scip_param.c:269
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition scip_param.c:429
SCIP_RETCODE SCIPgetPseudoBranchCands(SCIP *scip, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
int SCIPgetNPseudoBranchCands(SCIP *scip)
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition cons.c:4350
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:372
int SCIPgetNConshdlrs(SCIP *scip)
Definition scip_cons.c:964
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:323
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition scip_cons.c:181
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4782
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4320
int SCIPconshdlrGetNEnabledConss(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4826
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)),)
Definition scip_cons.c:347
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition scip_cons.c:940
SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:396
SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:444
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4340
int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4816
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:468
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4739
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:420
SCIP_CONSHDLR ** SCIPgetConshdlrs(SCIP *scip)
Definition scip_cons.c:953
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition cons.c:8490
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8393
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
void SCIPdialoghdlrClearBuffer(SCIP_DIALOGHDLR *dialoghdlr)
Definition dialog.c:446
SCIP_RETCODE SCIPreleaseDialog(SCIP *scip, SCIP_DIALOG **dialog)
SCIP_DIALOG * SCIPdialoghdlrGetRoot(SCIP_DIALOGHDLR *dialoghdlr)
Definition dialog.c:436
SCIP_Bool SCIPdialogHasEntry(SCIP_DIALOG *dialog, const char *entryname)
Definition dialog.c:1013
SCIP_RETCODE SCIPdialoghdlrAddHistory(SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, const char *command, SCIP_Bool escapecommand)
Definition dialog.c:725
SCIP_RETCODE SCIPincludeDialog(SCIP *scip, SCIP_DIALOG **dialog, SCIP_DECL_DIALOGCOPY((*dialogcopy)), SCIP_DECL_DIALOGEXEC((*dialogexec)), SCIP_DECL_DIALOGDESC((*dialogdesc)), SCIP_DECL_DIALOGFREE((*dialogfree)), const char *name, const char *desc, SCIP_Bool issubmenu, SCIP_DIALOGDATA *dialogdata)
Definition scip_dialog.c:59
SCIP_RETCODE SCIPaddDialogEntry(SCIP *scip, SCIP_DIALOG *dialog, SCIP_DIALOG *subdialog)
SCIP_RETCODE SCIPdialoghdlrGetWord(SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, const char *prompt, char **inputword, SCIP_Bool *endoffile)
Definition dialog.c:546
SCIP_DIALOG * SCIPgetRootDialog(SCIP *scip)
int SCIPdialogFindEntry(SCIP_DIALOG *dialog, const char *entryname, SCIP_DIALOG **subdialog)
Definition dialog.c:1046
void SCIPdispLongint(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_Longint val, int width)
Definition disp.c:581
const char * SCIPdispGetName(SCIP_DISP *disp)
Definition disp.c:335
SCIP_RETCODE SCIPincludeDisp(SCIP *scip, const char *name, const char *desc, const char *header, SCIP_DISPSTATUS dispstatus, SCIP_DECL_DISPCOPY((*dispcopy)), SCIP_DECL_DISPFREE((*dispfree)), SCIP_DECL_DISPINIT((*dispinit)), SCIP_DECL_DISPEXIT((*dispexit)), SCIP_DECL_DISPINITSOL((*dispinitsol)), SCIP_DECL_DISPEXITSOL((*dispexitsol)), SCIP_DECL_DISPOUTPUT((*dispoutput)), SCIP_DISPDATA *dispdata, int width, int priority, int position, SCIP_Bool stripline)
Definition scip_disp.c:55
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
SCIP_HEUR ** SCIPgetHeurs(SCIP *scip)
Definition scip_heur.c:276
int SCIPgetNHeurs(SCIP *scip)
Definition scip_heur.c:287
int SCIPheurGetFreq(SCIP_HEUR *heur)
Definition heur.c:1552
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition scip_mem.h:81
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition scip_mem.h:70
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
#define SCIPallocMemoryArray(scip, ptr, num)
Definition scip_mem.h:64
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition scip_mem.h:128
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition scip_mem.h:132
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:93
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition scip_mem.h:111
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition scip_mem.h:105
SCIP_RETCODE SCIPcheckSolOrig(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible, SCIP_Bool printreason, SCIP_Bool completely)
Definition scip_sol.c:4385
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition sol.c:4274
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition scip_sol.c:606
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition scip_sol.c:2134
SCIP_RETCODE SCIPcreatePseudoSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition scip_sol.c:724
SCIP_RETCODE SCIPpresolve(SCIP *scip)
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Longint SCIPconvertRealToLongint(SCIP *scip, SCIP_Real real)
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition var.c:18365
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition var.c:23510
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24300
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition scip_var.c:5118
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:23694
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition scip_var.c:1887
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
Definition scip_var.c:2378
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23522
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition scip_var.c:2166
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition scip_var.c:12465
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition scip_var.c:2078
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:1853
void SCIPsortDownPtrPtr(void **ptrarray1, void **ptrarray2, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
int SCIPsparseSolGetNVars(SCIP_SPARSESOL *sparsesol)
Definition misc.c:841
SCIP_Longint * SCIPsparseSolGetLbs(SCIP_SPARSESOL *sparsesol)
Definition misc.c:851
void SCIPsparseSolGetFirstSol(SCIP_SPARSESOL *sparsesol, SCIP_Longint *sol, int nvars)
Definition misc.c:871
SCIP_RETCODE SCIPsparseSolCreate(SCIP_SPARSESOL **sparsesol, SCIP_VAR **vars, int nvars, SCIP_Bool cleared)
Definition misc.c:767
SCIP_Longint * SCIPsparseSolGetUbs(SCIP_SPARSESOL *sparsesol)
Definition misc.c:861
void SCIPsparseSolFree(SCIP_SPARSESOL **sparsesol)
Definition misc.c:817
SCIP_Bool SCIPsparseSolGetNextSol(SCIP_SPARSESOL *sparsesol, SCIP_Longint *sol, int nvars)
Definition misc.c:894
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
return SCIP_OKAY
SCIPfreeSol(scip, &heurdata->sol))
int c
SCIP_Real objval
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
static SCIP_VAR ** vars
static const SCIP_Real scalars[]
Definition lp.c:5959
memory allocation routines
public methods for managing constraints
public methods for user interface dialog
public methods for displaying runtime statistics
public methods for primal heuristics
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
#define SCIPdebugPrintCons(x, y, z)
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for primal CIP solutions
public methods for problem variables
public methods for branching rule plugins and branching
public methods for constraint handler plugins and constraints
public methods for dialog handler plugins
public methods for display handler plugins
general public methods
public methods for primal heuristic plugins and divesets
public methods for memory management
public methods for message handling
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 SCIP variables
#define SCIP_DECL_CONSENFOLP(x)
Definition type_cons.h:363
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
#define SCIP_DECL_CONSEXIT(x)
Definition type_cons.h:136
#define SCIP_DECL_CONSINITSOL(x)
Definition type_cons.h:201
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition type_cons.h:64
#define SCIP_DECL_CONSENFORELAX(x)
Definition type_cons.h:388
#define SCIP_DECL_CONSENFOPS(x)
Definition type_cons.h:431
#define SCIP_DECL_CONSLOCK(x)
Definition type_cons.h:676
struct SCIP_Conshdlr SCIP_CONSHDLR
Definition type_cons.h:62
#define SCIP_DECL_CONSINIT(x)
Definition type_cons.h:126
#define SCIP_DECL_CONSCHECK(x)
Definition type_cons.h:474
#define SCIP_DECL_CONSHDLRCOPY(x)
Definition type_cons.h:108
#define SCIP_DECL_CONSEXITSOL(x)
Definition type_cons.h:216
#define SCIP_DECL_CONSFREE(x)
Definition type_cons.h:116
struct SCIP_Dialog SCIP_DIALOG
Definition type_dialog.h:50
#define SCIP_DECL_DIALOGEXEC(x)
Definition type_dialog.h:96
#define SCIP_DECL_DISPOUTPUT(x)
Definition type_disp.h:140
@ SCIP_DISPSTATUS_OFF
Definition type_disp.h:60
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
@ 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_VERBLEVEL_FULL
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
#define SCIP_DECL_SORTPTRCOMP(x)
Definition type_misc.h:189
struct SCIP_SparseSol SCIP_SPARSESOL
Definition type_misc.h:70
@ SCIP_PARAMEMPHASIS_COUNTER
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_FEASIBLE
Definition type_result.h:45
@ SCIP_INFEASIBLE
Definition type_result.h:46
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_PLUGINNOTFOUND
@ SCIP_INVALIDCALL
@ SCIP_ERROR
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_PROBLEM
Definition type_set.h:45
@ SCIP_STAGE_INITPRESOLVE
Definition type_set.h:48
@ SCIP_STAGE_SOLVED
Definition type_set.h:54
@ SCIP_STAGE_PRESOLVING
Definition type_set.h:49
@ SCIP_STAGE_TRANSFORMED
Definition type_set.h:47
@ SCIP_STAGE_INITSOLVE
Definition type_set.h:52
@ SCIP_STAGE_EXITPRESOLVE
Definition type_set.h:50
@ SCIP_STAGE_EXITSOLVE
Definition type_set.h:55
@ SCIP_STAGE_INIT
Definition type_set.h:44
@ SCIP_STAGE_FREE
Definition type_set.h:57
@ SCIP_STAGE_FREETRANS
Definition type_set.h:56
@ SCIP_STAGE_SOLVING
Definition type_set.h:53
@ SCIP_STAGE_TRANSFORMING
Definition type_set.h:46
@ SCIP_STAGE_PRESOLVED
Definition type_set.h:51
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
type definitions for symmetry computations
#define SYM_TIMING_AFTERPRESOL
#define SYM_HANDLETYPE_SYMCONS
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:141