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