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-2014 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
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, 2, (unsigned long) exponent);
171 #else
172  assert(exponent < 64);
173  (*value) = 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, 1);
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( SCIPallocMemory(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
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  SCIPdebugMessage("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  if( conshdlrdata->nsolutions == conshdlrdata->ssolutions )
623  {
624  if( conshdlrdata->ssolutions == 0 )
625  {
626  conshdlrdata->ssolutions = 100;
627  SCIP_CALL( SCIPallocMemoryArray(scip, &conshdlrdata->solutions, conshdlrdata->ssolutions) );
628  }
629  else
630  {
631  assert( conshdlrdata->ssolutions < INT_MAX / 2);
632  conshdlrdata->ssolutions *= 2;
633  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->solutions, conshdlrdata->ssolutions) );
634  }
635  }
636  assert( conshdlrdata->nsolutions < conshdlrdata->ssolutions );
637 
638  /* get number of active variables */
639  nvars = conshdlrdata->nvars;
640 
641  SCIPdebugMessage("creating solution number %d\n", conshdlrdata->nsolutions);
642 
643  /* create a solution */
644  SCIP_CALL( SCIPsparseSolCreate(&solution, conshdlrdata->vars, nvars, FALSE) );
645  assert(solution != NULL);
646 
647  lbvalues = SCIPsparseSolGetLbs(solution);
648  ubvalues = SCIPsparseSolGetUbs(solution);
649  assert(ubvalues != NULL);
650  assert(lbvalues != NULL);
651 
652  for( v = nvars - 1; v >= 0; --v )
653  {
654  SCIP_VAR* var;
655 
656  var = conshdlrdata->vars[v];
657  assert(var != NULL);
658 
659  if( sol == NULL )
660  {
661  lbvalues[v] = (SCIP_Longint)(SCIPvarGetLbLocal(var) + 0.5);
662  ubvalues[v] = (SCIP_Longint)(SCIPvarGetUbLocal(var) + 0.5);
663  }
664  else
665  {
666  lbvalues[v] = (SCIP_Longint)(SCIPgetSolVal(scip, sol, var) + 0.5);
667  ubvalues[v] = lbvalues[v];
668  }
669 
670  SCIPdebugMessage("variable <%s> [%"SCIP_LONGINT_FORMAT",%"SCIP_LONGINT_FORMAT"]\n",
671  SCIPvarGetName(var), lbvalues[v], ubvalues[v]);
672  }
673 
674  conshdlrdata->solutions[conshdlrdata->nsolutions] = solution;
675  conshdlrdata->nsolutions++;
676 
677  return SCIP_OKAY;
678 }
679 
680 
681 /** counts the number of solutions represented by sol */
682 static
684  SCIP* scip, /**< SCIP data structure */
685  SCIP_SOL* sol, /**< solution */
686  SCIP_Bool feasible, /**< is solution feasible? */
687  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
688  SCIP_RESULT* result /**< pointer to store the result of the checking process */
689  )
690 {
691  assert( scip != NULL );
692  assert( sol != NULL );
693  assert( conshdlrdata != NULL );
694  assert( result != NULL );
695 
696  /* the result should be infeasible since we reject any solution; however, if the solution passes the sparse test the
697  * result is set to SCIP_CUTOFF which cuts off the subtree initialized through the current node
698  */
699  assert(*result == SCIP_INFEASIBLE);
700 
701  if( feasible )
702  {
703  int v;
704 
705  Int newsols;
706 
707  SCIP_VAR** vars;
708  int nvars;
709 
710  SCIP_VAR* var;
711  SCIP_Real lb;
712  SCIP_Real ub;
713 
714  SCIPdebugMessage("counts number of solutions represented through the given one\n");
715 
716  /**@note aggregations and multi aggregations: we do not have to care about these things
717  * since we count solution from the transformed problem and therefore, SCIP does
718  * it for us
719  */
720  assert( SCIPgetNPseudoBranchCands(scip) != 0 );
721 
722  allocInt(&newsols); /*lint !e545*/
723 
724  /* set newsols to one */
725  setInt(&newsols, 1LL); /*lint !e545*/
726 
727  if( SCIPgetNBinVars(scip) == SCIPgetNVars(scip) )
728  {
729  int npseudocands;
730 
731  npseudocands = SCIPgetNPseudoBranchCands(scip);
732 
733  /* sets a power of 2 to the number of solutions */
734  setPowerOfTwo(&newsols, (SCIP_Longint) npseudocands); /*lint !e545*/
735  }
736  else
737  {
738  SCIP_VAR* origvar;
739  SCIP_Real scalar = 1.0;
740  SCIP_Real constant = 0.0;
741 
742  SCIP_CALL( SCIPgetPseudoBranchCands(scip, &vars, &nvars, NULL) );
743 
744  for( v = 0; v < nvars; ++v )
745  {
746  var = vars[v];
747  origvar = var;
748  /* get original variable to decide if we will count the domain; continuous variables aren't counted */
749  SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
750 
751  if( origvar != NULL && SCIPvarGetType(origvar) != SCIP_VARTYPE_CONTINUOUS )
752  {
753  lb = SCIPvarGetLbLocal(var);
754  ub = SCIPvarGetUbLocal(var);
755 
756  SCIPdebugMessage("variable <%s> Local Bounds are [%g,%g]\n", SCIPvarGetName(var), lb, ub);
757 
758  assert( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS );
759  assert( SCIPisFeasIntegral(scip, lb) );
760  assert( SCIPisFeasIntegral(scip, ub) );
761  assert( SCIPisFeasIntegral(scip, ub - lb) );
762  assert( SCIPisFeasLT(scip, lb, ub) );
763 
764  /* the number of integers laying in the interval [lb,ub] is (ub - lb + 1); to make everything integral we
765  * add another 0.5 and cut the fractional part off
766  */
767  multInt(&newsols, (SCIP_Longint)(ub - lb + 1.5) ); /*lint !e545*/
768  }
769  }
770  }
771 
772  *result = SCIP_CUTOFF;
773  conshdlrdata->feasST++;
774 
775  if( conshdlrdata->collect )
776  {
777  SCIP_CALL( collectSolution(scip, conshdlrdata, NULL) );
778  }
779 
780  addInt(&conshdlrdata->nsols, &newsols); /*lint !e545*/
781  freeInt(&newsols); /*lint !e545*/
782  }
783  else if(!conshdlrdata->discardsols)
784  {
785  SCIP_CALL( conshdlrdata->cutoffSolution(scip, sol, conshdlrdata) );
786  addOne(&conshdlrdata->nsols); /*lint !e545*/
787  conshdlrdata->nNonSparseSols++;
788  if( conshdlrdata->collect )
789  {
790  SCIP_CALL( collectSolution(scip, conshdlrdata, sol) );
791  }
792  }
793  else
794  conshdlrdata->nDiscardSols++;
795 
796  return SCIP_OKAY;
797 }
798 
799 
800 /** checks if the new solution is feasible for the logicor constraints */
801 static
803  SCIP* scip, /**< SCIP data structure */
804  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
805  int nconss, /**< number of enabled constraints */
806  SCIP_Bool* satisfied /**< pointer to store if the logicor constraints a satisfied */
807  )
808 {
809  /**@note the logicor constraints are not fully propagated; therefore, we have to check
810  * them by hand if they are satisfied or not; if a constraint is satisfied we
811  * delete it locally from the branch and bound tree.
812  */
813 
814  SCIP_CONS** conss;
815  SCIP_VAR** vars;
816  SCIP_Bool fixedone;
817  int nvars;
818  int c;
819  int v;
820 
821  SCIPdebugMessage("check logicor %d constraints\n", nconss);
822 
823  assert( scip != NULL );
824  assert( conshdlr != NULL );
825  assert( strcmp(SCIPconshdlrGetName(conshdlr),"logicor") == 0 );
826  assert( nconss == SCIPconshdlrGetNEnabledConss(conshdlr) );
827 
828  conss = SCIPconshdlrGetConss(conshdlr);
829  assert( conss != NULL );
830 
831  (*satisfied) = TRUE;
832  c = SCIPconshdlrGetNActiveConss(conshdlr) - 1;
833 
834  for( ; c >= 0 && nconss > 0 && (*satisfied); --c )
835  {
836  SCIPdebugMessage("logicor constraint %d\n", c);
837 
838  if( !SCIPconsIsEnabled(conss[c]) )
839  continue;
840 
841  nconss--;
842 
843  nvars = SCIPgetNVarsLogicor(scip, conss[c]);
844  vars = SCIPgetVarsLogicor(scip, conss[c]);
845 
846  /* calculate the constraint's activity */
847  fixedone = FALSE;
848  for( v = 0; v < nvars && !fixedone; ++v )
849  {
850  assert(SCIPvarIsBinary(vars[v]));
851 
852  if( !varIsUnfixedLocal(vars[v] ) )
853  fixedone = SCIPvarGetLbLocal(vars[v]) > 0.5;
854  }
855 
856  if( !fixedone )
857  {
858  SCIPdebugMessage("constraint <%s> cannot be disabled\n", SCIPconsGetName(conss[c]));
859  SCIPdebugPrintCons(scip, conss[c], NULL);
860  (*satisfied) = FALSE;
861  }
862  else
863  {
864  /* delete constraint from the problem locally since it is satisfied */
865  SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
866  }
867  }
868 
869  return SCIP_OKAY;
870 }
871 
872 
873 /** checks if the new solution is feasible for the knapsack constraints */
874 static
876  SCIP* scip, /**< SCIP data structure */
877  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
878  int nconss, /**< number of enabled constraints */
879  SCIP_Bool* satisfied /**< pointer to store if the logicor constraints a satisfied */
880  )
881 {
882  /**@note the knapsack constraints are not fully propagated; therefore, we have to check
883  * them by hand if they are satisfied or not; if a constraint is satisfied we
884  * delete it locally from the branch and bound tree.
885  */
886 
887  SCIP_CONS** conss;
888  SCIP_VAR** vars;
889  SCIP_Longint* weights;
890  SCIP_Longint capacity;
891  SCIP_Real capa;
892  int nvars;
893  int c;
894  int v;
895 
896  SCIPdebugMessage("check knapsack %d constraints\n", nconss);
897 
898  assert( scip != NULL );
899  assert( conshdlr != NULL );
900  assert( strcmp(SCIPconshdlrGetName(conshdlr),"knapsack") == 0 );
901  assert( nconss == SCIPconshdlrGetNEnabledConss(conshdlr) );
902 
903  conss = SCIPconshdlrGetConss(conshdlr);
904  assert( conss != NULL );
905 
906  (*satisfied) = TRUE;
907  c = SCIPconshdlrGetNActiveConss(conshdlr) - 1;
908 
909  for( ; c >= 0 && nconss > 0 && (*satisfied); --c )
910  {
911  SCIPdebugMessage("knapsack constraint %d\n", c);
912 
913  if( !SCIPconsIsEnabled(conss[c]) )
914  continue;
915 
916  nconss--;
917 
918  nvars = SCIPgetNVarsKnapsack(scip, conss[c]);
919  vars = SCIPgetVarsKnapsack(scip, conss[c]);
920  capacity = SCIPgetCapacityKnapsack(scip, conss[c]);
921  weights = SCIPgetWeightsKnapsack(scip,conss[c]);
922 
923  SCIPdebugMessage("knapsack capacity = %"SCIP_LONGINT_FORMAT"\n", capacity);
924 
925  capa = capacity + 0.1;
926 
927  for( v = nvars - 1; v >= 0 && capa >= 0 ; --v )
928  {
929  SCIPdebug( SCIP_CALL( SCIPprintVar( scip, vars[v], NULL) ) );
930  SCIPdebugMessage("weight = %"SCIP_LONGINT_FORMAT" :\n", weights[v]);
931  assert( SCIPvarIsIntegral(vars[v]) );
932 
933  /* the weights should be greater or equal to zero */
934  assert( weights[v] >= 0);
935 
936  if( !varIsUnfixedLocal(vars[v]) )
937  {
938  /* variables is fixed locally; therefore, subtract fixed variable value multiplied by
939  * the weight;
940  */
941  capa -= weights[v] * SCIPvarGetLbLocal(vars[v]);
942  }
943  else if( weights[v] >= 1 )
944  {
945  /* variable is unfixed and weight is greater than 0; therefore, subtract upper bound
946  * value multiplied by the weight
947  */
948  capa -= weights[v] * SCIPvarGetUbLocal(vars[v]);
949  }
950  }
951 
952  if( SCIPisFeasLT(scip, capa, 0.0) )
953  {
954  SCIPdebugMessage("constraint %s cannot be disabled\n", SCIPconsGetName(conss[c]));
955  SCIPdebugPrintCons(scip, conss[c], NULL);
956  (*satisfied) = FALSE;
957  }
958  else
959  {
960  /* delete constraint from the problem locally since it is satisfied */
961  SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
962  }
963  }
964  return SCIP_OKAY;
965 }
966 
967 
968 /** checks if the new solution is feasible for the bounddisjunction constraints */
969 static
971  SCIP* scip, /**< SCIP data structure */
972  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
973  int nconss, /**< number of enabled constraints */
974  SCIP_Bool* satisfied /**< pointer to store if the logicor constraints a satisfied */
975  )
976 {
977  /**@note the bounddisjunction constraints are not fully propagated; therefore, we have to check
978  * them by hand if they are satisfied or not; if a constraint is satisfied we
979  * delete it locally from the branch and bound tree
980  */
981 
982  SCIP_CONS** conss;
983  SCIP_VAR** vars;
984  SCIP_BOUNDTYPE* boundtypes;
985  SCIP_Real* bounds;
986  SCIP_Bool satisfiedbound;
987  int nvars;
988  int c;
989  int v;
990 
991  assert( scip != NULL );
992  assert( conshdlr != NULL );
993  assert( strcmp(SCIPconshdlrGetName(conshdlr),"bounddisjunction") == 0 );
994  assert( nconss == SCIPconshdlrGetNEnabledConss(conshdlr) );
995 
996  conss = SCIPconshdlrGetConss(conshdlr);
997  assert( conss != NULL );
998 
999  (*satisfied) = TRUE;
1000  c = SCIPconshdlrGetNActiveConss(conshdlr) - 1;
1001 
1002  for( ; c >= 0 && nconss > 0 && (*satisfied); --c )
1003  {
1004  if( !SCIPconsIsEnabled(conss[c]) )
1005  continue;
1006 
1007  nconss--;
1008  satisfiedbound = FALSE;
1009 
1010  nvars = SCIPgetNVarsBounddisjunction(scip, conss[c]);
1011  vars = SCIPgetVarsBounddisjunction(scip, conss[c]);
1012 
1013  boundtypes = SCIPgetBoundtypesBounddisjunction(scip, conss[c]);
1014  bounds = SCIPgetBoundsBounddisjunction(scip, conss[c]);
1015 
1016  for( v = nvars-1; v >= 0 && !satisfiedbound; --v )
1017  {
1018  SCIPdebug( SCIPprintVar(scip, vars[v], NULL) );
1019 
1020  /* variable should be in right bounds to delete constraint */
1021  if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
1022  satisfiedbound = SCIPisFeasGE(scip, SCIPvarGetLbLocal(vars[v]), bounds[v]);
1023  else
1024  {
1025  assert( boundtypes[v] == SCIP_BOUNDTYPE_UPPER );
1026  satisfiedbound = SCIPisFeasLE(scip, SCIPvarGetUbLocal(vars[v]), bounds[v]);
1027  }
1028  }
1029 
1030  if( !satisfiedbound )
1031  {
1032  SCIPdebugMessage("constraint %s cannot be disabled\n", SCIPconsGetName(conss[c]));
1033  SCIPdebugPrintCons(scip, conss[c], NULL);
1034  (*satisfied) = FALSE;
1035  }
1036  else
1037  {
1038  /* delete constraint from the problem locally since it is satisfied */
1039  SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
1040  }
1041  }
1042  return SCIP_OKAY;
1043 }
1044 
1045 
1046 /** checks if the new solution is feasible for the varbound constraints */
1047 static
1049  SCIP* scip, /**< SCIP data structure */
1050  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1051  int nconss, /**< number of enabled constraints */
1052  SCIP_Bool* satisfied /**< pointer to store if the logicor constraints a satisfied */
1053  )
1054 {
1055  /**@note the varbound constraints are not fully propagated; therefore, we have to check
1056  * them by hand if they are satisfied or not; if a constraint is satisfied we
1057  * delete it locally from the branch and bound tree.
1058  */
1059 
1060  SCIP_CONS** conss;
1061  SCIP_VAR* var;
1062  SCIP_VAR* vbdvar;
1063  SCIP_Real lhs;
1064  SCIP_Real rhs;
1065  SCIP_Real coef;
1066  int c;
1067 
1068  SCIPdebugMessage("check varbound %d constraints\n", nconss);
1069 
1070  assert( scip != NULL );
1071  assert( conshdlr != NULL );
1072  assert( strcmp(SCIPconshdlrGetName(conshdlr),"varbound") == 0 );
1073  assert( nconss == SCIPconshdlrGetNEnabledConss(conshdlr) );
1074 
1075  conss = SCIPconshdlrGetConss(conshdlr);
1076  assert( conss != NULL );
1077 
1078  (*satisfied) = TRUE;
1079  c = SCIPconshdlrGetNActiveConss(conshdlr) - 1;
1080 
1081  for( ; c >= 0 && nconss > 0 && (*satisfied); --c )
1082  {
1083  SCIPdebugMessage("varbound constraint %d\n", c);
1084 
1085  if( !SCIPconsIsEnabled(conss[c]) )
1086  continue;
1087 
1088  nconss--;
1089 
1090  var = SCIPgetVarVarbound(scip, conss[c]);
1091  vbdvar = SCIPgetVbdvarVarbound(scip, conss[c]);
1092 
1093  assert (SCIPvarGetType(vbdvar) != SCIP_VARTYPE_CONTINUOUS);
1094 
1095  coef = SCIPgetVbdcoefVarbound(scip, conss[c]);
1096  lhs = SCIPgetLhsVarbound(scip, conss[c]);
1097  rhs = SCIPgetRhsVarbound(scip, conss[c]);
1098 
1099  /* variables y is fixed locally; therefore, subtract fixed variable value multiplied by
1100  * the coefficient;
1101  */
1102  if(SCIPisGT(scip, SCIPvarGetUbLocal(var), rhs - SCIPvarGetUbLocal(vbdvar) * coef )
1103  || !SCIPisGE(scip, SCIPvarGetLbLocal(var), lhs - SCIPvarGetLbLocal(vbdvar) * coef ) )
1104  {
1105  SCIPdebugMessage("constraint %s cannot be disabled\n", SCIPconsGetName(conss[c]));
1106  SCIPdebugPrintCons(scip, conss[c], NULL);
1107  SCIPdebugMessage("<%s> lb: %.15g\t ub: %.15g\n", SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var));
1108  SCIPdebugMessage("<%s> lb: %.15g\t ub: %.15g\n", SCIPvarGetName(vbdvar), SCIPvarGetLbLocal(vbdvar), SCIPvarGetUbLocal(vbdvar));
1109  (*satisfied) = FALSE;
1110  }
1111  else
1112  {
1113  /* delete constraint from the problem locally since it is satisfied */
1114  SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
1115  }
1116  }
1117 
1118  return SCIP_OKAY;
1119 }
1120 
1121 
1122 /** check if the current node initializes a non trivial unrestricted subtree */
1123 static
1125  SCIP* scip, /**< SCIP main data structure */
1126  SCIP_SOL* sol, /**< solution to check */
1127  SCIP_Bool* feasible /**< pointer to store the result of the check */
1128  )
1129 {
1130  int h;
1131 
1132  SCIP_CONSHDLR** conshdlrs;
1133  int nconshdlrs;
1134 
1135  SCIP_CONSHDLR* conshdlr;
1136  int nconss;
1137 
1138  SCIPdebugMessage("check if the sparse solution is feasible\n");
1139 
1140  assert( scip != NULL );
1141  assert( sol != NULL );
1142  assert( feasible != NULL );
1143 
1144  assert( SCIPgetNPseudoBranchCands(scip) != 0 );
1145 
1146  *feasible = FALSE;
1147 
1148  nconshdlrs = SCIPgetNConshdlrs(scip) - 1;
1149  conshdlrs = SCIPgetConshdlrs(scip);
1150  assert(conshdlrs != NULL);
1151 
1152  /* check each constraint handler if there are constraints which are not enabled */
1153  for( h = nconshdlrs ; h >= 0 ; --h )
1154  {
1155  conshdlr = conshdlrs[h];
1156  assert( conshdlr != NULL );
1157 
1158  /* skip this constraints handler */
1159  if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 )
1160  continue;
1161 
1162  nconss = SCIPconshdlrGetNEnabledConss(conshdlr);
1163 
1164  if( nconss > 0 )
1165  {
1166  SCIP_Bool satisfied;
1167 
1168  SCIPdebugMessage("constraint handler %s has %d active constraint(s)\n",
1169  SCIPconshdlrGetName(conshdlr), nconss );
1170 
1171  if( strcmp(SCIPconshdlrGetName(conshdlr), "logicor") == 0 )
1172  {
1173  SCIP_CALL( checkLogicor(scip, conshdlr, nconss, &satisfied) );
1174  if( !satisfied )
1175  {
1176  SCIPdebugMessage("a <logicor> constraint cannot be disabled\n");
1177  return SCIP_OKAY;
1178  }
1179  }
1180  else if( strcmp(SCIPconshdlrGetName(conshdlr), "knapsack") == 0 )
1181  {
1182  SCIP_CALL( checkKnapsack(scip, conshdlr, nconss, &satisfied) );
1183  if( !satisfied )
1184  {
1185  SCIPdebugMessage("a <knapsack> constraint cannot be disabled\n");
1186  return SCIP_OKAY;
1187  }
1188  }
1189  else if( strcmp(SCIPconshdlrGetName(conshdlr), "bounddisjunction") == 0 )
1190  {
1191  SCIP_CALL( checkBounddisjunction(scip, conshdlr, nconss, &satisfied) );
1192  if( !satisfied )
1193  {
1194  SCIPdebugMessage("a <bounddisjunction> constraint cannot be disabled\n");
1195  return SCIP_OKAY;
1196  }
1197  }
1198  else if( strcmp(SCIPconshdlrGetName(conshdlr), "varbound") == 0 )
1199  {
1200  SCIP_CALL( checkVarbound(scip, conshdlr, nconss, &satisfied) );
1201  if( !satisfied )
1202  {
1203  SCIPdebugMessage("a <varbound> constraint cannot be disabled\n");
1204  return SCIP_OKAY;
1205  }
1206  }
1207  else
1208  {
1209  SCIPdebugMessage("sparse solution is infeasible since the following constraint (and maybe more) is(/are) enabled\n");
1210  SCIPdebugPrintCons(scip, SCIPconshdlrGetConss(conshdlr)[0], NULL);
1211  return SCIP_OKAY;
1212  }
1213  }
1214  }
1215 
1216  *feasible = TRUE;
1217  SCIPdebugMessage("sparse solution is feasible\n");
1218 
1219  return SCIP_OKAY;
1220 }
1221 
1222 
1223 /** check the given solution */
1224 static
1226  SCIP* scip, /**< SCIP data structure */
1227  SCIP_SOL* sol, /**< solution to add */
1228  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
1229  SCIP_RESULT* result /**< pointer to store the result of the checking process */
1230  )
1231 {
1232  SCIP_Longint nsols;
1233  SCIP_Bool feasible;
1234  SCIP_Bool valid;
1235 
1236  SCIPdebugMessage("start to add sparse solution\n");
1237 
1238  assert( scip != NULL );
1239  assert( sol != NULL );
1240  assert( conshdlrdata != NULL );
1241  assert( result != NULL );
1242 
1243  /* the solution should not be found through a heuristic since in this case the informations of SCIP are not valid for
1244  * this solution
1245  */
1246 
1247  /**@todo it might be not necessary to check this assert since we can check in general all solutions of feasibility
1248  * independently of the origin; however, the locally fixed technique does only work if the solution comes from
1249  * the branch and bound tree; in case the solution comes from a heuristic we should try to sequentially fix the
1250  * variables in the branch and bound tree and check after every fixing if all constraints are disabled; at the
1251  * point where all constraints are disabled the unfixed variables are "stars" (arbitrary);
1252  */
1253  assert( SCIPgetNOrigVars(scip) != 0);
1254  assert( SCIPsolGetHeur(sol) == NULL);
1255 
1256  /* setting result to infeasible since we reject any solution; however, if the solution passes the sparse test or is
1257  * completely fixed the result is set to SCIP_CUTOFF which cuts off the subtree initialized through the current node
1258  */
1259  *result = SCIP_INFEASIBLE;
1260 
1261 #ifdef SCIP_DEBUG
1262  {
1263  SCIP_VAR* var;
1264  SCIP_VAR** vars;
1265  int v;
1266  int nvars;
1267 
1268  nvars = SCIPgetNVars(scip);
1269  vars = SCIPgetVars(scip);
1270 
1271  for( v = 0; v < nvars; ++v )
1272  {
1273  var = vars[v];
1274  SCIPdebugMessage("variables <%s> Local Bounds are [%g,%g] Global Bounds are [%g,%g]\n",
1276  }
1277  }
1278 #endif
1279 
1280  /* check if integer variables are completely fixed */
1281  if( SCIPgetNPseudoBranchCands(scip) == 0 )
1282  {
1283  /* check solution original space */
1284  checkSolutionOrig(scip, sol, conshdlrdata);
1285 
1286  addOne(&conshdlrdata->nsols); /*lint !e545*/
1287  conshdlrdata->nNonSparseSols++;
1288 
1289  SCIPdebugMessage("-> add one to number of solutions\n");
1290 
1291  if( conshdlrdata->collect )
1292  {
1293  SCIP_CALL( collectSolution(scip, conshdlrdata, sol) );
1294  }
1295 
1296  /* in case of continuous variables are present we explicitly cutoff the integer assignment since in case of
1297  * nonlinear constraint we want to avoid the count that integer assignment again
1298  */
1299  if( conshdlrdata->continuous )
1300  {
1301  SCIP_CALL( conshdlrdata->cutoffSolution(scip, sol, conshdlrdata) );
1302  }
1303 
1304  /* since all integer are fixed we cut off the subtree */
1305  *result = SCIP_CUTOFF;
1306  }
1307  else if( conshdlrdata->sparsetest )
1308  {
1309  SCIP_CALL( checkFeasSubtree(scip, sol, &feasible) ) ;
1310  SCIP_CALL( countSparseSol(scip, sol, feasible, conshdlrdata, result) );
1311  }
1312 
1313  /* transform the current number of solutions into a SCIP_Longint */
1314  nsols = getNCountedSols(conshdlrdata->nsols, &valid);
1315 
1316  /* check if the solution limit is hit and stop SCIP if this is the case */
1317  if( conshdlrdata->sollimit > -1 && (!valid || conshdlrdata->sollimit <= nsols) )
1318  {
1319  SCIP_CALL( SCIPinterruptSolve(scip) );
1320  }
1321 
1322  assert( *result == SCIP_INFEASIBLE || *result == SCIP_CUTOFF );
1323  SCIPdebugMessage("result is %s\n", *result == SCIP_INFEASIBLE ? "SCIP_INFEASIBLE" : "SCIP_CUTOFF" );
1324 
1325  return SCIP_OKAY;
1326 }
1327 
1328 /*
1329  * Callback methods of constraint handler
1330  */
1331 
1332 /** creates the handler for countsols constraints and includes it in SCIP */
1333 static
1335  SCIP* scip, /**< SCIP data structure */
1336  SCIP_Bool dialogs /**< sould count dialogs be added */
1337  );
1338 
1339 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
1340 static
1341 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyCountsols)
1342 { /*lint --e{715}*/
1343  SCIP_CONSHDLRDATA* conshdlrdata;
1344 
1345  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1346  assert(conshdlrdata != NULL);
1347 
1348  /* in case the count constraint handler is active we avoid copying to ensure a safe count */
1349  if( conshdlrdata->active )
1350  *valid = FALSE;
1351  else
1352  {
1353  assert(scip != NULL);
1354  assert(conshdlr != NULL);
1355  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1356 
1357  /* call inclusion method of constraint handler and do not add counting dialogs */
1359 
1360  *valid = TRUE;
1361  }
1362 
1363  return SCIP_OKAY;
1364 }
1365 
1366 #define consCopyCountsols NULL
1367 
1368 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
1369 static
1370 SCIP_DECL_CONSFREE(consFreeCountsols)
1371 { /*lint --e{715}*/
1372  SCIP_CONSHDLRDATA* conshdlrdata;
1373 
1374  assert(conshdlr != NULL);
1375  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1376 
1377  /* free constraint handler data */
1378  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1379  assert(conshdlrdata != NULL);
1380 
1381  /* free conshdlrdata */
1382  freeInt(&conshdlrdata->nsols); /*lint !e545*/
1383 
1384  assert( conshdlrdata->solutions == NULL );
1385  assert( conshdlrdata->nsolutions == 0 );
1386  assert( conshdlrdata->ssolutions == 0 );
1387 
1388  SCIPfreeMemory(scip, &conshdlrdata);
1389  SCIPconshdlrSetData(conshdlr, NULL);
1390 
1391  return SCIP_OKAY;
1392 }
1393 
1394 /** initialization method of constraint handler (called after problem was transformed) */
1395 static
1396 SCIP_DECL_CONSINIT(consInitCountsols)
1397 { /*lint --e{715}*/
1398  SCIP_CONSHDLRDATA* conshdlrdata;
1399 
1400  assert( conshdlr != NULL );
1401  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1402 
1403  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1404  assert(conshdlrdata != NULL );
1405 
1406  /* reset counting variables */
1407  conshdlrdata->feasST = 0; /* number of non trivial unrestricted subtrees */
1408  conshdlrdata->nDiscardSols = 0; /* number of discard solutions */
1409  conshdlrdata->nNonSparseSols = 0; /* number of non sparse solutions */
1410  setInt(&conshdlrdata->nsols, 0LL); /* number of solutions */ /*lint !e545*/
1411 
1412  conshdlrdata->solutions = NULL;
1413  conshdlrdata->nsolutions = 0;
1414  conshdlrdata->ssolutions = 0;
1415 
1416  if( conshdlrdata->active )
1417  {
1418  SCIP_VAR** origvars;
1419  int norigvars;
1420  int nallvars;
1421  int v;
1422 
1423  origvars = SCIPgetOrigVars(scip);
1424  norigvars = SCIPgetNOrigVars(scip);
1425 
1426  /* get number of integral variables */
1427  conshdlrdata->nallvars = SCIPgetNVars(scip) - SCIPgetNContVars(scip);
1428 
1429  SCIP_CALL( SCIPallocMemoryArray(scip, &conshdlrdata->allvars, conshdlrdata->nallvars) );
1430 
1431  nallvars = 0;
1432 
1433  /* capture and lock all variables */
1434  for( v = 0; v < norigvars; ++v )
1435  {
1436  if( SCIPvarGetType(origvars[v]) != SCIP_VARTYPE_CONTINUOUS )
1437  {
1438  assert(nallvars < conshdlrdata->nallvars);
1439 
1440  SCIP_CALL( SCIPgetTransformedVar(scip, origvars[v], &conshdlrdata->allvars[nallvars]) );
1441  assert(conshdlrdata->allvars[nallvars] != NULL);
1442 
1443  /* capture variable to ensure that the variable will not be deleted */
1444  SCIP_CALL( SCIPcaptureVar(scip, conshdlrdata->allvars[nallvars]) );
1445 
1446  if( strncmp(SCIPvarGetName(conshdlrdata->allvars[nallvars]), "t_andresultant_", strlen("t_andresultant_")) != 0 )
1447  {
1448  /* lock variable to avoid dual reductions */
1449  SCIP_CALL( SCIPaddVarLocks(scip, conshdlrdata->allvars[nallvars], 1, 1) );
1450  }
1451 
1452  nallvars++;
1453  }
1454  }
1455  assert(nallvars == conshdlrdata->nallvars);
1456 
1457  /* check if continuous variables are present */
1458  conshdlrdata->continuous = SCIPgetNContVars(scip) > 0;
1459  }
1460 
1461  return SCIP_OKAY;
1462 }
1463 
1464 /** deinitialization method of constraint handler (called before transformed problem is freed) */
1465 static
1466 SCIP_DECL_CONSEXIT(consExitCountsols)
1467 { /*lint --e{715}*/
1468  SCIP_CONSHDLRDATA* conshdlrdata;
1469  int s;
1470  int v;
1471 
1472  assert( conshdlr != NULL );
1473  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1474 
1475  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1476  assert(conshdlrdata != NULL );
1477 
1478  /* release variables to hashmap */
1479  for( v = conshdlrdata->nvars - 1; v >= 0; --v )
1480  {
1481  SCIP_CALL( SCIPreleaseVar(scip, &(conshdlrdata->vars[v])) );
1482  }
1483 
1484  if( conshdlrdata->hashmap != NULL)
1485  {
1486  /* free hashmap of active variables to pistions */
1487  SCIPhashmapFree(&(conshdlrdata->hashmap));
1488  }
1489 
1490  /* free active variables */
1491  SCIPfreeMemoryArrayNull(scip, &(conshdlrdata->vars) );
1492  conshdlrdata->nvars = 0;
1493 
1494  if( conshdlrdata->allvars != NULL )
1495  {
1496  /* release and unlock all variables */
1497  for( v = 0; v < conshdlrdata->nallvars; ++v )
1498  {
1499  if( strncmp(SCIPvarGetName(conshdlrdata->allvars[v]), "t_andresultant_", strlen("t_andresultant_")) != 0 )
1500  {
1501  /* remove the previously added variable locks */
1502  SCIP_CALL( SCIPaddVarLocks(scip, conshdlrdata->allvars[v], -1, -1) );
1503  }
1504 
1505  SCIP_CALL( SCIPreleaseVar(scip, &conshdlrdata->allvars[v]) );
1506  }
1507 
1508  SCIPfreeMemoryArrayNull(scip, &conshdlrdata->allvars);
1509  conshdlrdata->nvars = 0;
1510  }
1511 
1512  if( conshdlrdata->nsolutions > 0 )
1513  {
1514  for( s = conshdlrdata->nsolutions - 1; s >= 0 ; --s )
1515  {
1516  SCIPsparseSolFree(&(conshdlrdata->solutions[s]));
1517  }
1518 
1519  SCIPfreeMemoryArrayNull(scip, &conshdlrdata->solutions);
1520  conshdlrdata->nsolutions = 0;
1521  conshdlrdata->ssolutions = 0;
1522 
1523  assert( conshdlrdata->solutions == NULL );
1524  }
1525  conshdlrdata->continuous = FALSE;
1526 
1527  assert( conshdlrdata->solutions == NULL );
1528  assert( conshdlrdata->nsolutions == 0 );
1529  assert( conshdlrdata->ssolutions == 0 );
1530 
1531  return SCIP_OKAY;
1532 }
1533 
1534 
1535 /** solving process initialization method of constraint handler (called when branch and bound process is about to begin)
1536  *
1537  * This method is called when the presolving was finished and the branch and bound process is about to begin.
1538  * The constraint handler may use this call to initialize its branch and bound specific data.
1539  */
1540 static
1541 SCIP_DECL_CONSINITSOL(consInitsolCountsols)
1542 { /*lint --e{715}*/
1543  SCIP_CONSHDLRDATA* conshdlrdata;
1544 
1545  assert( conshdlr != NULL );
1546  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1547 
1548  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1549  assert(conshdlrdata != NULL );
1550 
1551  if( conshdlrdata->active )
1552  {
1553  SCIP_VAR** vars;
1554  int v;
1555 
1556  assert(conshdlrdata->nsolutions == 0);
1557  assert(conshdlrdata->solutions == NULL);
1558 
1559  conshdlrdata->nvars = SCIPgetNVars(scip) - SCIPgetNContVars(scip);
1560  vars = SCIPgetVars(scip);
1561 
1562  /* exclude upgrade continuous original variables */
1563  for( v = conshdlrdata->nvars - 1; v >= 0; --v )
1564  {
1565  SCIP_VAR* origvar;
1566  SCIP_Real scalar = 1.0;
1567  SCIP_Real constant = 0.0;
1568 
1569  origvar = vars[v];
1570 
1571  /* get original variable to decide if we will count the domain; continuous variables aren't counted */
1572  SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
1573 
1574  if( origvar != NULL && SCIPvarGetType(origvar) != SCIP_VARTYPE_CONTINUOUS )
1575  break;
1576  }
1577  conshdlrdata->nvars = v + 1;
1578 
1579  /* @todo we need to forbid variable downgrading, from integer type to implicit integer type, e.g. done in
1580  * cons_linear
1581  */
1582 #ifndef NDEBUG
1583  for( v = conshdlrdata->nvars - 1; v >= 0; --v )
1584  {
1585  SCIP_VAR* origvar;
1586  SCIP_Real scalar = 1.0;
1587  SCIP_Real constant = 0.0;
1588 
1589  origvar = vars[v];
1590 
1591  /* get original variable to decide if we will count the domain; continuous variables aren't counted */
1592  SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
1593 
1594  assert(origvar != NULL && SCIPvarGetType(origvar) != SCIP_VARTYPE_CONTINUOUS);
1595  }
1596 #endif
1597 
1598  /* copy array of active variables */
1599  SCIP_CALL( SCIPduplicateMemoryArray(scip, &(conshdlrdata->vars), vars, conshdlrdata->nvars) );
1600 
1601  /* store mapping from all active variables to their position afetr presolving because during solving new variables
1602  * might be added and therefore could destroy writing collected solutions
1603  */
1604  SCIP_CALL( SCIPhashmapCreate(&(conshdlrdata->hashmap), SCIPblkmem(scip), 5 * conshdlrdata->nvars + 1) );
1605 
1606  /* add variables to hashmap */
1607  for( v = conshdlrdata->nvars - 1; v >= 0; --v )
1608  {
1609  assert(SCIPvarGetProbindex(conshdlrdata->vars[v]) == v);
1610  SCIP_CALL( SCIPhashmapInsert(conshdlrdata->hashmap, conshdlrdata->vars[v], (void*) (size_t)(v+1)) );
1611  SCIP_CALL( SCIPcaptureVar(scip, conshdlrdata->vars[v]) );
1612  }
1613 
1614  /* check if the problem is binary (ignoring continuous variables) */
1615  if( SCIPgetNBinVars(scip) == (SCIPgetNVars(scip) - SCIPgetNContVars(scip)) )
1616  conshdlrdata->cutoffSolution = addBinaryCons;
1617  else
1618  conshdlrdata->cutoffSolution = addIntegerCons;
1619  }
1620 
1621  return SCIP_OKAY;
1622 }
1623 
1624 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
1625 static
1626 SCIP_DECL_CONSEXITSOL(consExitsolCountsols)
1627 { /*lint --e{715}*/
1628  SCIP_CONSHDLRDATA* conshdlrdata;
1629 
1630  assert(scip != NULL);
1631  assert(conshdlr != NULL);
1632  assert(nconss == 0);
1633  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1634 
1635  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1636  assert(conshdlrdata != NULL );
1637 
1638  if( conshdlrdata->active && restart )
1639  {
1640  SCIPerrorMessage("When collecting and counting solutions restarts need to be disabled (presolving/maxrestarts = 0).\n");
1641  SCIPABORT();
1642  return SCIP_INVALIDCALL; /*lint !e527*/
1643  }
1644 
1645  return SCIP_OKAY;
1646 }
1647 
1648 /** constraint enforcing method of constraint handler for LP solutions */
1649 static
1650 SCIP_DECL_CONSENFOLP(consEnfolpCountsols)
1651 { /*lint --e{715}*/
1652  SCIP_CONSHDLRDATA* conshdlrdata;
1653 
1654  SCIPdebugMessage("method SCIP_DECL_CONSENFOLP(consEnfolpCountsols)\n");
1655 
1656  assert( scip != NULL );
1657  assert( conshdlr != NULL );
1658  assert( nconss == 0 );
1659 
1660  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1661  assert( conshdlrdata != NULL );
1662 
1663  if( conshdlrdata->active )
1664  {
1665  if( !solinfeasible )
1666  {
1667  SCIP_SOL* sol;
1668 
1669  SCIP_CALL( SCIPcreateLPSol(scip, &sol, NULL ) );
1670 
1671  SCIP_CALL( checkSolution(scip, sol, conshdlrdata, result) );
1672  SCIP_CALL( SCIPfreeSol(scip, &sol) );
1673  }
1674  else
1675  *result = SCIP_INFEASIBLE;
1676  }
1677  else
1678  *result = SCIP_FEASIBLE;
1679 
1680  assert( !conshdlrdata->active || *result == SCIP_INFEASIBLE || *result == SCIP_CUTOFF );
1681 
1682  return SCIP_OKAY;
1683 }
1684 
1685 
1686 /** constraint enforcing method of constraint handler for pseudo solutions */
1687 static
1688 SCIP_DECL_CONSENFOPS(consEnfopsCountsols)
1689 { /*lint --e{715}*/
1690  SCIP_CONSHDLRDATA* conshdlrdata;
1691 
1692  SCIPdebugMessage("method SCIP_DECL_CONSENFOPS(consEnfopsCountsols)\n");
1693 
1694  assert( scip != NULL );
1695  assert( conshdlr != NULL );
1696  assert( nconss == 0 );
1697 
1698  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1699  assert( conshdlrdata != NULL );
1700 
1701 
1702  if( conshdlrdata->active )
1703  {
1704  if( !solinfeasible )
1705  {
1706  SCIP_SOL* sol;
1707 
1708  SCIP_CALL( SCIPcreatePseudoSol(scip, &sol, NULL ) );
1709 
1710  SCIP_CALL( checkSolution(scip, sol, conshdlrdata, result) );
1711  SCIP_CALL( SCIPfreeSol(scip, &sol) );
1712  }
1713  else
1714  *result = SCIP_INFEASIBLE;
1715  }
1716  else
1717  *result = SCIP_FEASIBLE;
1718 
1719  assert( !conshdlrdata->active || *result == SCIP_INFEASIBLE || *result == SCIP_CUTOFF );
1720 
1721  return SCIP_OKAY;
1722 }
1723 
1724 
1725 /** feasibility check method of constraint handler for integral solutions */
1726 static
1727 SCIP_DECL_CONSCHECK(consCheckCountsols)
1728 { /*lint --e{715}*/
1729  /**@todo solutions which come from scip_check should be ignored since it is not clear who
1730  * generated these solution; later we should analyze this problem */
1731  SCIP_CONSHDLRDATA* conshdlrdata;
1732 
1733  SCIPdebugMessage("method SCIP_DECL_CONSCHECK(consCheckCountsols)\n");
1734 
1735  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1736  assert( conshdlrdata != NULL );
1737 
1738  if( conshdlrdata->active )
1739  {
1740  if( !conshdlrdata->warning )
1741  {
1742  SCIPwarningMessage(scip, "a solution comes in over <SCIP_DECL_CONSCHECK(consCheckCountsols)>; currently these solutions are ignored\n");
1743  conshdlrdata->warning = TRUE;
1744  }
1745 
1746  *result = SCIP_INFEASIBLE;
1747  }
1748  else
1749  *result = SCIP_FEASIBLE;
1750 
1751  return SCIP_OKAY;
1752 }
1753 
1754 
1755 /** variable rounding lock method of constraint handler */
1756 static
1757 SCIP_DECL_CONSLOCK(consLockCountsols)
1758 { /*lint --e{715}*/
1759  return SCIP_OKAY;
1760 }
1761 
1762 
1763 /*
1764  * Callback methods and local method for dialogs
1765  */
1766 
1767 /** dialog execution method for the count command */
1768 SCIP_DECL_DIALOGEXEC(SCIPdialogExecCountPresolve)
1769 { /*lint --e{715}*/
1770  SCIP_Bool active;
1771 
1772  SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
1773  SCIPdialogMessage(scip, NULL, "\n");
1774  SCIP_CALL( SCIPgetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", &active) );
1775 
1776  switch( SCIPgetStage(scip) )
1777  {
1778  case SCIP_STAGE_INIT:
1779  SCIPdialogMessage(scip, NULL, "no problem exists\n");
1780  break;
1781 
1782  case SCIP_STAGE_PROBLEM:
1783  /* activate constraint handler cons_countsols */
1784  if( !active )
1785  {
1786  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", TRUE) );
1787  }
1788  /*lint -fallthrough*/
1790  case SCIP_STAGE_PRESOLVING:
1791  /* presolve problem */
1792  SCIP_CALL( SCIPpresolve(scip) );
1793 
1794  /* reset cons_countsols activation */
1795  if( !active )
1796  {
1797  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", FALSE) );
1798  }
1799  break;
1800 
1801  case SCIP_STAGE_PRESOLVED:
1802  case SCIP_STAGE_SOLVING:
1803  SCIPdialogMessage(scip, NULL, "problem is already presolved\n");
1804  break;
1805 
1806  case SCIP_STAGE_SOLVED:
1807  SCIPdialogMessage(scip, NULL, "problem is already (pre)solved\n");
1808  break;
1809 
1813  case SCIP_STAGE_INITSOLVE:
1814  case SCIP_STAGE_EXITSOLVE:
1815  case SCIP_STAGE_FREETRANS:
1816  case SCIP_STAGE_FREE:
1817  default:
1818  SCIPerrorMessage("invalid SCIP stage\n");
1819  return SCIP_INVALIDCALL;
1820  } /*lint --e{616}*/
1821 
1822  SCIPdialogMessage(scip, NULL, "\n");
1823  *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
1824 
1825  return SCIP_OKAY;
1826 }
1827 
1828 /** dialog execution method for the count command */
1829 SCIP_DECL_DIALOGEXEC(SCIPdialogExecCount)
1830 { /*lint --e{715}*/
1831  SCIP_RETCODE retcode;
1832  SCIP_Bool active;
1833 
1834  SCIP_Bool valid;
1835  SCIP_Longint nsols;
1836  int displayprimalbound;
1837  int displaygap;
1838  int displaysols;
1839  int displayfeasST;
1840  int nrestarts;
1841 
1842  SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
1843  SCIPdialogMessage(scip, NULL, "\n");
1844  SCIP_CALL( SCIPgetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", &active) );
1845  SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrestarts", &nrestarts) );
1846 
1847  if( nrestarts != 0 )
1848  {
1849  /* need to disabled restarts, since collecting solutions won't work but also the captures for variables are not
1850  * correctly handled
1851  */
1852  SCIPwarningMessage(scip, "counting forces parameter <presolving/maxrestarts> to 0\n");
1853  if( SCIPisParamFixed(scip, "presolving/maxrestarts") )
1854  {
1855  SCIP_CALL( SCIPunfixParam(scip, "presolving/maxrestarts") );
1856  }
1857  SCIP_CALL( SCIPsetIntParam(scip, "presolving/maxrestarts", 0) );
1858  }
1859 
1860  switch( SCIPgetStage(scip) )
1861  {
1862  case SCIP_STAGE_INIT:
1863  SCIPdialogMessage(scip, NULL, "no problem exists\n");
1864  break;
1865 
1866  case SCIP_STAGE_PROBLEM:
1867  /* activate constraint handler cons_countsols */
1868  if( !active )
1869  {
1870  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", TRUE) );
1871  }
1872  /*lint -fallthrough*/
1874  case SCIP_STAGE_PRESOLVING:
1875  /* presolve problem */
1876  SCIP_CALL( SCIPpresolve(scip) );
1877  /*lint -fallthrough*/
1878  case SCIP_STAGE_PRESOLVED:
1879  /* reset activity status of constraint handler cons_countsols */
1880  if( !active )
1881  {
1882  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", FALSE) );
1883  }
1884  /*lint -fallthrough*/
1885  case SCIP_STAGE_SOLVING:
1886  /* check if the problem contains continuous variables */
1887  if( SCIPgetNContVars(scip) != 0 )
1888  {
1890  "Problem contains continuous variables (after presolving). Counting projection to integral variables!\n");
1891  }
1892 
1893  /* turn off primal bound and gap column */
1894  SCIP_CALL( SCIPgetIntParam(scip, "display/primalbound/active", &displayprimalbound) );
1895  if( displayprimalbound != 0 )
1896  {
1897  SCIP_CALL( SCIPsetIntParam(scip, "display/primalbound/active", 0) );
1898  }
1899  SCIP_CALL( SCIPgetIntParam(scip, "display/gap/active", &displaygap) );
1900  if( displaygap != 0 )
1901  {
1902  SCIP_CALL( SCIPsetIntParam(scip, "display/gap/active", 0) );
1903  }
1904 
1905  /* turn on sols and feasST column */
1906  SCIP_CALL( SCIPgetIntParam(scip, "display/sols/active", &displaysols) );
1907  if( displayprimalbound != 2 )
1908  {
1909  SCIP_CALL( SCIPsetIntParam(scip, "display/sols/active", 2) );
1910  }
1911  SCIP_CALL( SCIPgetIntParam(scip, "display/feasST/active", &displayfeasST) );
1912  if( displayprimalbound != 2 )
1913  {
1914  SCIP_CALL( SCIPsetIntParam(scip, "display/feasST/active", 2) );
1915  }
1916 
1917  /* find the countsols constraint handler */
1918  assert( SCIPfindConshdlr(scip, CONSHDLR_NAME) != NULL );
1919 
1920  retcode = SCIPcount(scip);
1921 
1922  valid = FALSE;
1923  nsols = SCIPgetNCountedSols(scip, &valid);
1924 
1925  if( valid )
1926  SCIPdialogMessage(scip, NULL, "Feasible Solutions : %"SCIP_LONGINT_FORMAT"", nsols);
1927  else
1928  {
1929  char* buffer;
1930  int buffersize = SCIP_MAXSTRLEN;
1931  int requiredsize;
1932 
1933  SCIP_CALL( SCIPallocBufferArray(scip, &buffer, buffersize) );
1934  SCIPgetNCountedSolsstr(scip, &buffer, buffersize, &requiredsize);
1935 
1936  if( requiredsize > buffersize )
1937  {
1938  SCIP_CALL( SCIPreallocBufferArray(scip, &buffer, requiredsize) );
1939  SCIPgetNCountedSolsstr(scip, &buffer, buffersize, &requiredsize);
1940  }
1941 
1942  assert( buffersize >= requiredsize );
1943  SCIPdialogMessage(scip, NULL, "Feasible Solutions : %s", buffer);
1944 
1945  SCIPfreeBufferArray(scip, &buffer);
1946  }
1947 
1948  SCIPdialogMessage(scip, NULL, " (%d non-trivial feasible subtrees)\n", SCIPgetNCountedFeasSubtrees(scip));
1949 
1950  *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
1951 
1952  /* reset display columns */
1953  if( displayprimalbound != 0 )
1954  {
1955  SCIP_CALL( SCIPsetIntParam(scip, "display/primalbound/active", displayprimalbound) );
1956  }
1957  if( displaygap != 0 )
1958  {
1959  SCIP_CALL( SCIPsetIntParam(scip, "display/gap/active", displaygap) );
1960  }
1961 
1962  /* reset sols and feasST column */
1963  if( displaysols != 2 )
1964  {
1965  SCIP_CALL( SCIPsetIntParam(scip, "display/sols/active", displaysols) );
1966  }
1967  if( displayfeasST != 2 )
1968  {
1969  SCIP_CALL( SCIPsetIntParam(scip, "display/feasST/active", displayfeasST) );
1970  }
1971 
1972  /* reset cons_countsols activation */
1973  if( !active )
1974  {
1975  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", FALSE) );
1976  }
1977 
1978  /* evaluate retcode */
1979  SCIP_CALL( retcode );
1980  break;
1981 
1982  case SCIP_STAGE_SOLVED:
1983  SCIPdialogMessage(scip, NULL, "problem is already solved\n");
1984  break;
1985 
1989  case SCIP_STAGE_INITSOLVE:
1990  case SCIP_STAGE_EXITSOLVE:
1991  case SCIP_STAGE_FREETRANS:
1992  case SCIP_STAGE_FREE:
1993  default:
1994  SCIPerrorMessage("invalid SCIP stage\n");
1995  return SCIP_INVALIDCALL;
1996  } /*lint --e{616}*/
1997 
1998  SCIPdialogMessage(scip, NULL, "\n");
1999  *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
2000 
2001  return SCIP_OKAY;
2002 }
2003 
2004 /** comparison method for sorting variables by non-decreasing w.r.t. problem index */
2005 static
2006 SCIP_DECL_SORTPTRCOMP(varCompProbindex)
2007 {
2008  SCIP_VAR* var1;
2009  SCIP_VAR* var2;
2010 
2011  var1 = (SCIP_VAR*)elem1;
2012  var2 = (SCIP_VAR*)elem2;
2013 
2014  assert(var1 != NULL);
2015  assert(var2 != NULL);
2016 
2017  if( SCIPvarGetProbindex(var1) < SCIPvarGetProbindex(var2) )
2018  return -1;
2019  else if( SCIPvarGetProbindex(var1) > SCIPvarGetProbindex(var2) )
2020  return +1;
2021  else
2022  {
2023  assert(var1 == var2 || (SCIPvarGetProbindex(var1) == -1 && SCIPvarGetProbindex(var2) == -1));
2024  return 0;
2025  }
2026 }
2027 
2028 /** expands the sparse solutions and writes them to the file */
2029 static
2031  SCIP* scip, /**< SCIP data structure */
2032  FILE* file, /**< file handler */
2033  SCIP_VAR** allvars, /**< SCIP variables */
2034  int nallvars, /**< number of all variables */
2035  SCIP_VAR** activevars, /**< SCIP variables */
2036  int nactivevars, /**< number of active variables */
2037  SCIP_HASHMAP* hashmap, /**< hashmap from active solution variable to the position in the active
2038  * variables array
2039  */
2040  SCIP_SPARSESOL** sols, /**< sparse solutions to expands and write */
2041  int nsols /**< number of sparse solutions */
2042  )
2043 {
2044  SCIP_SPARSESOL* sparsesol;
2045  SCIP_VAR** vars;
2046  SCIP_Real* scalars;
2047  SCIP_Longint* sol;
2048  SCIP_Longint solcnt;
2049  int s;
2050  int v;
2051 
2052  assert(scip != NULL);
2053  assert(file != NULL);
2054  assert(hashmap != NULL);
2055  assert(allvars != NULL || nallvars == 0);
2056  assert(activevars != NULL || nactivevars == 0);
2057  assert(sols != NULL || nsols == 0);
2058 
2059  solcnt = 0;
2060 
2061  /* get memory to store active solution */
2062  SCIP_CALL( SCIPallocBufferArray(scip, &sol, nactivevars) );
2063  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nactivevars) );
2064  SCIP_CALL( SCIPallocBufferArray(scip, &scalars, nactivevars) );
2065 
2066  /* loop over all sparse solutions */
2067  for( s = 0; s < nsols; ++s )
2068  {
2069  sparsesol = sols[s]; /*lint !e613*/
2070  assert(sparsesol != NULL);
2071  assert(SCIPsparseSolGetNVars(sparsesol) == nactivevars);
2072 
2073  /* get first solution of the sparse solution */
2074  SCIPsparseSolGetFirstSol(sparsesol, sol, nactivevars);
2075 
2076  do
2077  {
2078  SCIP_Real objval;
2079 
2080  solcnt++;
2081 
2082  /* print solution number */
2083  SCIPinfoMessage(scip, file, "%d(%"SCIP_LONGINT_FORMAT"), ", s+1, solcnt);
2084 
2085  objval = 0.0;
2086 
2087  /* write none active variables */
2088  for( v = 0; v < nallvars; ++v )
2089  {
2090  SCIP_Real constant;
2091  SCIP_Real realvalue;
2092  int requiredsize;
2093  int nvars;
2094  int idx;
2095  int i;
2096 
2097  vars[0] = allvars[v]; /*lint !e613*/
2098  scalars[0] = 1.0;
2099  nvars = 1;
2100  constant = 0.0;
2101 
2102  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, &nvars, nallvars, &constant, &requiredsize, TRUE) );
2103  assert(requiredsize <= nallvars);
2104  assert(nvars <= nactivevars);
2105 
2106  realvalue = constant;
2107 
2108  for( i = 0; i < nvars; ++i )
2109  {
2110  assert(SCIPhashmapExists(hashmap, vars[i]));
2111  idx = ((int) (size_t)SCIPhashmapGetImage(hashmap, vars[i])) - 1;
2112  assert(0 <= idx && idx < nactivevars);
2113  assert(activevars[idx] == vars[i]); /*lint !e613*/
2114 
2115  objval += SCIPvarGetObj(vars[i]) * sol[idx];
2116  realvalue += scalars[i] * sol[idx];
2117  }
2118  assert(SCIPisIntegral(scip, realvalue));
2119 
2120  SCIPinfoMessage(scip, file, "%g, ", realvalue);
2121  }
2122 
2123  /* transform objective value into original problem space */
2124  objval = SCIPretransformObj(scip, objval);
2125 
2126  /* output the objective value of the solution */
2127  SCIPinfoMessage(scip, file, "%g\n", objval);
2128  }
2129  while( SCIPsparseSolGetNextSol(sparsesol, sol, nactivevars) );
2130  }
2131 
2132  /* free buffer arrays */
2133  SCIPfreeBufferArray(scip, &scalars);
2134  SCIPfreeBufferArray(scip, &vars);
2135  SCIPfreeBufferArray(scip, &sol);
2136 
2137  return SCIP_OKAY;
2138 }
2139 
2140 /** execution method of dialog for writing all solutions */
2141 SCIP_DECL_DIALOGEXEC(SCIPdialogExecWriteAllsolutions)
2142 { /*lint --e{715}*/
2143  FILE* file;
2144  SCIP_Longint nsols;
2145  char* filename;
2146  char* word;
2147  SCIP_Bool endoffile;
2148  SCIP_Bool valid;
2149 
2150  assert( scip != NULL );
2151 
2152  SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
2153 
2154  switch( SCIPgetStage(scip) )
2155  {
2156  case SCIP_STAGE_INIT:
2157  SCIPdialogMessage(scip, NULL, "no problem available\n");
2158  break;
2159  case SCIP_STAGE_PROBLEM:
2161  case SCIP_STAGE_FREETRANS:
2162  SCIPdialogMessage(scip, NULL, "the counting process was not started yet\n");
2163  break;
2166  case SCIP_STAGE_PRESOLVING:
2168  case SCIP_STAGE_PRESOLVED:
2169  case SCIP_STAGE_INITSOLVE:
2170  case SCIP_STAGE_SOLVING:
2171  case SCIP_STAGE_SOLVED:
2172  case SCIP_STAGE_EXITSOLVE:
2173  {
2174  SCIP_CONSHDLR* conshdlr;
2175  SCIP_CONSHDLRDATA* conshdlrdata;
2176  int nsparsesols;
2177 
2178  valid = FALSE;
2179  nsols = SCIPgetNCountedSols(scip, &valid);
2180 
2181  /* find the countsols constraint handler */
2182  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2183  assert( conshdlr != NULL );
2184 
2185  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2186  assert( conshdlrdata != NULL );
2187 
2188  nsparsesols = conshdlrdata->nsolutions;
2189 
2190  if( !valid )
2191  {
2192  /* too many solutions, output not "possible" */
2193  char* buffer;
2194  int buffersize;
2195  int requiredsize;
2196 
2197  buffersize = SCIP_MAXSTRLEN;
2198 
2199  SCIP_CALL( SCIPallocBufferArray(scip, &buffer, buffersize) );
2200  SCIPgetNCountedSolsstr(scip, &buffer, buffersize, &requiredsize);
2201 
2202  if( requiredsize > buffersize )
2203  {
2204  buffersize = requiredsize;
2205  SCIP_CALL( SCIPreallocBufferArray(scip, &buffer, requiredsize) );
2206  SCIPgetNCountedSolsstr(scip, &buffer, buffersize, &requiredsize);
2207  }
2208 
2209  assert( buffersize >= requiredsize );
2210  SCIPdialogMessage(scip, NULL, "no output, because of too many feasible solutions : %s\n", buffer);
2211 
2212  SCIPfreeBufferArray(scip, &buffer);
2213  }
2214  else if( nsols == 0 )
2215  {
2216  SCIPdialogMessage(scip, NULL, "there are no counted solutions\n");
2217  }
2218  else if( nsparsesols == 0 )
2219  {
2220  SCIPdialogMessage(scip, NULL, "there is no solution collect (set parameter <constraints/countsols/collect> to TRUE)\n");
2221  }
2222  else
2223  {
2224  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, "enter filename: ", &word, &endoffile) );
2225 
2226  /* copy the filename for later use */
2227  SCIP_CALL( SCIPduplicateBufferArray(scip, &filename, word, (int)strlen(word)+1) );
2228 
2229  if( endoffile )
2230  {
2231  *nextdialog = NULL;
2232  return SCIP_OKAY;
2233  }
2234 
2235  SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, filename, TRUE) );
2236 
2237  if( filename[0] != '\0' )
2238  {
2239  file = fopen(filename, "w");
2240 
2241  if( file == NULL )
2242  {
2243  SCIPdialogMessage(scip, NULL, "error creating file <%s>\n", filename);
2244  SCIPdialoghdlrClearBuffer(dialoghdlr);
2245  }
2246  else
2247  {
2248  SCIP_SPARSESOL** sparsesols;
2249  SCIP_VAR** origvars;
2250  SCIP_VAR** allvars;
2251  int norigvars;
2252  int nvars;
2253  int v;
2254 
2255  SCIP_RETCODE retcode;
2256 
2257  /* get sparse solutions defined over the active variables */
2258  nvars = conshdlrdata->nvars;
2259  sparsesols = conshdlrdata->solutions;
2260 
2261  /* get original problem variables */
2262  retcode = SCIPallocBufferArray(scip, &origvars, SCIPgetNOrigVars(scip));
2263  if( retcode != SCIP_OKAY )
2264  {
2265  fclose(file);
2266  SCIP_CALL( retcode );
2267  }
2268 
2269  norigvars = 0;
2270 
2271  for( v = 0; v < SCIPgetNOrigVars(scip); ++v )
2272  {
2274  {
2275  origvars[norigvars] = SCIPgetOrigVars(scip)[v];
2276  norigvars++;
2277  }
2278  }
2279  assert(norigvars == conshdlrdata->nallvars);
2280 
2281  retcode = SCIPduplicateBufferArray(scip, &allvars, conshdlrdata->allvars, norigvars);
2282  if( retcode != SCIP_OKAY )
2283  {
2284  fclose(file); /*lint !e449*/
2285  SCIP_CALL( retcode );
2286  }
2287 
2288  /* sort original variables array and the corresponding transformed variables w.r.t. the problem index */
2289  SCIPsortDownPtrPtr((void**)allvars, (void**)origvars, varCompProbindex, norigvars);
2290 
2291  SCIPdialogMessage(scip, NULL, "saving %"SCIP_LONGINT_FORMAT" (%d) feasible solutions\n", nsols, nsparsesols);
2292 
2293  /* first row: output the names of the variables in the given ordering */
2294  SCIPinfoMessage(scip, file, "#, ");
2295 
2296  for( v = 0; v < norigvars; ++v )
2297  {
2298 #ifndef NDEBUG
2299  {
2300  /* check if the original variable fits to the transform variable the constraint handler has */
2301  SCIP_VAR* transvar;
2302  SCIP_CALL( SCIPgetTransformedVar(scip, origvars[v], &transvar) );
2303  assert(transvar != NULL);
2304  assert(transvar == allvars[v]);
2305  }
2306 #endif
2307  SCIPinfoMessage(scip, file, "%s, ", SCIPvarGetName(origvars[v]));
2308  }
2309 
2310  SCIPinfoMessage(scip, file, "objval\n");
2311 
2312  /* expand and write solution */
2313  retcode = writeExpandedSolutions(scip, file, allvars, conshdlrdata->nallvars, conshdlrdata->vars, nvars, conshdlrdata->hashmap, sparsesols, nsparsesols);
2314  if( retcode != SCIP_OKAY )
2315  {
2316  fclose(file);
2317  SCIP_CALL( retcode );
2318  }
2319  SCIPdialogMessage(scip, NULL, "written solutions information to file <%s>\n", filename);
2320 
2321  SCIPfreeBufferArray(scip, &allvars);
2322  SCIPfreeBufferArray(scip, &origvars);
2323 
2324  fclose(file);
2325  }
2326 
2327  /* free buffer array */
2328  SCIPfreeBufferArray(scip, &filename);
2329  }
2330  }
2331  break;
2332  }
2333  case SCIP_STAGE_FREE:
2334  SCIPerrorMessage("invalid call during SCIP_STAGE_FREE\n");
2335  return SCIP_ERROR;
2336  }
2337 
2338  *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
2339 
2340  return SCIP_OKAY;
2341 }
2342 
2343 /** create the interactive shell dialogs for the counting process */
2344 static
2346  SCIP* scip /**< SCIP data structure */
2347  )
2348 {
2349  SCIP_DIALOG* root;
2350  SCIP_DIALOG* dialog;
2351  SCIP_DIALOG* setmenu;
2352  SCIP_DIALOG* submenu;
2353 
2354  /* includes or updates the default dialog menus in SCIP */
2356 
2357  root = SCIPgetRootDialog(scip);
2358  assert( root != NULL );
2359 
2360  /* add dialog entry for counting */
2361  if( !SCIPdialogHasEntry(root, "count") )
2362  {
2363  SCIP_CALL( SCIPincludeDialog(scip, &dialog, NULL, SCIPdialogExecCount, NULL, NULL,
2364  "count", "count number of feasible solutions", FALSE, NULL) );
2365  SCIP_CALL( SCIPaddDialogEntry(scip, root, dialog) );
2366  SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
2367  }
2368 
2369  /* add dialog entry for counting */
2370  if( !SCIPdialogHasEntry(root, "countpresolve") )
2371  {
2372  SCIP_CALL( SCIPincludeDialog(scip, &dialog, NULL, SCIPdialogExecCountPresolve, NULL, NULL,
2373  "countpresolve", "presolve instance before counting number of feasible solutions", FALSE, NULL) );
2374  SCIP_CALL( SCIPaddDialogEntry(scip, root, dialog) );
2375  SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
2376  }
2377 
2378  /* search for the "write" sub menu to add "allsolutions" dialog */
2379  if( SCIPdialogFindEntry(root, "write", &submenu) != 1 )
2380  {
2381  SCIPerrorMessage("write sub menu not found\n");
2382  return SCIP_PLUGINNOTFOUND;
2383  }
2384  assert(submenu != NULL);
2385 
2386  /* add dialog "allsolutions" to sub menu "write" */
2387  if( !SCIPdialogHasEntry(submenu, "allsolutions") )
2388  {
2389  SCIP_CALL( SCIPincludeDialog(scip, &dialog, NULL, SCIPdialogExecWriteAllsolutions, NULL, NULL,
2390  "allsolutions", "write all counted primal solutions to file", FALSE, NULL) );
2391  SCIP_CALL( SCIPaddDialogEntry(scip, submenu, dialog) );
2392  SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
2393  }
2394 
2395  /* search for the "set" sub menu to find the "emphasis" sub menu */
2396  if( SCIPdialogFindEntry(root, "set", &setmenu) != 1 )
2397  {
2398  SCIPerrorMessage("set sub menu not found\n");
2399  return SCIP_PLUGINNOTFOUND;
2400  }
2401  assert(setmenu != NULL);
2402 
2403  return SCIP_OKAY;
2404 }
2405 
2406 /*
2407  * Callback methods for columns
2408  */
2409 
2410 /** output method of display column to output file stream 'file' */
2411 static
2412 SCIP_DECL_DISPOUTPUT(dispOutputSols)
2413 { /*lint --e{715}*/
2414 #ifndef NDEBUG
2415  SCIP_CONSHDLR* conshdlr;
2416 #endif
2417  SCIP_Longint sols;
2418  SCIP_Bool valid;
2419 
2420  assert(disp != NULL);
2421  assert(strcmp(SCIPdispGetName(disp), DISP_SOLS_NAME) == 0);
2422  assert(scip != NULL);
2423 
2424 #ifndef NDEBUG
2425  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2426  assert( conshdlr != NULL );
2427  assert( SCIPconshdlrGetNConss(conshdlr) == 0 );
2428 #endif
2429 
2430  sols = SCIPgetNCountedSols(scip, &valid);
2431 
2432  if( !valid )
2433  {
2434  SCIPinfoMessage(scip, file, "TooMany");
2435  }
2436  else
2437  {
2439  }
2440 
2441  return SCIP_OKAY;
2442 }
2443 
2444 
2445 /** output method of display column to output file stream 'file' */
2446 static
2447 SCIP_DECL_DISPOUTPUT(dispOutputFeasSubtrees)
2448 { /*lint --e{715}*/
2449 #ifndef NDEBUG
2450  SCIP_CONSHDLR* conshdlr;
2451 #endif
2452 
2453  assert(disp != NULL);
2454  assert(scip != NULL);
2455  assert(strcmp(SCIPdispGetName(disp), DISP_CUTS_NAME) == 0);
2456 
2457 #ifndef NDEBUG
2458  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2459  assert( conshdlr != NULL );
2460  assert( SCIPconshdlrGetNConss(conshdlr) == 0 );
2461 #endif
2462 
2464 
2465  return SCIP_OKAY;
2466 }
2467 
2468 
2469 /*
2470  * Interface methods of constraint handler
2471  */
2472 
2473 /** creates the handler for countsols constraints and includes it in SCIP */
2474 static
2476  SCIP* scip, /**< SCIP data structure */
2477  SCIP_Bool dialogs /**< sould count dialogs be added */
2478  )
2479 {
2480  /* create countsol constraint handler data */
2481  SCIP_CONSHDLRDATA* conshdlrdata;
2482  SCIP_CONSHDLR* conshdlr;
2483 
2484 #ifdef WITH_GMP
2485  char gmpversion[20];
2486 #endif
2487 
2488  /* create constraint handler specific data here */
2489  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata) );
2490 
2491  /* include constraint handler */
2494  consEnfolpCountsols, consEnfopsCountsols, consCheckCountsols, consLockCountsols,
2495  conshdlrdata) );
2496 
2497  assert(conshdlr != NULL);
2498 
2499  /* set non-fundamental callbacks via specific setter functions */
2500  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyCountsols, consCopyCountsols) );
2501  SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitCountsols) );
2502  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolCountsols) );
2503  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeCountsols) );
2504  SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitCountsols) );
2505  SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolCountsols) );
2506 
2507  /* add countsols constraint handler parameters */
2509  "constraints/"CONSHDLR_NAME"/active",
2510  "is the constraint handler active?",
2511  &conshdlrdata->active, FALSE, DEFAULT_ACTIVE, NULL, NULL));
2513  "constraints/"CONSHDLR_NAME"/sparsetest",
2514  "should the sparse solution test be turned on?",
2515  &conshdlrdata->sparsetest, FALSE, DEFAULT_SPARSETEST, NULL, NULL));
2517  "constraints/"CONSHDLR_NAME"/discardsols",
2518  "is it allowed to discard solutions?",
2519  &conshdlrdata->discardsols, FALSE, DEFAULT_DISCARDSOLS, NULL, NULL));
2521  "constraints/"CONSHDLR_NAME"/collect",
2522  "should the solutions be collected?",
2523  &conshdlrdata->collect, FALSE, DEFAULT_COLLECT, NULL, NULL));
2525  "constraints/"CONSHDLR_NAME"/sollimit",
2526  "counting stops, if the given number of solutions were found (-1: no limit)",
2527  &conshdlrdata->sollimit, FALSE, DEFAULT_SOLLIMIT, -1LL, SCIP_LONGINT_MAX, NULL, NULL));
2528 
2529  /* create the interactive shell dialogs for the counting process */
2530  if( dialogs )
2531  {
2532  SCIP_CALL( createCountDialog(scip) );
2533  }
2534 
2535  /* include display column */
2537  NULL, NULL, NULL, NULL, NULL, NULL, dispOutputSols,
2540  NULL, NULL, NULL, NULL, NULL, NULL, dispOutputFeasSubtrees,
2542 
2543 #ifdef WITH_GMP
2544 #ifdef mpir_version
2545  /* add info about using MPIR to external codes information */
2546  (void) SCIPsnprintf(gmpversion, sizeof(gmpversion), "MPIR %s", mpir_version);
2547  SCIP_CALL( SCIPincludeExternalCodeInformation(scip, gmpversion, "Multiple Precision Integers and Rationals Library developed by W. Hart (mpir.org)") );
2548 #else
2549  /* add info about using GMP to external codes information */
2550  (void) SCIPsnprintf(gmpversion, sizeof(gmpversion), "GMP %s", gmp_version);
2551  SCIP_CALL( SCIPincludeExternalCodeInformation(scip, gmpversion, "GNU Multiple Precision Arithmetic Library developed by T. Granlund (gmplib.org)") );
2552 #endif
2553 #endif
2554 
2555  return SCIP_OKAY;
2556 }
2557 
2558 /** creates the handler for countsols constraints and includes it in SCIP */
2560  SCIP* scip /**< SCIP data structure */
2561  )
2562 {
2563  /* include constraint handler including the count dialog */
2565 
2566  return SCIP_OKAY;
2567 }
2568 
2569 
2570 /** execute counting */
2572  SCIP* scip /**< SCIP data structure */
2573  )
2574 {
2575  SCIP_Bool active;
2576 
2577  /* activate constraint handler cons_countsols */
2578  SCIP_CALL( SCIPgetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", &active) );
2579  if( !active )
2580  {
2581  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", TRUE) );
2582  }
2583 
2584  /* check if the parameter setting allows a valid counting process */
2585  SCIP_CALL( checkParameters(scip) );
2586 
2587  /* start the solving process */
2588  SCIP_CALL( SCIPsolve(scip) );
2589 
2590  /* reset activity status of constraint handler cons_countsols */
2591  if( !active )
2592  {
2593  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/"CONSHDLR_NAME"/active", FALSE) );
2594  }
2595 
2596  return SCIP_OKAY;
2597 }
2598 
2599 
2600 /** returns number of feasible solutions found as SCIP_Longint; if the number does not fit into
2601  * a SCIP_Longint the valid flag is set to FALSE
2602  */
2604  SCIP* scip, /**< SCIP data structure */
2605  SCIP_Bool* valid /**< pointer to store if the return value is valid */
2606  )
2607 {
2608  SCIP_CONSHDLR* conshdlr;
2609  SCIP_CONSHDLRDATA* conshdlrdata;
2610 
2611  /* find the countsols constraint handler */
2612  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2613  assert( conshdlr != NULL );
2614 
2615  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2616  assert( conshdlrdata != NULL );
2617 
2618  return getNCountedSols(conshdlrdata->nsols, valid);
2619 }
2620 
2621 
2622 /** puts the number of counted solutions in the given char* buffer */
2624  SCIP* scip, /**< SCIP data structure */
2625  char** buffer, /**< buffer to store the number for counted solutions */
2626  int buffersize, /**< buffer size */
2627  int* requiredsize /**< pointer to store the required size */
2628  )
2629 {
2630  SCIP_CONSHDLR* conshdlr;
2631  SCIP_CONSHDLRDATA* conshdlrdata;
2632 
2633  /* find the countsols constraint handler */
2634  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2635  assert( conshdlr != NULL );
2636 
2637  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2638  assert( conshdlrdata != NULL );
2639 
2640 #ifdef WITH_GMP
2641  /* size must be by two larger than the length of the string, since there need to be storage for a sign and a
2642  * null-termination
2643  */
2644  assert(0 <= (int) (mpz_sizeinbase( conshdlrdata->nsols, 10 ) + 2));
2645  *requiredsize = (int) (mpz_sizeinbase( conshdlrdata->nsols, 10 ) + 2);
2646  if( *requiredsize <= buffersize)
2647  toString(conshdlrdata->nsols, buffer, buffersize);
2648 #else
2649  if( conshdlrdata->nsols < pow(10.0, (double)buffersize) )
2650  {
2651  toString(conshdlrdata->nsols, buffer, buffersize);
2652  *requiredsize = (int)strlen(*buffer);
2653  }
2654  else
2655  *requiredsize = 21;
2656 #endif
2657 }
2658 
2659 
2660 /** returns number of counted non trivial feasible subtrees */
2662  SCIP* scip /**< SCIP data structure */
2663  )
2664 {
2665  SCIP_CONSHDLR* conshdlr;
2666  SCIP_CONSHDLRDATA* conshdlrdata;
2667 
2668  assert( scip != NULL );
2669 
2670  /* find the countsols constraint handler */
2671  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2672  assert( conshdlr != NULL );
2673 
2674  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2675  assert( conshdlrdata != NULL );
2676 
2677  return conshdlrdata->feasST;
2678 }
2679 
2680 
2681 /** Method to get the sparse solution.
2682  *
2683  * @note You get the pointer to the sparse solutions stored in the constraint handler (not a copy).
2684  *
2685  * @note The sparse solutions are stored w.r.t. the active variables. This are the variables which got not removed
2686  * during presolving. For none active variables the value has to be computed depending on their aggregation
2687  * type. See for more details about that \ref COLLECTALLFEASEBLES.
2688  */
2690  SCIP* scip, /**< SCIP data structure */
2691  SCIP_VAR*** vars, /**< pointer to active variable array defining to variable order */
2692  int* nvars, /**< number of active variables */
2693  SCIP_SPARSESOL*** sols, /**< pointer to the solutions */
2694  int* nsols /**< pointer to number of solutions */
2695  )
2696 {
2697  SCIP_CONSHDLR* conshdlr;
2698  SCIP_CONSHDLRDATA* conshdlrdata;
2699 
2700  assert( scip != NULL );
2701 
2702  /* find the countsols constraint handler */
2703  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2704  assert( conshdlr != NULL );
2705 
2706  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2707  assert( conshdlrdata != NULL );
2708 
2709  *vars = conshdlrdata->vars;
2710  *nvars = conshdlrdata->nvars;
2711  *sols = conshdlrdata->solutions;
2712  *nsols = conshdlrdata->nsolutions;
2713 }
2714 
2715 /** setting SCIP parameters for such that a valid counting process is possible */
2717  SCIP* scip /**< SCIP data structure */
2718  )
2719 {
2721  return SCIP_OKAY;
2722 }
2723