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