Scippy

    SCIP

    Solving Constraint Integer Programs

    cons_rpa.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-2025 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_rpa.c
    26 * @brief constraint handler for recursive circle packing
    27 * @author Benjamin Mueller
    28 *
    29 * This constraint handler is used to store information about which (not verified) rectangular patterns have been locked
    30 * and which circular patterns have not been tried to be verified yet.
    31 *
    32 * @todo Is it enough the lock the unverified circular pattern variables only in the positive direction?
    33 * @todo remove all unnecessary callbacks and defines
    34 */
    35
    36/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    37
    38#include <assert.h>
    39#include <string.h>
    40
    41#include "cons_rpa.h"
    42#include "probdata_rpa.h"
    43#include "pattern.h"
    44
    45
    46/* fundamental constraint handler properties */
    47#define CONSHDLR_NAME "rpa"
    48#define CONSHDLR_DESC "ringpacking constraint handler"
    49#define CONSHDLR_ENFOPRIORITY 1 /**< priority of the constraint handler for constraint enforcing */
    50#define CONSHDLR_CHECKPRIORITY -1 /**< priority of the constraint handler for checking feasibility */
    51#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
    52 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    53#define CONSHDLR_NEEDSCONS FALSE /**< should the constraint handler be skipped, if no constraints are available? */
    54
    55/* new best solution event handler properties */
    56#define EVENTHDLR_NAME "bestsol"
    57#define EVENTHDLR_DESC "best solution event handler"
    58
    59/* default values of parameters */
    60#define DEFAULT_VERIFICATION_NLPTILIM 10.0 /**< time limit for each verification NLP */
    61#define DEFAULT_VERIFICATION_NLPNODELIM 10000L /**< node limit for each verification NLP */
    62#define DEFAULT_VERIFICATION_HEURTILIM 10.0 /**< time limit for heuristic verification */
    63#define DEFAULT_VERIFICATION_HEURITERLIM 1000 /**< iteration limit for each heuristic verification */
    64#define DEFAULT_VERIFICATION_TOTALTILIM 3600.0 /**< total time limit for all verification problems during the solving process */
    65
    66/*
    67 * Data structures
    68 */
    69
    70/** constraint handler data */
    71struct SCIP_ConshdlrData
    72{
    73 SCIP_EVENTHDLR* eventhdlr; /**< event handler */
    74
    75 SCIP_Bool* locked; /**< array to remember which (not verified) patterns have been locked */
    76 int lockedsize; /**< size of locked array */
    77 SCIP_Bool* tried; /**< array to mark circular patterns that have been tried to be verified */\
    78
    79 /* parameter for verification */
    80 SCIP_Real timeleft; /**< time left for solving verification problem during the solving process */
    81 SCIP_Real nlptilim; /**< hard time limit for verification nlp */
    82 SCIP_Real heurtilim; /**< hard time limit for verification heuristic*/
    83 SCIP_Longint nlpnodelim; /**< hard node limit for verification nlp */
    84 int heuriterlim; /**< hard iteration limit for verification heuristic*/
    85};
    86
    87/*
    88 * Local methods
    89 */
    90
    91/** auxiliary function to decide whether a proposed solution is feasible; a solution is called feasible if and only if
    92 * z*_C = 0 holds for all circular patterns that are either not packable, i.e., SCIP_PACKABLE_NO or SCIP_PACKABLE_UNKNOWN
    93 */
    94static
    96 SCIP* scip, /**< SCIP data structure */
    97 SCIP_SOL* sol /**< solution (NULL for LP solution) */
    98 )
    99{
    100 SCIP_PROBDATA* probdata;
    101 SCIP_PATTERN** cpatterns;
    102 SCIP_VAR** cvars;
    103 int ncpatterns;
    104 int p;
    105
    106 probdata = SCIPgetProbData(scip);
    107 assert(probdata != NULL);
    108
    109 /* get information about circular patterns and their corresponding variables */
    110 SCIPprobdataGetCInfos(probdata, &cpatterns, &cvars, &ncpatterns);
    111 assert(ncpatterns > 0);
    112
    113 for( p = 0; p < ncpatterns; ++p )
    114 {
    115 assert(cpatterns[p] != NULL);
    116 assert(cvars[p] != NULL);
    117
    118 /* check only circular patterns which might not be packable */
    120 {
    121 SCIP_Real solval = SCIPgetSolVal(scip, sol, cvars[p]);
    122
    123 if( !SCIPisFeasZero(scip, solval) )
    124 {
    125 SCIPdebugMsg(scip, "solution might be infeasible because of circular pattern %d = (%g,%d)\n", p,
    126 SCIPgetSolVal(scip, sol, cvars[p]), SCIPpatternGetPackableStatus(cpatterns[p]));
    127 return FALSE;
    128 }
    129 }
    130 }
    131
    132 return TRUE;
    133}
    134
    135/** tries to verify a circular pattern; it first tries to call heuristic(s) and afterwards uses a verification NLP */
    136static
    138 SCIP* scip, /**< SCIP data structure */
    139 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    140 SCIP_PROBDATA* probdata, /**< problem data */
    141 SCIP_PATTERN* pattern /**< circular pattern */
    142 )
    143{
    144 SCIP_Real timelimit;
    145 SCIP_Real nlptimelimit;
    146 SCIP_Real heurtimelimit;
    147
    148 assert(probdata != NULL);
    149 assert(pattern != NULL);
    152
    153 /* get the total time limit */
    154 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
    155
    156 /* verify heuristically */
    157 heurtimelimit = MIN(timelimit - SCIPgetSolvingTime(scip), conshdlrdata->heurtilim); /*lint !e666*/
    158
    159 SCIPdebugMsg(scip, "call verification heuristic (%g,%d)\n", heurtimelimit, conshdlrdata->heuriterlim);
    160 conshdlrdata->timeleft += SCIPgetSolvingTime(scip);
    161 SCIP_CALL( SCIPverifyCircularPatternHeuristic(scip, probdata, pattern, heurtimelimit, conshdlrdata->heuriterlim) );
    162 conshdlrdata->timeleft -= SCIPgetSolvingTime(scip);
    163
    164 /* use verification NLP if pattern is still not verified */
    166 {
    167 nlptimelimit = MIN3(conshdlrdata->timeleft, timelimit - SCIPgetSolvingTime(scip), conshdlrdata->nlptilim); /*lint !e666*/
    168
    169 SCIPdebugMsg(scip, "call verification NLP (%g,%lld)\n", nlptimelimit, conshdlrdata->nlpnodelim);
    170 conshdlrdata->timeleft += SCIPgetSolvingTime(scip);
    171 SCIP_CALL( SCIPverifyCircularPatternNLP(scip, probdata, pattern, nlptimelimit, conshdlrdata->nlpnodelim) );
    172 conshdlrdata->timeleft -= SCIPgetSolvingTime(scip);
    173 }
    174
    175 SCIPdebugMsg(scip, "packable status? %d\n", SCIPpatternGetPackableStatus(pattern));
    176 SCIPcheckPattern(scip, probdata, pattern);
    177
    178 return SCIP_OKAY;
    179}
    180
    181/** auxiliary function for enforcing ringpacking constraint; the function checks whether
    182 *
    183 * 1. the solution is feasible; if yes -> skip
    184 * 2. tries to verify an unverified circular pattern C with z*_c > 0
    185 * 2a. case packable or unknown: go to 2.
    186 * 2b. case not packable: fix z_C to 0 -> skip
    187 * 3. fix all unverified circular patterns to 0
    188 *
    189 * Note that after step 3. the dual bound is not valid anymore.
    190 */
    191static
    193 SCIP* scip, /**< SCIP data structure */
    194 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    195 SCIP_SOL* sol, /**< solution (NULL for LP solution) */
    196 SCIP_RESULT* result /**< pointer to store the result */
    197 )
    198{
    199 SCIP_CONSHDLRDATA* conshdlrdata;
    200 SCIP_PROBDATA* probdata;
    201 SCIP_PATTERN** cpatterns;
    202 SCIP_VAR** cvars;
    203 int ncpatterns;
    204 int p;
    205
    206#ifdef SCIP_DEBUG
    207 SCIPdebugMsg(scip, "enforce solution:\n");
    209#endif
    210
    211 *result = SCIP_FEASIBLE;
    212
    213 /* (1.) check whether the solution is already feasible */
    214 if( isSolFeasible(scip, sol) )
    215 return SCIP_OKAY;
    216
    217 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    218 assert(conshdlrdata != NULL);
    219 probdata = SCIPgetProbData(scip);
    220 assert(probdata != NULL);
    221
    222 /* get circular pattern information */
    223 SCIPprobdataGetCInfos(probdata, &cpatterns, &cvars, &ncpatterns);
    224 assert(cpatterns != NULL);
    225 assert(cvars != NULL);
    226 assert(ncpatterns > 0);
    227
    228 /* (2.) try to verify a pattern */
    229 for( p = 0; p < ncpatterns; ++p )
    230 {
    231 SCIP_Real solval;
    232 SCIP_Bool infeasible;
    233 SCIP_Bool success;
    234
    235 assert(cpatterns[p] != NULL);
    236 assert(cvars[p] != NULL);
    237
    238 solval = SCIPgetSolVal(scip, sol, cvars[p]);
    239
    240 /* skip unused circular patterns */
    241 if( SCIPisFeasZero(scip, solval) )
    242 continue;
    243
    244 /* try to verify an unknown circular pattern */
    245 if( SCIPpatternGetPackableStatus(cpatterns[p]) == SCIP_PACKABLE_UNKNOWN && !conshdlrdata->tried[p] )
    246 {
    247 SCIP_CALL( verifyCircularPattern(scip, conshdlrdata, probdata, cpatterns[p]) );
    248 conshdlrdata->tried[p] = TRUE;
    249 }
    250
    251 /* (2a.) fix corresponding variable to zero if pattern is not packable */
    253 {
    254 SCIP_CALL( SCIPfixVar(scip, cvars[p], 0.0, &infeasible, &success) );
    255 SCIPdebugMsg(scip, "fix unpackable pattern %d\n", p);
    256
    257 if( infeasible )
    258 {
    259 *result = SCIP_CUTOFF;
    260 return SCIP_OKAY;
    261 }
    262 else if( success )
    263 {
    264 /* stop since we cutoff the LP solution */
    265 *result = SCIP_REDUCEDDOM;
    266 return SCIP_OKAY;
    267 }
    268 }
    269 }
    270
    271 SCIPdebugMsg(scip, "fix all tested but still unverified circular patterns\n");
    272
    273 /* (3.) fix an unverified patterns that is used */
    274 for( p = 0; p < ncpatterns; ++p )
    275 {
    277 {
    278 SCIP_Bool infeasible;
    279 SCIP_Bool success;
    280
    281 SCIP_CALL( SCIPfixVar(scip, cvars[p], 0.0, &infeasible, &success) );
    282 SCIPdebugMsg(scip, "fix unknown pattern %d in [%g,%g] (success=%u)\n", p, SCIPvarGetLbLocal(cvars[p]),
    283 SCIPvarGetUbLocal(cvars[p]), success);
    284
    285 /* dual bound is not valid anymore */
    287
    288 if( infeasible )
    289 {
    290 *result = SCIP_CUTOFF;
    291 return SCIP_OKAY;
    292 }
    293 else if( success )
    294 *result = SCIP_REDUCEDDOM;
    295 }
    296 }
    297
    298 return SCIP_OKAY;
    299}
    300
    301/** get shading of a given pattern type */
    302static
    304 int type, /**< pattern type */
    305 int ntypes /**< total number of patterns */
    306 )
    307{
    308 assert(type >= 0);
    309 assert(type < ntypes);
    310
    311 return (int)MIN(100, MAX(ntypes, 100) / (type+1));
    312}
    313
    314/*
    315 * Callback methods of event handler
    316 */
    317
    318/** processes the event that a new primal solution has been found */
    319static
    320SCIP_DECL_EVENTEXEC(processNewSolutionEvent)
    321{ /*lint --e{715}*/
    322 SCIP_PATTERN** patterns;
    323 SCIP_VAR** vars;
    324 SCIP_PROBDATA* probdata;
    325 SCIP_SOL* sol;
    326 char* filename;
    327 int npatterns;
    328 int p;
    329
    330 assert((SCIPeventGetType(event) & SCIP_EVENTTYPE_SOLFOUND) != 0);
    331
    332 probdata = SCIPgetProbData(scip);
    333 assert(probdata != NULL);
    334
    335 sol = SCIPeventGetSol(event);
    336 assert(sol != NULL);
    337
    338 /* check whether new solution is indeed feasible */
    339#ifndef NDEBUG
    340 {
    341 /* check circular patterns */
    342 SCIPprobdataGetCInfos(probdata, &patterns, &vars, &npatterns);
    343 assert(npatterns > 0);
    344
    345 for( p = 0; p < npatterns; ++p )
    346 {
    347 SCIP_Real val;
    348
    349 assert(patterns[p] != NULL);
    350 assert(vars[p] != NULL);
    351
    352 val = SCIPgetSolVal(scip, sol, vars[p]);
    353
    354 /* pattern is either not used or packable */
    355 assert(SCIPisFeasZero(scip, val) || SCIPpatternGetPackableStatus(patterns[p]) == SCIP_PACKABLE_YES);
    356 SCIPcheckPattern(scip, probdata, patterns[p]);
    357 }
    358
    359 /* check rectangular patterns */
    360 SCIPprobdataGetRInfos(probdata, &patterns, &vars, &npatterns);
    361 assert(npatterns > 0);
    362
    363 for( p = 0; p < npatterns; ++p )
    364 SCIPcheckPattern(scip, probdata, patterns[p]);
    365 }
    366#endif
    367
    368 /* write best solution information into a tex file */
    369 SCIP_CALL( SCIPgetStringParam(scip, "ringpacking/texfilename", &filename) );
    370
    371 if( strcmp(filename, "") != 0 )
    372 {
    373 FILE* file;
    374 SCIP_Real* rexts;
    375 SCIP_Real* rints;
    376 int* demands;
    377 SCIP_Real width;
    378 SCIP_Real height;
    379 int ntypes;
    380
    381 rexts = SCIPprobdataGetRexts(probdata);
    382 rints = SCIPprobdataGetRints(probdata);
    383 demands = SCIPprobdataGetDemands(probdata);
    384 width = SCIPprobdataGetWidth(probdata);
    385 height = SCIPprobdataGetHeight(probdata);
    386 ntypes = SCIPprobdataGetNTypes(probdata);
    387
    388 SCIPdebugMsg(scip, "write best solution into %s\n", filename);
    389
    390 file = fopen(filename, "w");
    391 assert(file != NULL);
    392
    393 /* latex header */
    394 SCIPinfoMessage(scip, file, "\\documentclass[preview]{standalone}\n");
    395 SCIPinfoMessage(scip, file, "\\usepackage{tikz}\n");
    396 SCIPinfoMessage(scip, file, "\\usepackage{xstring}\n\n");
    397 SCIPinfoMessage(scip, file, "\\begin{document}\n\n");
    398
    399 /* circular patterns */
    400 SCIPinfoMessage(scip, file, "\\section*{circular patterns}\n\n");
    401 SCIPprobdataGetCInfos(probdata, &patterns, &vars, &npatterns);
    402 for( p = 0; p < npatterns; ++p )
    403 {
    405 {
    406 int type = SCIPpatternGetCircleType(patterns[p]);
    407 int i;
    408
    409 SCIPinfoMessage(scip, file, "\\StrSubstitute{%s}{_}{-}[\\pname]\n", SCIPvarGetName(vars[p]));
    410 SCIPinfoMessage(scip, file, "\\subsection*{\\texttt{\\pname} = %g demand=%d}\n",
    411 SCIPgetSolVal(scip, sol, vars[p]), demands[type]);
    412 SCIPinfoMessage(scip, file, "\\resizebox{0.3\\textwidth}{!}{\n");
    413 SCIPinfoMessage(scip, file, "\\begin{tikzpicture}\n");
    414 SCIPinfoMessage(scip, file, "\\draw[draw=none,fill=black!%d!white] (%g,%g) circle (%g);\n",
    415 getShadingVal(type, ntypes), 0.0, 0.0, rexts[type]);
    416 SCIPinfoMessage(scip, file, "\\draw[draw=none,fill=white] (%g,%g) circle (%g);\n", 0.0, 0.0, rints[type]);
    417
    418 for( i = 0; i < SCIPpatternGetNElemens(patterns[p]); ++i )
    419 {
    420 int elemtype = SCIPpatternGetElementType(patterns[p], i);
    421 SCIP_Real x = SCIPpatternGetElementPosX(patterns[p], i);
    422 SCIP_Real y = SCIPpatternGetElementPosY(patterns[p], i);
    423 SCIP_Real _rext = rexts[elemtype];
    424 SCIP_Real _rint = rints[elemtype];
    425
    426 SCIPinfoMessage(scip, file, "\\draw[draw=none,fill=black!%d!white] (%g,%g) circle (%g);\n",
    427 getShadingVal(elemtype, ntypes), x, y, _rext);
    428 SCIPinfoMessage(scip, file, "\\draw[draw=none,fill=white] (%g,%g) circle (%g);\n", x, y, _rint);
    429 }
    430
    431 SCIPinfoMessage(scip, file, "\\end{tikzpicture}\n");
    432 SCIPinfoMessage(scip, file, "}\n\n");
    433 }
    434 }
    435
    436 /* rectangular patterns */
    437 SCIPinfoMessage(scip, file, "\\section*{rectangular patterns}\n\n");
    438 SCIPprobdataGetRInfos(probdata, &patterns, &vars, &npatterns);
    439 for( p = 0; p < npatterns; ++p )
    440 {
    441 int i;
    442
    443 assert(SCIPpatternGetPackableStatus(patterns[p]) == SCIP_PACKABLE_YES);
    444
    445 SCIPinfoMessage(scip, file, "\\StrSubstitute{%s}{_}{-}[\\pname]\n", SCIPvarGetName(vars[p]));
    446 SCIPinfoMessage(scip, file, "\\subsection*{\\texttt{\\pname} = %g}\n", SCIPgetSolVal(scip, sol, vars[p]));
    447 SCIPinfoMessage(scip, file, "\\resizebox{0.3\\textwidth}{!}{\n");
    448 SCIPinfoMessage(scip, file, "\\begin{tikzpicture}\n");
    449
    450 for( i = 0; i < SCIPpatternGetNElemens(patterns[p]); ++i )
    451 {
    452 int elemtype = SCIPpatternGetElementType(patterns[p], i);
    453 SCIP_Real x = SCIPpatternGetElementPosX(patterns[p], i);
    454 SCIP_Real y = SCIPpatternGetElementPosY(patterns[p], i);
    455 SCIP_Real _rext = rexts[elemtype];
    456
    457 SCIPinfoMessage(scip, file, "\\draw[draw=none,fill=black!%d!white] (%g,%g) circle (%g);\n",
    458 getShadingVal(elemtype, ntypes), x, y, _rext);
    459 /* SCIPinfoMessage(scip, file, "\\draw[draw=none,fill=white] (%g,%g) circle (%g);\n", x, y, _rint); */
    460 }
    461
    462 SCIPinfoMessage(scip, file, "\\draw[] (%g,%g) -- (%g,%g) -- (%g,%g) -- (%g,%g) -- cycle;\n",
    463 0.0, 0.0, 0.0, height, width, height, width, 0.0);
    464
    465 SCIPinfoMessage(scip, file, "\\end{tikzpicture}\n");
    466 SCIPinfoMessage(scip, file, "}\n\n");
    467 }
    468
    469 SCIPinfoMessage(scip, file, "\\end{document}\n");
    470
    471 fclose(file);
    472 }
    473
    474 return SCIP_OKAY;
    475}
    476
    477
    478/*
    479 * Callback methods of constraint handler
    480 */
    481
    482
    483/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    484static
    486{ /*lint --e{715}*/
    487 SCIP_CONSHDLRDATA* conshdlrdata = SCIPconshdlrGetData(conshdlr);
    488 assert(conshdlrdata != NULL);
    489
    490 if( conshdlrdata->locked != NULL )
    491 {
    492 SCIPfreeBlockMemoryArray(scip, &conshdlrdata->locked, conshdlrdata->lockedsize);
    493 conshdlrdata->lockedsize = 0;
    494 }
    495
    496 SCIPfreeBlockMemory(scip, &conshdlrdata);
    497
    498 return SCIP_OKAY;
    499}
    500
    501
    502/** solving process initialization method of constraint handler (called when branch and bound process is about to begin) */
    503static
    505{ /*lint --e{715}*/
    506 SCIP_CONSHDLRDATA* conshdlrdata;
    507 SCIP_PROBDATA* probdata;
    508 int ncpatterns;
    509
    510 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    511 assert(conshdlrdata != NULL);
    512 assert(conshdlrdata->tried == NULL);
    513
    514 probdata = SCIPgetProbData(scip);
    515 assert(probdata != NULL);
    516
    517 SCIPprobdataGetCInfos(probdata, NULL, NULL, &ncpatterns);
    518 assert(ncpatterns > 0);
    519
    520 /* allocate memory to remember which patterns have been tested to be packable */
    521 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &conshdlrdata->tried, ncpatterns) );
    522 BMSclearMemoryArray(conshdlrdata->tried, ncpatterns);
    523
    524 /* catch events for new solutions */
    525 SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_BESTSOLFOUND, conshdlrdata->eventhdlr, NULL, NULL) );
    526
    527 return SCIP_OKAY;
    528}
    529
    530
    531/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    532static
    534{ /*lint --e{715}*/
    535 SCIP_CONSHDLRDATA* conshdlrdata;
    536 SCIP_PROBDATA* probdata;
    537 int ncpatterns;
    538
    539 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    540 assert(conshdlrdata != NULL);
    541 assert(conshdlrdata->tried != NULL);
    542
    543 probdata = SCIPgetProbData(scip);
    544 assert(probdata != NULL);
    545
    546 SCIPprobdataGetCInfos(probdata, NULL, NULL, &ncpatterns);
    547 assert(ncpatterns > 0);
    548
    549 SCIPfreeBlockMemoryArray(scip, &conshdlrdata->tried, ncpatterns);
    550
    551 /* free events for new solutions */
    552 SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_BESTSOLFOUND, conshdlrdata->eventhdlr, NULL, -1) );
    553
    554 return SCIP_OKAY;
    555}
    556
    557
    558/** constraint enforcing method of constraint handler for LP solutions */
    559static
    561{ /*lint --e{715}*/
    562 SCIP_CALL( enforceSol(scip, conshdlr, NULL, result) );
    563
    564 return SCIP_OKAY;
    565}
    566
    567
    568/** constraint enforcing method of constraint handler for relaxation solutions */
    569static
    570SCIP_DECL_CONSENFORELAX(consEnforelaxRpa)
    571{ /*lint --e{715}*/
    572 SCIP_CALL( enforceSol(scip, conshdlr, sol, result) );
    573
    574 return SCIP_OKAY;
    575}
    576
    577
    578/** constraint enforcing method of constraint handler for pseudo solutions */
    579static
    581{ /*lint --e{715}*/
    582 SCIP_CALL( enforceSol(scip, conshdlr, NULL, result) );
    583
    584 return SCIP_OKAY;
    585}
    586
    587
    588/** feasibility check method of constraint handler for integral solutions */
    589static
    591{ /*lint --e{715}*/
    593
    594 return SCIP_OKAY;
    595}
    596
    597/** variable rounding lock method of constraint handler */
    598static
    600{ /*lint --e{715}*/
    601 SCIP_CONSHDLRDATA* conshdlrdata;
    602 SCIP_PROBDATA* probdata;
    603 SCIP_PATTERN** cpatterns;
    604 SCIP_VAR** cvars;
    605 SCIP_Bool first;
    606 int ncpatterns;
    607 int p;
    608
    609 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    610 assert(conshdlrdata != NULL);
    611
    612 probdata = SCIPgetProbData(scip);
    613 assert(probdata != NULL);
    614
    615 /* get circular patterns and corresponding variables */
    616 SCIPprobdataGetCInfos(probdata, &cpatterns, &cvars, &ncpatterns);
    617 assert(cpatterns != NULL);
    618 assert(cvars != NULL);
    619 assert(ncpatterns > 0);
    620
    621 /* remember whether we have locked the variables for the first time */
    622 if( conshdlrdata->locked == NULL )
    623 {
    624 first = TRUE;
    625 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &conshdlrdata->locked, ncpatterns) );
    626 BMSclearMemoryArray(conshdlrdata->locked, ncpatterns);
    627 conshdlrdata->lockedsize = ncpatterns;
    628 }
    629 else
    630 first = FALSE;
    631
    632 /*
    633 * A pattern might change its status during a later verification step and we only need to lock patterns with a
    634 * SCIP_PACKABLE_UNKNOWN status. For this reason, we keep track of patterns that have been locked. The CONSLOCK
    635 * callback should only be called twice because the constraint handler does not have constraints.
    636 */
    637 for( p = 0; p < ncpatterns; ++p )
    638 {
    639 assert(cpatterns[p] != NULL);
    640 assert(cvars[p] != NULL);
    641
    642 if( first && SCIPpatternGetPackableStatus(cpatterns[p]) == SCIP_PACKABLE_UNKNOWN )
    643 {
    644 assert(!conshdlrdata->locked[p]);
    645 assert(nlocksneg + nlockspos > 0);
    646
    647 SCIP_CALL( SCIPaddVarLocksType(scip, cvars[p], SCIP_LOCKTYPE_MODEL, nlocksneg + nlockspos,
    648 nlocksneg + nlockspos) );
    649 conshdlrdata->locked[p] = TRUE;
    650 SCIPdebugMsg(scip, "lock %s\n", SCIPvarGetName(cvars[p]));
    651 }
    652 else if( !first && conshdlrdata->locked[p] )
    653 {
    654 assert(nlocksneg + nlockspos < 0);
    655
    656 SCIP_CALL( SCIPaddVarLocksType(scip, cvars[p], SCIP_LOCKTYPE_MODEL, nlocksneg + nlockspos,
    657 nlocksneg + nlockspos) );
    658 conshdlrdata->locked[p] = FALSE;
    659 SCIPdebugMsg(scip, "unlock %s\n", SCIPvarGetName(cvars[p]));
    660 }
    661 }
    662
    663 return SCIP_OKAY;
    664}
    665
    666
    667/*
    668 * constraint specific interface methods
    669 */
    670
    671
    672/** creates the handler for ringpacking */
    674 SCIP* scip /**< SCIP data structure */
    675 )
    676{
    677 SCIP_CONSHDLRDATA* conshdlrdata;
    678 SCIP_CONSHDLR* conshdlr = NULL;
    679
    680 SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
    681 BMSclearMemory(conshdlrdata);
    682
    683 /* include constraint handler */
    686 consEnfolpRpa, consEnfopsRpa, consCheckRpa, consLockRpa,
    687 conshdlrdata) );
    688 assert(conshdlr != NULL);
    689
    690 /* set non-fundamental callbacks via specific setter functions */
    691 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolRpa) );
    692 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeRpa) );;
    693 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolRpa) );
    694 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxRpa) );
    695
    696 /* add event handler for new solutios */
    698 processNewSolutionEvent, NULL) );
    699
    700 /* add verification parameters */
    702 "ringpacking/verification/nlptilim",
    703 "time limit for verification NLP",
    704 &conshdlrdata->nlptilim, FALSE, DEFAULT_VERIFICATION_NLPTILIM, -1.0, SCIP_REAL_MAX, NULL, NULL) );
    705
    707 "ringpacking/verification/nlpnodelim",
    708 "node limit for verification NLP",
    709 &conshdlrdata->nlpnodelim, FALSE, DEFAULT_VERIFICATION_NLPNODELIM, 0L, SCIP_LONGINT_MAX, NULL, NULL) );
    710
    712 "ringpacking/verification/heurtilim",
    713 "time limit for heuristic verification",
    714 &conshdlrdata->heurtilim, FALSE, DEFAULT_VERIFICATION_HEURTILIM, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    715
    717 "ringpacking/verification/heuriterlim",
    718 "iteration limit for heuristic verification",
    719 &conshdlrdata->heuriterlim, FALSE, DEFAULT_VERIFICATION_HEURITERLIM, 0, INT_MAX, NULL, NULL) );
    720
    722 "ringpacking/verification/totaltilim",
    723 "total time limit for all verification problems during the solving process",
    724 &conshdlrdata->timeleft, FALSE, DEFAULT_VERIFICATION_TOTALTILIM, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    725
    726 return SCIP_OKAY;
    727}
    SCIP_VAR ** y
    Definition: circlepacking.c:64
    SCIP_VAR ** x
    Definition: circlepacking.c:63
    static SCIP_DECL_CONSFREE(consFreeRpa)
    Definition: cons_rpa.c:485
    static SCIP_DECL_CONSLOCK(consLockRpa)
    Definition: cons_rpa.c:599
    static SCIP_Bool isSolFeasible(SCIP *scip, SCIP_SOL *sol)
    Definition: cons_rpa.c:95
    #define CONSHDLR_NEEDSCONS
    Definition: cons_rpa.c:53
    #define CONSHDLR_CHECKPRIORITY
    Definition: cons_rpa.c:50
    #define DEFAULT_VERIFICATION_HEURTILIM
    Definition: cons_rpa.c:62
    #define CONSHDLR_DESC
    Definition: cons_rpa.c:48
    static SCIP_DECL_CONSENFOPS(consEnfopsRpa)
    Definition: cons_rpa.c:580
    static SCIP_DECL_CONSEXITSOL(consExitsolRpa)
    Definition: cons_rpa.c:533
    static int getShadingVal(int type, int ntypes)
    Definition: cons_rpa.c:303
    static SCIP_DECL_CONSCHECK(consCheckRpa)
    Definition: cons_rpa.c:590
    #define DEFAULT_VERIFICATION_TOTALTILIM
    Definition: cons_rpa.c:64
    static SCIP_DECL_EVENTEXEC(processNewSolutionEvent)
    Definition: cons_rpa.c:320
    static SCIP_DECL_CONSENFOLP(consEnfolpRpa)
    Definition: cons_rpa.c:560
    static SCIP_RETCODE verifyCircularPattern(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_PROBDATA *probdata, SCIP_PATTERN *pattern)
    Definition: cons_rpa.c:137
    static SCIP_RETCODE enforceSol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_SOL *sol, SCIP_RESULT *result)
    Definition: cons_rpa.c:192
    #define DEFAULT_VERIFICATION_NLPNODELIM
    Definition: cons_rpa.c:61
    static SCIP_DECL_CONSINITSOL(consInitsolRpa)
    Definition: cons_rpa.c:504
    #define DEFAULT_VERIFICATION_NLPTILIM
    Definition: cons_rpa.c:60
    static SCIP_DECL_CONSENFORELAX(consEnforelaxRpa)
    Definition: cons_rpa.c:570
    #define DEFAULT_VERIFICATION_HEURITERLIM
    Definition: cons_rpa.c:63
    #define CONSHDLR_EAGERFREQ
    Definition: cons_rpa.c:51
    #define EVENTHDLR_DESC
    Definition: cons_rpa.c:57
    #define CONSHDLR_ENFOPRIORITY
    Definition: cons_rpa.c:49
    #define CONSHDLR_NAME
    Definition: cons_rpa.c:47
    #define EVENTHDLR_NAME
    Definition: cons_rpa.c:56
    constraint handler for ringpacking
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define MIN3(x, y, z)
    Definition: def.h:232
    #define SCIP_LONGINT_MAX
    Definition: def.h:142
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPincludeConshdlrRpa(SCIP *scip)
    Definition: cons_rpa.c:673
    SCIP_PROBDATA * SCIPgetProbData(SCIP *scip)
    Definition: scip_prob.c:1139
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    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_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
    Definition: scip_param.c:307
    SCIP_RETCODE SCIPgetStringParam(SCIP *scip, const char *name, char **value)
    Definition: scip_param.c:345
    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
    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:4336
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_SOL * SCIPeventGetSol(SCIP_EVENT *event)
    Definition: event.c:1567
    SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:293
    SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: scip_event.c:333
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2349
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
    Definition: scip_var.c:10318
    #define BMSclearMemory(ptr)
    Definition: memory.h:129
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    SCIP_Real SCIPpatternGetElementPosY(SCIP_PATTERN *pattern, int elem)
    Definition: pattern.c:269
    SCIP_Real SCIPpatternGetElementPosX(SCIP_PATTERN *pattern, int elem)
    Definition: pattern.c:257
    SCIP_PATTERNTYPE SCIPpatternGetPatternType(SCIP_PATTERN *pattern)
    Definition: pattern.c:296
    SCIP_PACKABLE SCIPpatternGetPackableStatus(SCIP_PATTERN *pattern)
    Definition: pattern.c:335
    int SCIPpatternGetElementType(SCIP_PATTERN *pattern, int i)
    Definition: pattern.c:225
    int SCIPpatternGetNElemens(SCIP_PATTERN *pattern)
    Definition: pattern.c:215
    int SCIPpatternGetCircleType(SCIP_PATTERN *pattern)
    Definition: pattern.c:309
    pattern data for ringpacking problem
    @ SCIP_PATTERNTYPE_CIRCULAR
    Definition: pattern.h:51
    @ SCIP_PACKABLE_NO
    Definition: pattern.h:43
    @ SCIP_PACKABLE_YES
    Definition: pattern.h:44
    @ SCIP_PACKABLE_UNKNOWN
    Definition: pattern.h:45
    SCIP_Real SCIPprobdataGetHeight(SCIP_PROBDATA *probdata)
    SCIP_RETCODE SCIPverifyCircularPatternNLP(SCIP *scip, SCIP_PROBDATA *probdata, SCIP_PATTERN *pattern, SCIP_Real timelim, SCIP_Longint nodelim)
    int * SCIPprobdataGetDemands(SCIP_PROBDATA *probdata)
    void SCIPprobdataGetRInfos(SCIP_PROBDATA *probdata, SCIP_PATTERN ***rpatterns, SCIP_VAR ***rvars, int *nrpatterns)
    int SCIPprobdataGetNTypes(SCIP_PROBDATA *probdata)
    void SCIPprobdataGetCInfos(SCIP_PROBDATA *probdata, SCIP_PATTERN ***cpatterns, SCIP_VAR ***cvars, int *ncpatterns)
    SCIP_Real * SCIPprobdataGetRexts(SCIP_PROBDATA *probdata)
    SCIP_RETCODE SCIPverifyCircularPatternHeuristic(SCIP *scip, SCIP_PROBDATA *probdata, SCIP_PATTERN *pattern, SCIP_Real timelim, int iterlim)
    SCIP_Real * SCIPprobdataGetRints(SCIP_PROBDATA *probdata)
    void SCIPprobdataInvalidateDualbound(SCIP *scip, SCIP_PROBDATA *probdata)
    void SCIPcheckPattern(SCIP *scip, SCIP_PROBDATA *probdata, SCIP_PATTERN *pattern)
    SCIP_Real SCIPprobdataGetWidth(SCIP_PROBDATA *probdata)
    Problem data for ringpacking problem.
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    #define SCIP_EVENTTYPE_BESTSOLFOUND
    Definition: type_event.h:106
    #define SCIP_EVENTTYPE_SOLFOUND
    Definition: type_event.h:146
    struct SCIP_ProbData SCIP_PROBDATA
    Definition: type_prob.h:53
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141