Scippy

SCIP

Solving Constraint Integer Programs

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