SCIP Doxygen Documentation
Loading...
Searching...
No Matches
presol_dualcomp.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 presol_dualcomp.c
26 * @ingroup DEFPLUGINS_PRESOL
27 * @brief dual compensation presolver
28 * @author Dieter Weninger
29 *
30 * This presolver looks for variables with
31 * i) objcoef >= 0 and exactly one downlock
32 * ii) objcoef <= 0 and exactly one uplock
33 * and fixes the variable in case i) at the lower bound and in case ii) at the
34 * upper bound if a combination of singleton continuous variables can compensate
35 * the downlock in case i) and the uplock in case ii).
36 */
37
38/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
39
42#include "scip/pub_matrix.h"
43#include "scip/pub_message.h"
44#include "scip/pub_presol.h"
45#include "scip/pub_var.h"
46#include "scip/scip_general.h"
47#include "scip/scip_mem.h"
48#include "scip/scip_message.h"
49#include "scip/scip_nlp.h"
50#include "scip/scip_numerics.h"
51#include "scip/scip_param.h"
52#include "scip/scip_presol.h"
53#include "scip/scip_pricer.h"
54#include "scip/scip_prob.h"
55#include "scip/scip_probing.h"
56#include "scip/scip_var.h"
57
58
59#define PRESOL_NAME "dualcomp"
60#define PRESOL_DESC "compensate single up-/downlocks by singleton continuous variables"
61
62/* we need singleton continuous variables for the lock compensation,
63 * thus it is presumably a good idea to call this presolver before stuffing, which
64 * fixes singleton continuous variables
65 */
66#define PRESOL_PRIORITY -50 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
67#define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
68#define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
69
70#define DEFAULT_COMP_ONLY_DIS_VARS FALSE /**< should only discrete variables be compensated? */
71
72/*
73 * Data structures
74 */
75
76/** control parameters */
77struct SCIP_PresolData
78{
79 SCIP_Bool componlydisvars; /**< flag indicating if only discrete variables should be compensated */
80};
81
82/** type of fixing direction */
84{
85 FIXATLB = -1, /**< fix variable at lower bound */
86 NOFIX = 0, /**< do not fix variable */
87 FIXATUB = 1 /**< fix variable at upper bound */
88};
90
91/** type of variable lock compensation */
98
99/*
100 * Local methods
101 */
102
103/** try to compensate a variable with a single opposite lock
104 by using singleton continuous variables */
105static
107 SCIP* scip, /**< SCIP main data structure */
108 SCIP_MATRIX* matrix, /**< matrix containing the constraints */
109 int col, /**< variable fixing candidate */
110 int row, /**< row index with opposite lock */
111 SCIP_Real val, /**< value of fixing candidate in the opposite lock constraint */
112 SCIP_Bool twosides, /**< flag indicating that two sides are present */
113 LOCKCOMPENSATION compensation, /**< type of lock compensation */
114 FIXINGDIRECTION* varstofix, /**< array holding fixing information */
115 int* nfixings /**< number of possible fixings */
116 )
117{
118 SCIP_Real* valpnt;
119 int* rowpnt;
120 int* rowend;
121 SCIP_VAR* var;
122 int colidx;
123 SCIP_Real coef;
124 SCIP_Real lhs;
125 SCIP_Real delta;
126 SCIP_Bool trytofix;
127 SCIP_Real lb;
128 SCIP_Real ub;
129 SCIP_Bool deltaisinf;
130 SCIP_Real ratio;
131 SCIP_Bool multrowbyminusone;
132 SCIP_Bool singleton;
133 SCIP_Real offset;
134
135 assert(scip != NULL);
136 assert(matrix != NULL);
137 assert(0 <= col && col < SCIPmatrixGetNColumns(matrix));
138 assert(0 <= row && row < SCIPmatrixGetNRows(matrix));
139 assert(compensation == COMPENSATE_DOWNLOCK || compensation == COMPENSATE_UPLOCK);
140 assert(varstofix != NULL);
141 assert(nfixings != NULL);
142
143 /* the variable for compensation should not be a compensation variable itself */
144 assert(SCIPmatrixGetColNNonzs(matrix, col) != 1 || SCIPvarIsIntegral(SCIPmatrixGetVar(matrix, col)));
145
146 /* try lock compensation only if minimum one singleton continuous variable is present */
147 singleton = FALSE;
148 rowpnt = SCIPmatrixGetRowIdxPtr(matrix, row);
149 rowend = rowpnt + SCIPmatrixGetRowNNonzs(matrix, row);
150 for( ; rowpnt < rowend; rowpnt++ )
151 {
152 var = SCIPmatrixGetVar(matrix, *rowpnt);
153
154 if( SCIPmatrixGetColNNonzs(matrix, *rowpnt) == 1 && !SCIPvarIsIntegral(var)
157 {
158 /* minimal one valid compensation variable is present in this row */
159 singleton = TRUE;
160 break;
161 }
162 }
163
164 /* return if no compensation variable is available */
165 if( !singleton )
166 return SCIP_OKAY;
167
168 /* we perform the following transformations afterwards:
169 *
170 * lhs <= a1 x1 + a2 x2 + ... an xn <= rhs
171 * with a1, a2, ..., an >= 0.
172 *
173 * for the downlock case we multiply the constraint in thought by (-1)
174 * if the corresponding coefficient is negative.
175 *
176 * we attribute the uplock case to the downlock case by multiplying
177 * in thought the corresponding column by (-1).
178 */
179 multrowbyminusone = FALSE;
180 if( compensation == COMPENSATE_DOWNLOCK )
181 {
182 if( SCIPisLT(scip,val,0.0) )
183 multrowbyminusone = TRUE;
184 }
185 else
186 {
187 assert(compensation == COMPENSATE_UPLOCK);
188
189 /* in the uplock case we multiply the column in thought by (-1) and
190 * thus we need to multiply the constraint by (-1) to get a positive coefficient
191 */
192 if( SCIPisGT(scip,val,0.0) )
193 multrowbyminusone = TRUE;
194 }
195
196 /* we need the objective coefficient and constraint coefficient ratio
197 * to later preserve optimality.
198 * further we need to consider multiplications of the constraint by (-1).
199 * for ranged rows and equalities we switch to the rhs.
200 */
201 lhs = SCIPmatrixGetRowLhs(matrix, row);
202 ratio = SCIPvarGetObj( SCIPmatrixGetVar(matrix,col) ) / val;
203 if( multrowbyminusone )
204 {
205 if( twosides )
206 lhs = -SCIPmatrixGetRowRhs(matrix, row);
207 else
208 lhs = -lhs;
209
210 ratio = -ratio;
211 }
212
213 offset = 0.0;
214 trytofix = TRUE;
215 delta = 0;
216 deltaisinf = FALSE;
217
218 rowpnt = SCIPmatrixGetRowIdxPtr(matrix, row);
219 rowend = rowpnt + SCIPmatrixGetRowNNonzs(matrix, row);
220 valpnt = SCIPmatrixGetRowValPtr(matrix, row);
221
222 for( ; rowpnt < rowend; rowpnt++, valpnt++ )
223 {
224 colidx = *rowpnt;
225 coef = *valpnt;
226 var = SCIPmatrixGetVar(matrix, colidx);
229
230 if( colidx == col )
231 {
232 /* this is the variable which we want to compensate */
233
234 if( compensation == COMPENSATE_DOWNLOCK )
235 {
236 if( SCIPisInfinity(scip, -lb) )
237 {
238 trytofix = FALSE;
239 break;
240 }
241 else
242 {
243 if( multrowbyminusone )
244 offset += (-coef) * lb;
245 else
246 offset += coef * lb;
247 }
248 }
249 else
250 {
251 if( SCIPisInfinity(scip, ub) )
252 {
253 trytofix = FALSE;
254 break;
255 }
256 else
257 {
258 /* for the uplock case we have opposed sign for the coefficient as
259 * in the downlock case.
260 * the multiplication of the column results in swapping the negative bounds.
261 */
262 if( multrowbyminusone )
263 offset += coef * (-ub);
264 else
265 offset += (-coef) * (-ub);
266 }
267 }
268 }
269 else if( SCIPmatrixGetColNNonzs(matrix, colidx) == 1 && !SCIPvarIsIntegral(var)
272 {
273 /* this is singleton continuous variable and
274 * thus a valid compensation candidate
275 */
276
277 if( SCIPisLT(scip,coef,0.0) )
278 {
279 /* coef < 0 */
280
281 if( multrowbyminusone )
282 {
283 if( SCIPisInfinity(scip, -lb) )
284 {
285 trytofix = FALSE;
286 break;
287 }
288
289 /* we have a negative coefficient and the row is multiplied by (-1)
290 * thus actually we have a positive coefficient
291 */
292 offset += (-coef) * lb;
293
294 /* only consider singleton continuous variables with a better or the same
295 * obj/coef ratio for preserving optimality
296 */
297 if( SCIPisLE(scip,SCIPvarGetObj(SCIPmatrixGetVar(matrix, colidx))/(-coef), ratio) )
298 {
299 if( SCIPisInfinity(scip, ub) )
300 {
301 deltaisinf = TRUE;
302 break;
303 }
304
305 /* calculate the contribution to the compensation value */
306 delta += (-coef) * (ub - lb);
307 }
308 }
309 else
310 {
311 if( SCIPisInfinity(scip, ub) )
312 {
313 trytofix = FALSE;
314 break;
315 }
316
317 /* we have a negative coefficient and hence need to multiply the column by (-1).
318 * this means the bounds swap and change the sign
319 */
320 offset += (-coef) * (-ub);
321
322 /* only consider singleton continuous variables with a better or the same
323 * obj/coef ratio for preserving optimality
324 */
325 if( SCIPisLE(scip,SCIPvarGetObj(SCIPmatrixGetVar(matrix, colidx))/coef, ratio) )
326 {
327 if( SCIPisInfinity(scip, -lb) )
328 {
329 deltaisinf = TRUE;
330 break;
331 }
332
333 /* calculate the contribution to the compensation value */
334 delta += (-coef) * (ub - lb);
335 }
336 }
337 }
338 else
339 {
340 /* coef >= 0 */
341
342 if( multrowbyminusone )
343 {
344 /* we have a positive or zero coefficient and the row is multiplied by (-1) */
345 if( SCIPisInfinity(scip, ub) )
346 {
347 trytofix = FALSE;
348 break;
349 }
350
351 /* we have a positive or zero coefficient and multiply in thought the constraint
352 * by (-1) thus we have actually a negative coefficient and multiply the column by (-1).
353 * therefore the sign of the coefficient does not change but the bounds swap and change
354 * the sign.
355 */
356 offset += coef * (-ub);
357
358 /* we have a positive or zero coefficient and multiply in thought the constraint
359 * by (-1) which delivers the ratio.
360 * a further multiplication of the column does not change anything.
361 */
362 if( SCIPisLE(scip,SCIPvarGetObj(SCIPmatrixGetVar(matrix, colidx))/(-coef), ratio) )
363 {
364 if( SCIPisInfinity(scip, -lb) )
365 {
366 deltaisinf = TRUE;
367 break;
368 }
369
370 /* calculate the contribution to the compensation value */
371 delta += coef * (ub - lb);
372 }
373 }
374 else
375 {
376 if( SCIPisInfinity(scip, -lb) )
377 {
378 trytofix = FALSE;
379 break;
380 }
381
382 /* we have positive coefficient and do not need to multiply anything by (-1) */
383 offset += coef * lb;
384
385 if( SCIPisLE(scip,SCIPvarGetObj(SCIPmatrixGetVar(matrix, colidx))/coef, ratio) )
386 {
387 if( SCIPisInfinity(scip, ub) )
388 {
389 deltaisinf = TRUE;
390 break;
391 }
392
393 /* calculate the contribution to the compensation value */
394 delta += coef * (ub - lb);
395 }
396 }
397 }
398 }
399 else
400 {
401 /* remaining variables */
402
403 /* the reasons for the following signs are the same as for the singleton
404 * continuous variables
405 */
406 if( SCIPisLT(scip,coef,0.0) )
407 {
408 if( multrowbyminusone )
409 {
410 if( SCIPisInfinity(scip, -lb) )
411 {
412 trytofix = FALSE;
413 break;
414 }
415
416 offset += (-coef) * lb;
417 }
418 else
419 {
420 if( SCIPisInfinity(scip, ub) )
421 {
422 trytofix = FALSE;
423 break;
424 }
425
426 offset += (-coef) * (-ub);
427 }
428 }
429 else
430 {
431 if( multrowbyminusone )
432 {
433 if( SCIPisInfinity(scip, ub) )
434 {
435 trytofix = FALSE;
436 break;
437 }
438
439 offset += coef * (-ub);
440 }
441 else
442 {
443 if( SCIPisInfinity(scip, -lb) )
444 {
445 trytofix = FALSE;
446 break;
447 }
448
449 offset += coef * lb;
450 }
451 }
452 }
453 }
454
455 /* avoid fixings to infinite values or fixings of already fixed variables */
456 if( trytofix && varstofix[col] == NOFIX)
457 {
458 /* feasibility is secured if the compensation value delta
459 * is large enough to compensate the value lhs-offset
460 */
461 if( deltaisinf || SCIPisLE(scip, lhs-offset, delta) )
462 {
463 if( compensation == COMPENSATE_UPLOCK )
464 {
466 {
467 varstofix[col] = FIXATUB;
468 (*nfixings)++;
469
470#ifdef SCIP_MORE_DEBUG
471 SCIPmatrixPrintRow(scip, matrix, row);
472 SCIPdebugMsg(scip, "%s, bds=[%.2f,%.2f], obj=%.2f, nnonzs=%d, type=%s, fix=ub, %.1f <= %.1f\n",
475 SCIPmatrixGetColNNonzs(matrix, col),
476 SCIPvarGetType(SCIPmatrixGetVar(matrix, col))==SCIP_VARTYPE_CONTINUOUS ? "con" : "dis",
477 lhs-offset, delta);
478#endif
479 }
480 }
481 else
482 {
484 {
485 varstofix[col] = FIXATLB;
486 (*nfixings)++;
487
488#ifdef SCIP_MORE_DEBUG
489 SCIPmatrixPrintRow(scip, matrix, row);
490 SCIPdebugMsg(scip, "%s, bds=[%.2f,%.2f], obj=%.2f, nnonzs=%d, type=%s, fix=lb, %.1f <= %.1f\n",
493 SCIPmatrixGetColNNonzs(matrix, col),
494 SCIPvarGetType(SCIPmatrixGetVar(matrix, col))==SCIP_VARTYPE_CONTINUOUS ? "con" : "dis",
495 lhs-offset, delta);
496#endif
497 }
498 }
499 }
500 }
501
502 return SCIP_OKAY;
503}
504
505/*
506 * Callback methods of presolver
507 */
508
509/** copy method for constraint handler plugins (called when SCIP copies plugins) */
510static
511SCIP_DECL_PRESOLCOPY(presolCopyDualcomp)
512{ /*lint --e{715}*/
513 assert(scip != NULL);
514 assert(presol != NULL);
515
517
518 /* call inclusion method of presolver */
520
521 return SCIP_OKAY;
522}
523
524/** execution method of presolver */
525static
526SCIP_DECL_PRESOLEXEC(presolExecDualcomp)
527{ /*lint --e{715}*/
528 SCIP_PRESOLDATA* presoldata;
529 SCIP_MATRIX* matrix;
530 SCIP_Bool initialized;
531 SCIP_Bool complete;
532 SCIP_Bool infeasible;
533
534 assert(result != NULL);
536
538 return SCIP_OKAY;
539
541 return SCIP_OKAY;
542
543 /* don't run if no compensation variables are present */
544 if( SCIPgetNContVars(scip) == 0 )
545 return SCIP_OKAY;
546
548 return SCIP_OKAY;
549
551
552 presoldata = SCIPpresolGetData(presol);
553 assert(presoldata != NULL);
554
555 matrix = NULL;
556
557 SCIP_CALL( SCIPmatrixCreate(scip, &matrix, TRUE, &initialized, &complete, &infeasible,
558 naddconss, ndelconss, nchgcoefs, nchgbds, nfixedvars) );
559
560 /* if infeasibility was detected during matrix creation, return here */
561 if( infeasible )
562 {
563 if( initialized )
564 SCIPmatrixFree(scip, &matrix);
565
567 return SCIP_OKAY;
568 }
569
570 /* we only work on pure MIPs currently */
571 if( initialized && complete )
572 {
573 int ncols;
574 int i;
575 SCIP_Real* valpnt;
576 int* colpnt;
577 int* colend;
578 int row;
579 SCIP_VAR* var;
580 SCIP_Bool inspect;
581 SCIP_Real val;
582 FIXINGDIRECTION* varstofix;
583 int nfixings;
584 SCIP_Real lhs;
585 SCIP_Real rhs;
586 SCIP_Bool twosides;
587
588 ncols = SCIPmatrixGetNColumns(matrix);
589 nfixings = 0;
590
591 SCIP_CALL( SCIPallocBufferArray(scip, &varstofix, ncols) );
592 BMSclearMemoryArray(varstofix, ncols);
593
594 for(i = 0; i < ncols; i++)
595 {
596 var = SCIPmatrixGetVar(matrix, i);
597
598 /* exclude compensation variables itself for compensation */
599 if( !SCIPvarIsIntegral(var) && SCIPmatrixGetColNNonzs(matrix, i) == 1 )
600 continue;
601
602 /* if requested exclude continuous variables for compensation */
603 if( presoldata->componlydisvars && !SCIPvarIsIntegral(var) )
604 continue;
605
606 /* verifiy that this variable has one uplock and that the uplocks are consistent */
608 SCIPmatrixGetColNUplocks(matrix, i) == 1 &&
610 {
611 row = -1;
612 val = 0.0;
613 inspect = FALSE;
614 twosides = FALSE;
615 colpnt = SCIPmatrixGetColIdxPtr(matrix, i);
616 colend = colpnt + SCIPmatrixGetColNNonzs(matrix, i);
617 valpnt = SCIPmatrixGetColValPtr(matrix, i);
618
619 /* search row which causes the uplock */
620 for( ; (colpnt < colend); colpnt++, valpnt++ )
621 {
622 row = *colpnt;
623 val = *valpnt;
624 lhs = SCIPmatrixGetRowLhs(matrix, row);
625 rhs = SCIPmatrixGetRowRhs(matrix, row);
626
627 if( SCIPisEQ(scip, lhs, rhs) )
628 {
629 /* equation */
630 inspect = TRUE;
631 twosides = TRUE;
632 break;
633 }
634 else if( SCIPmatrixIsRowRhsInfinity(matrix, row) )
635 {
636 /* >= */
637 if( SCIPisLT(scip, val, 0.0) )
638 {
639 inspect = TRUE;
640 break;
641 }
642 }
643 else if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) )
644 {
645 /* ranged row */
646 inspect = TRUE;
647 twosides = TRUE;
648 break;
649 }
650 }
651
652 assert(inspect);
653
654 if( inspect ) /*lint !e774*/
655 {
656 assert(row >= 0);
657 assert(!SCIPisZero(scip, val));
658
659 /* try to fix variable i at the upper bound */
660 SCIP_CALL( compensateVarLock(scip, matrix, i, row, val,
661 twosides, COMPENSATE_UPLOCK, varstofix, &nfixings) );
662 }
663 }
664 /* verifiy that this variable has one downlock and that the downlocks are consistent */
666 SCIPmatrixGetColNDownlocks(matrix, i) == 1 &&
668 {
669 row = -1;
670 val = 0.0;
671 inspect = FALSE;
672 twosides = FALSE;
673 colpnt = SCIPmatrixGetColIdxPtr(matrix, i);
674 colend = colpnt + SCIPmatrixGetColNNonzs(matrix, i);
675 valpnt = SCIPmatrixGetColValPtr(matrix, i);
676
677 /* search row which causes the downlock */
678 for( ; (colpnt < colend); colpnt++, valpnt++ )
679 {
680 row = *colpnt;
681 val = *valpnt;
682 lhs = SCIPmatrixGetRowLhs(matrix, row);
683 rhs = SCIPmatrixGetRowRhs(matrix, row);
684
685 if( SCIPisEQ(scip, lhs, rhs) )
686 {
687 /* equation */
688 inspect = TRUE;
689 twosides = TRUE;
690 break;
691 }
692 else if( SCIPmatrixIsRowRhsInfinity(matrix, row) )
693 {
694 /* >= */
695 if( SCIPisGT(scip, val, 0.0) )
696 {
697 inspect = TRUE;
698 break;
699 }
700 }
701 else if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) )
702 {
703 /* ranged row */
704 inspect = TRUE;
705 twosides = TRUE;
706 break;
707 }
708 }
709
710 assert(inspect);
711
712 if( inspect ) /*lint !e774*/
713 {
714 assert(row >= 0);
715 assert(!SCIPisZero(scip, val));
716
717 /* try to fix variable i at the lower bound */
718 SCIP_CALL( compensateVarLock(scip, matrix, i, row, val,
719 twosides, COMPENSATE_DOWNLOCK, varstofix, &nfixings) );
720 }
721 }
722 }
723
724 if( nfixings > 0 )
725 {
726 int v;
727 int oldnfixedvars;
728 int numupperboundfixings;
729 int numlowerboundfixings;
730 int numcontinuousfixings;
731 int numdiscretefixings;
732
733 oldnfixedvars = *nfixedvars;
734 numupperboundfixings = 0;
735 numlowerboundfixings = 0;
736 numcontinuousfixings = 0;
737 numdiscretefixings = 0;
738
739 /* look for fixable variables */
740 for( v = ncols - 1; v >= 0; --v )
741 {
742 SCIP_Bool fixed;
743
744 var = SCIPmatrixGetVar(matrix, v);
745
746 if( varstofix[v] == FIXATLB )
747 {
748 SCIP_Real lb;
749
751
752 /* avoid fixings to infinite values */
753 assert(!SCIPisInfinity(scip, -lb));
754
755 SCIPdebugMsg(scip, "Fix variable %s at lower bound %.15g\n", SCIPvarGetName(var), lb);
756
757 /* fix at lower bound */
758 SCIP_CALL( SCIPfixVar(scip, var, lb, &infeasible, &fixed) );
759 if( infeasible )
760 {
761 SCIPdebugMsg(scip, " -> infeasible fixing\n");
763
764 break;
765 }
766 assert(fixed);
767 (*nfixedvars)++;
768 numlowerboundfixings++;
769
770 if( !SCIPvarIsIntegral(var) )
771 numcontinuousfixings++;
772 else
773 numdiscretefixings++;
774 }
775 else if( varstofix[v] == FIXATUB )
776 {
777 SCIP_Real ub;
778
780
781 /* avoid fixings to infinite values */
783
784 SCIPdebugMsg(scip, "Fix variable %s at upper bound %.15g\n", SCIPvarGetName(var), ub);
785
786 /* fix at upper bound */
787 SCIP_CALL( SCIPfixVar(scip, var, ub, &infeasible, &fixed) );
788 if( infeasible )
789 {
790 SCIPdebugMsg(scip, " -> infeasible fixing\n");
792
793 break;
794 }
795 assert(fixed);
796 (*nfixedvars)++;
797 numupperboundfixings++;
798
799 if( !SCIPvarIsIntegral(var) )
800 numcontinuousfixings++;
801 else
802 numdiscretefixings++;
803 }
804 }
805
806 if( *result != SCIP_CUTOFF && *nfixedvars > oldnfixedvars )
808
809 SCIPdebugMsg(scip, "### lbfixes: %d, ubfixes: %d, con: %d, dis: %d\n",
810 numlowerboundfixings, numupperboundfixings,
811 numcontinuousfixings, numdiscretefixings);
812 }
813
814 SCIPfreeBufferArray(scip, &varstofix);
815 }
816
817 SCIPmatrixFree(scip, &matrix);
818
819 return SCIP_OKAY;
820}
821
822/*
823 * presolver specific interface methods
824 */
825
826/** destructor of presolver to free user data (called when SCIP is exiting) */
827static
828SCIP_DECL_PRESOLFREE(presolFreeDualcomp)
829{ /*lint --e{715}*/
830 SCIP_PRESOLDATA* presoldata;
831
832 /* free presolver data */
833 presoldata = SCIPpresolGetData(presol);
834 assert(presoldata != NULL);
835
836 SCIPfreeBlockMemory(scip, &presoldata);
837 SCIPpresolSetData(presol, NULL);
838
839 return SCIP_OKAY;
840}
841
842/** creates the dualcomp presolver and includes it in SCIP */
844 SCIP* scip /**< SCIP data structure */
845 )
846{
847 SCIP_PRESOLDATA* presoldata;
848 SCIP_PRESOL* presol;
849
850 /* create dualcomp presolver data */
851 SCIP_CALL( SCIPallocBlockMemory(scip, &presoldata) );
852
853 /* include presolver */
855 PRESOL_TIMING, presolExecDualcomp, presoldata) );
856 SCIP_CALL( SCIPsetPresolCopy(scip, presol, presolCopyDualcomp) );
857 SCIP_CALL( SCIPsetPresolFree(scip, presol, presolFreeDualcomp) );
858
860 "presolving/dualcomp/componlydisvars",
861 "should only discrete variables be compensated?",
862 &presoldata->componlydisvars, FALSE, DEFAULT_COMP_ONLY_DIS_VARS, NULL, NULL) );
863
864 return SCIP_OKAY;
865}
#define NULL
Definition def.h:257
#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_CALL(x)
Definition def.h:364
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_STAGE SCIPgetStage(SCIP *scip)
int SCIPgetNContVars(SCIP *scip)
Definition scip_prob.c:2569
#define SCIPdebugMsg
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 SCIPincludePresolDualcomp(SCIP *scip)
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_Bool SCIPisNLPEnabled(SCIP *scip)
Definition scip_nlp.c:74
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol,)
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
Definition presol.c:538
SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
Definition presol.c:528
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol,)
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
Definition presol.c:625
int SCIPgetNActivePricers(SCIP *scip)
SCIP_Bool SCIPinProbing(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:4380
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23485
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23522
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition scip_var.c:10318
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:4322
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition scip_var.c:10984
return SCIP_OKAY
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_VAR * var
int * SCIPmatrixGetColIdxPtr(SCIP_MATRIX *matrix, int col)
Definition matrix.c:1873
int SCIPmatrixGetRowNNonzs(SCIP_MATRIX *matrix, int row)
Definition matrix.c:2013
int SCIPmatrixGetColNDownlocks(SCIP_MATRIX *matrix, int col)
Definition matrix.c:1941
int SCIPmatrixGetColNNonzs(SCIP_MATRIX *matrix, int col)
Definition matrix.c:1885
SCIP_Bool SCIPmatrixIsRowRhsInfinity(SCIP_MATRIX *matrix, int row)
Definition matrix.c:2095
int SCIPmatrixGetColNUplocks(SCIP_MATRIX *matrix, int col)
Definition matrix.c:1929
SCIP_Real SCIPmatrixGetRowLhs(SCIP_MATRIX *matrix, int row)
Definition matrix.c:2047
SCIP_Real * SCIPmatrixGetRowValPtr(SCIP_MATRIX *matrix, int row)
Definition matrix.c:1977
SCIP_Real SCIPmatrixGetRowRhs(SCIP_MATRIX *matrix, int row)
Definition matrix.c:2059
SCIP_Real * SCIPmatrixGetColValPtr(SCIP_MATRIX *matrix, int col)
Definition matrix.c:1861
SCIP_RETCODE SCIPmatrixCreate(SCIP *scip, SCIP_MATRIX **matrixptr, SCIP_Bool onlyifcomplete, SCIP_Bool *initialized, SCIP_Bool *complete, SCIP_Bool *infeasible, int *naddconss, int *ndelconss, int *nchgcoefs, int *nchgbds, int *nfixedvars)
Definition matrix.c:703
int SCIPmatrixGetNColumns(SCIP_MATRIX *matrix)
Definition matrix.c:1897
void SCIPmatrixFree(SCIP *scip, SCIP_MATRIX **matrix)
Definition matrix.c:1348
SCIP_VAR * SCIPmatrixGetVar(SCIP_MATRIX *matrix, int col)
Definition matrix.c:1953
int * SCIPmatrixGetRowIdxPtr(SCIP_MATRIX *matrix, int row)
Definition matrix.c:2001
void SCIPmatrixPrintRow(SCIP *scip, SCIP_MATRIX *matrix, int row)
Definition matrix.c:1425
int SCIPmatrixGetNRows(SCIP_MATRIX *matrix)
Definition matrix.c:2037
memory allocation routines
#define BMSclearMemoryArray(ptr, num)
Definition memory.h:130
#define PRESOL_NAME
#define PRESOL_PRIORITY
#define PRESOL_MAXROUNDS
#define PRESOL_TIMING
#define PRESOL_DESC
Fixingdirection
@ FIXATUB
@ FIXATLB
@ NOFIX
enum Fixingdirection FIXINGDIRECTION
#define DEFAULT_COMP_ONLY_DIS_VARS
enum Lockcompensation LOCKCOMPENSATION
Lockcompensation
@ COMPENSATE_UPLOCK
@ COMPENSATE_DOWNLOCK
static SCIP_RETCODE compensateVarLock(SCIP *scip, SCIP_MATRIX *matrix, int col, int row, SCIP_Real val, SCIP_Bool twosides, LOCKCOMPENSATION compensation, FIXINGDIRECTION *varstofix, int *nfixings)
dual compensation presolver
public methods for matrix
public methods for message output
public methods for presolvers
public methods for problem variables
general public methods
public methods for memory management
public methods for message handling
public methods for nonlinear relaxation
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for presolving plugins
public methods for variable pricer plugins
public methods for global and local (sub)problems
public methods for the probing mode
public methods for SCIP variables
struct SCIP_Matrix SCIP_MATRIX
Definition type_matrix.h:42
#define SCIP_DECL_PRESOLCOPY(x)
Definition type_presol.h:60
struct SCIP_PresolData SCIP_PRESOLDATA
Definition type_presol.h:51
#define SCIP_DECL_PRESOLFREE(x)
Definition type_presol.h:68
struct SCIP_Presol SCIP_PRESOL
Definition type_presol.h:50
#define SCIP_DECL_PRESOLEXEC(x)
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_SUCCESS
Definition type_result.h:58
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_PRESOLVING
Definition type_set.h:49
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARTYPE_CONTINUOUS
Definition type_var.h:71
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:141