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