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