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