Scippy

SCIP

Solving Constraint Integer Programs

primal.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-2024 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 primal.c
26 * @ingroup OTHER_CFILES
27 * @brief methods for collecting primal CIP solutions and primal informations
28 * @author Tobias Achterberg
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
33#include <assert.h>
34
35#include "scip/def.h"
36#include "scip/set.h"
37#include "scip/stat.h"
38#include "scip/visual.h"
39#include "scip/event.h"
40#include "scip/lp.h"
41#include "scip/var.h"
42#include "scip/prob.h"
43#include "scip/sol.h"
44#include "scip/primal.h"
45#include "scip/tree.h"
46#include "scip/reopt.h"
47#include "scip/disp.h"
48#include "scip/struct_event.h"
49#include "scip/pub_message.h"
50#include "scip/pub_var.h"
52
53
54/*
55 * memory growing methods for dynamically allocated arrays
56 */
57
58/** ensures, that sols array can store at least num entries */
59static
61 SCIP_PRIMAL* primal, /**< primal data */
62 SCIP_SET* set, /**< global SCIP settings */
63 int num /**< minimum number of entries to store */
64 )
65{
66 assert(primal->nsols <= primal->solssize);
67
68 if( num > primal->solssize )
69 {
70 int newsize;
71
72 newsize = SCIPsetCalcMemGrowSize(set, num);
73 SCIP_ALLOC( BMSreallocMemoryArray(&primal->sols, newsize) );
74 primal->solssize = newsize;
75 }
76 assert(num <= primal->solssize);
77
78 return SCIP_OKAY;
79}
80
81/** ensures, that partialsols array can store at least num entries */
82static
84 SCIP_PRIMAL* primal, /**< primal data */
85 SCIP_SET* set, /**< global SCIP settings */
86 int num /**< minimum number of entries to store */
87 )
88{
89 assert(primal->npartialsols <= primal->partialsolssize);
90
91 if( num > primal->partialsolssize )
92 {
93 int newsize;
94
95 newsize = SCIPsetCalcMemGrowSize(set, num);
96 newsize = MIN(newsize, set->limit_maxorigsol);
97
98 SCIP_ALLOC( BMSreallocMemoryArray(&primal->partialsols, newsize) );
99 primal->partialsolssize = newsize;
100 }
101 assert(num <= primal->partialsolssize);
102
103 return SCIP_OKAY;
104}
105
106/** ensures, that existingsols array can store at least num entries */
107static
109 SCIP_PRIMAL* primal, /**< primal data */
110 SCIP_SET* set, /**< global SCIP settings */
111 int num /**< minimum number of entries to store */
112 )
113{
114 assert(primal->nexistingsols <= primal->existingsolssize);
115
116 if( num > primal->existingsolssize )
117 {
118 int newsize;
119
120 newsize = SCIPsetCalcMemGrowSize(set, num);
121 SCIP_ALLOC( BMSreallocMemoryArray(&primal->existingsols, newsize) );
122 primal->existingsolssize = newsize;
123 }
124 assert(num <= primal->existingsolssize);
125
126 return SCIP_OKAY;
127}
128
129/** creates primal data */
131 SCIP_PRIMAL** primal /**< pointer to primal data */
132 )
133{
134 assert(primal != NULL);
135
136 SCIP_ALLOC( BMSallocMemory(primal) );
137 (*primal)->sols = NULL;
138 (*primal)->partialsols = NULL;
139 (*primal)->existingsols = NULL;
140 (*primal)->currentsol = NULL;
141 (*primal)->primalray = NULL;
142 (*primal)->solssize = 0;
143 (*primal)->partialsolssize = 0;
144 (*primal)->nsols = 0;
145 (*primal)->npartialsols = 0;
146 (*primal)->existingsolssize = 0;
147 (*primal)->nexistingsols = 0;
148 (*primal)->nsolsfound = 0;
149 (*primal)->nlimsolsfound = 0;
150 (*primal)->nbestsolsfound = 0;
151 (*primal)->nlimbestsolsfound = 0;
152 (*primal)->upperbound = SCIP_INVALID;
153 (*primal)->cutoffbound = SCIP_INVALID;
154 (*primal)->updateviolations = TRUE;
155
156 return SCIP_OKAY;
157}
158
159/** frees primal data */
161 SCIP_PRIMAL** primal, /**< pointer to primal data */
162 BMS_BLKMEM* blkmem /**< block memory */
163 )
164{
165 int s;
166
167 assert(primal != NULL);
168 assert(*primal != NULL);
169
170 /* free temporary solution for storing current solution */
171 if( (*primal)->currentsol != NULL )
172 {
173 SCIP_CALL( SCIPsolFree(&(*primal)->currentsol, blkmem, *primal) );
174 }
175
176 /* free solution for storing primal ray */
177 if( (*primal)->primalray != NULL )
178 {
179 SCIP_CALL( SCIPsolFree(&(*primal)->primalray, blkmem, *primal) );
180 }
181
182 /* free feasible primal CIP solutions */
183 for( s = 0; s < (*primal)->nsols; ++s )
184 {
185 SCIP_CALL( SCIPsolFree(&(*primal)->sols[s], blkmem, *primal) );
186 }
187 /* free partial CIP solutions */
188 for( s = 0; s < (*primal)->npartialsols; ++s )
189 {
190 SCIP_CALL( SCIPsolFree(&(*primal)->partialsols[s], blkmem, *primal) );
191 }
192 assert((*primal)->nexistingsols == 0);
193
194 BMSfreeMemoryArrayNull(&(*primal)->sols);
195 BMSfreeMemoryArrayNull(&(*primal)->partialsols);
196 BMSfreeMemoryArrayNull(&(*primal)->existingsols);
197 BMSfreeMemory(primal);
198
199 return SCIP_OKAY;
200}
201
202/** clears primal data */
204 SCIP_PRIMAL** primal, /**< pointer to primal data */
205 BMS_BLKMEM* blkmem /**< block memory */
206 )
207{
208 int s;
209
210 assert(primal != NULL);
211 assert(*primal != NULL);
212
213 /* free temporary solution for storing current solution */
214 if( (*primal)->currentsol != NULL )
215 {
216 SCIP_CALL( SCIPsolFree(&(*primal)->currentsol, blkmem, *primal) );
217 }
218
219 /* free solution for storing primal ray */
220 if( (*primal)->primalray != NULL )
221 {
222 SCIP_CALL( SCIPsolFree(&(*primal)->primalray, blkmem, *primal) );
223 }
224
225 /* free feasible primal CIP solutions */
226 for( s = 0; s < (*primal)->nsols; ++s )
227 {
228 SCIP_CALL( SCIPsolFree(&(*primal)->sols[s], blkmem, *primal) );
229 }
230
231 (*primal)->currentsol = NULL;
232 (*primal)->primalray = NULL;
233 (*primal)->nsols = 0;
234 (*primal)->nsolsfound = 0;
235 (*primal)->nlimsolsfound = 0;
236 (*primal)->nbestsolsfound = 0;
237 (*primal)->nlimbestsolsfound = 0;
238 (*primal)->upperbound = SCIP_INVALID;
239 (*primal)->cutoffbound = SCIP_INVALID;
240 (*primal)->updateviolations = TRUE;
241
242 return SCIP_OKAY;
243}
244
245/** sorts primal solutions by objective value */
246static
248 SCIP_PRIMAL* primal, /**< primal data */
249 SCIP_SET* set, /**< global SCIP settings */
250 SCIP_PROB* origprob, /**< original problem */
251 SCIP_PROB* transprob /**< transformed problem */
252 )
253{
254 int i;
255
256 for( i = 1; i < primal->nsols; ++i )
257 {
258 SCIP_SOL* sol;
259 SCIP_Real objval;
260 int j;
261
262 sol = primal->sols[i];
263 objval = SCIPsolGetObj(sol, set, transprob, origprob);
264 for( j = i; j > 0 && objval < SCIPsolGetObj(primal->sols[j-1], set, transprob, origprob); --j )
265 primal->sols[j] = primal->sols[j-1];
266 primal->sols[j] = sol;
267 }
268
269 return;
270}
271
272/** sets the cutoff bound in primal data and in LP solver */
273static
275 SCIP_PRIMAL* primal, /**< primal data */
276 BMS_BLKMEM* blkmem, /**< block memory */
277 SCIP_SET* set, /**< global SCIP settings */
278 SCIP_STAT* stat, /**< problem statistics data */
279 SCIP_PROB* prob, /**< problem data */
280 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
281 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
282 SCIP_TREE* tree, /**< branch and bound tree */
283 SCIP_REOPT* reopt, /**< reoptimization data structure */
284 SCIP_LP* lp, /**< current LP data */
285 SCIP_Real cutoffbound /**< new cutoff bound */
286 )
287{
288 assert(primal != NULL);
289 assert(cutoffbound <= SCIPsetInfinity(set));
290 assert(primal->upperbound == SCIP_INVALID || SCIPsetIsLE(set, cutoffbound, primal->upperbound)); /*lint !e777*/
291 assert(!SCIPtreeInRepropagation(tree));
292
293 SCIPsetDebugMsg(set, "changing cutoff bound from %g to %g\n", primal->cutoffbound, cutoffbound);
294
295 primal->cutoffbound = MIN(cutoffbound, primal->upperbound); /* get rid of numerical issues */
296
297 /* set cut off value in LP solver */
298 SCIP_CALL( SCIPlpSetCutoffbound(lp, set, prob, primal->cutoffbound) );
299
300 /* cut off leaves of the tree */
301 SCIP_CALL( SCIPtreeCutoff(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, primal->cutoffbound) );
302
303 return SCIP_OKAY;
304}
305
306/** sets the cutoff bound in primal data and in LP solver */
308 SCIP_PRIMAL* primal, /**< primal data */
309 BMS_BLKMEM* blkmem, /**< block memory */
310 SCIP_SET* set, /**< global SCIP settings */
311 SCIP_STAT* stat, /**< problem statistics data */
312 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
313 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
314 SCIP_PROB* transprob, /**< transformed problem data */
315 SCIP_PROB* origprob, /**< original problem data */
316 SCIP_TREE* tree, /**< branch and bound tree */
317 SCIP_REOPT* reopt, /**< reoptimization data structure */
318 SCIP_LP* lp, /**< current LP data */
319 SCIP_Real cutoffbound, /**< new cutoff bound */
320 SCIP_Bool useforobjlimit /**< should the cutoff bound be used to update the objective limit, if
321 * better? */
322 )
323{
324 assert(primal != NULL);
325 assert(cutoffbound <= SCIPsetInfinity(set));
326 assert(cutoffbound <= primal->upperbound);
327 assert(transprob != NULL);
328 assert(origprob != NULL);
329
330 if( cutoffbound < primal->cutoffbound )
331 {
332 if( useforobjlimit )
333 {
334 SCIP_Real objval;
335
336 objval = SCIPprobExternObjval(transprob, origprob, set, cutoffbound);
337
338 if( objval < SCIPprobGetObjlim(origprob, set) )
339 {
340 SCIPsetDebugMsg(set, "changing cutoff bound from %g to %g changes objective limit from %g to %g\n",
341 primal->cutoffbound, cutoffbound, SCIPprobGetObjlim(origprob, set), objval);
342 SCIPprobSetObjlim(origprob, objval);
343 SCIPprobSetObjlim(transprob, objval);
344 }
345 }
346
347 /* update cutoff bound */
348 SCIP_CALL( primalSetCutoffbound(primal, blkmem, set, stat, transprob, eventfilter, eventqueue, tree, reopt, lp, cutoffbound) );
349 }
350 else if( cutoffbound > primal->cutoffbound )
351 {
352 SCIPerrorMessage("invalid increase in cutoff bound\n");
353 return SCIP_INVALIDDATA;
354 }
355
356 return SCIP_OKAY;
357}
358
359/** sets upper bound in primal data and in LP solver */
360static
362 SCIP_PRIMAL* primal, /**< primal data */
363 BMS_BLKMEM* blkmem, /**< block memory */
364 SCIP_SET* set, /**< global SCIP settings */
365 SCIP_STAT* stat, /**< problem statistics data */
366 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
367 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
368 SCIP_PROB* prob, /**< transformed problem after presolve */
369 SCIP_TREE* tree, /**< branch and bound tree */
370 SCIP_REOPT* reopt, /**< reoptimization data structure */
371 SCIP_LP* lp, /**< current LP data */
372 SCIP_Real upperbound /**< new upper bound */
373 )
374{
375 SCIP_Real cutoffbound;
376
377 assert(primal != NULL);
378 assert(stat != NULL);
379 assert(upperbound <= SCIPsetInfinity(set));
380 assert(upperbound <= primal->upperbound || stat->nnodes == 0);
381
382 SCIPsetDebugMsg(set, "changing upper bound from %g to %g\n", primal->upperbound, upperbound);
383
384 primal->upperbound = upperbound;
385
386 /* if objective value is always integral, the cutoff bound can be reduced to nearly the previous integer number */
387 if( SCIPprobIsObjIntegral(prob) && !SCIPsetIsInfinity(set, upperbound) )
388 {
389 SCIP_Real delta;
390
392
393 cutoffbound = SCIPsetFeasCeil(set, upperbound) - (1.0 - delta);
394 cutoffbound = MIN(cutoffbound, upperbound); /* SCIPsetFeasCeil() can increase bound by almost 1.0 due to numerics
395 * and very large upperbound value */
396 }
397 else
398 cutoffbound = upperbound;
399
400 /* update cutoff bound */
401 if( cutoffbound < primal->cutoffbound )
402 {
403 SCIP_CALL( primalSetCutoffbound(primal, blkmem, set, stat, prob, eventfilter, eventqueue, tree, reopt, lp, cutoffbound) );
404 }
405
406 /* update upper bound in visualization output */
407 if( SCIPtreeGetCurrentDepth(tree) >= 0 )
408 {
409 SCIPvisualUpperbound(stat->visual, set, stat, primal->upperbound);
410 }
411
412 return SCIP_OKAY;
413}
414
415/** sets upper bound in primal data and in LP solver */
417 SCIP_PRIMAL* primal, /**< primal data */
418 BMS_BLKMEM* blkmem, /**< block memory */
419 SCIP_SET* set, /**< global SCIP settings */
420 SCIP_STAT* stat, /**< problem statistics data */
421 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
422 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
423 SCIP_PROB* prob, /**< transformed problem after presolve */
424 SCIP_TREE* tree, /**< branch and bound tree */
425 SCIP_REOPT* reopt, /**< reoptimization data structure */
426 SCIP_LP* lp, /**< current LP data */
427 SCIP_Real upperbound /**< new upper bound */
428 )
429{
430 assert(primal != NULL);
431 assert(upperbound <= SCIPsetInfinity(set));
432
433 if( upperbound < primal->upperbound )
434 {
435 /* update primal bound */
436 SCIP_CALL( primalSetUpperbound(primal, blkmem, set, stat, eventfilter, eventqueue, prob, tree, reopt, lp, upperbound) );
437 }
438 else if( upperbound > primal->upperbound )
439 {
440 SCIPerrorMessage("invalid increase in upper bound\n");
441 return SCIP_INVALIDDATA;
442 }
443
444 return SCIP_OKAY;
445}
446
447/** updates upper bound and cutoff bound in primal data after a tightening of the problem's objective limit */
449 SCIP_PRIMAL* primal, /**< primal data */
450 BMS_BLKMEM* blkmem, /**< block memory */
451 SCIP_SET* set, /**< global SCIP settings */
452 SCIP_STAT* stat, /**< problem statistics data */
453 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
454 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
455 SCIP_PROB* transprob, /**< transformed problem data */
456 SCIP_PROB* origprob, /**< original problem data */
457 SCIP_TREE* tree, /**< branch and bound tree */
458 SCIP_REOPT* reopt, /**< reoptimization data structure */
459 SCIP_LP* lp /**< current LP data */
460 )
461{
462 SCIP_Real objlimit;
463 SCIP_Real inf;
464
465 assert(primal != NULL);
466
467 /* get internal objective limit */
468 objlimit = SCIPprobInternObjval(transprob, origprob, set, SCIPprobGetObjlim(origprob, set));
469 inf = SCIPsetInfinity(set);
470 objlimit = MIN(objlimit, inf);
471
472 /* update the cutoff bound */
473 if( objlimit < primal->cutoffbound )
474 {
475 SCIP_CALL( primalSetCutoffbound(primal, blkmem, set, stat, transprob, eventfilter, eventqueue, tree, reopt, lp, objlimit) );
476 }
477
478 /* set new upper bound (and decrease cutoff bound, if objective value is always integral) */
479 if( objlimit < primal->upperbound )
480 {
481 SCIP_CALL( primalSetUpperbound(primal, blkmem, set, stat, eventfilter, eventqueue, transprob, tree, reopt, lp, objlimit) );
482 }
483
484 return SCIP_OKAY;
485}
486
487/** recalculates upper bound and cutoff bound in primal data after a change of the problem's objective offset */
489 SCIP_PRIMAL* primal, /**< primal data */
490 BMS_BLKMEM* blkmem, /**< block memory */
491 SCIP_SET* set, /**< global SCIP settings */
492 SCIP_STAT* stat, /**< problem statistics data */
493 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
494 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
495 SCIP_PROB* transprob, /**< tranformed problem data */
496 SCIP_PROB* origprob, /**< original problem data */
497 SCIP_TREE* tree, /**< branch and bound tree */
498 SCIP_REOPT* reopt, /**< reoptimization data structure */
499 SCIP_LP* lp /**< current LP data */
500 )
501{
502 SCIP_Real upperbound;
503 SCIP_Real inf;
504
505 assert(primal != NULL);
507
508 /* recalculate internal objective limit */
509 upperbound = SCIPprobInternObjval(transprob, origprob, set, SCIPprobGetObjlim(origprob, set));
510 inf = SCIPsetInfinity(set);
511 upperbound = MIN(upperbound, inf);
512
513 /* resort current primal solutions */
514 sortPrimalSols(primal, set, origprob, transprob);
515
516 /* compare objective limit to currently best solution */
517 if( primal->nsols > 0 )
518 {
519 SCIP_Real obj;
520
521 assert(SCIPsolIsOriginal(primal->sols[0]));
522 obj = SCIPsolGetObj(primal->sols[0], set, transprob, origprob);
523
524 upperbound = MIN(upperbound, obj);
525 }
526
527 /* invalidate old upper bound */
528 SCIP_CALL( primalSetUpperbound(primal, blkmem, set, stat, eventfilter, eventqueue, transprob, tree, reopt, lp, SCIPsetInfinity(set)) );
529
530 /* reset the cutoff bound
531 *
532 * @note we might need to relax the bound since in presolving the objective correction of an
533 * aggregation is still in progress
534 */
535 SCIP_CALL( primalSetCutoffbound(primal, blkmem, set, stat, transprob, eventfilter, eventqueue, tree, reopt, lp, upperbound) );
536
537 /* set new upper bound (and decrease cutoff bound, if objective value is always integral) */
538 SCIP_CALL( primalSetUpperbound(primal, blkmem, set, stat, eventfilter, eventqueue, transprob, tree, reopt, lp, upperbound) );
539
540 return SCIP_OKAY;
541}
542
543/** adds additional objective offset in original space to all existing solution (in original space) */
545 SCIP_PRIMAL* primal, /**< primal data */
546 SCIP_SET* set, /**< global SCIP settings */
547 SCIP_Real addval /**< additional objective offset in original space */
548 )
549{
550 int i;
551
552 assert(primal != NULL);
553 assert(set != NULL);
555
556#ifndef NDEBUG
557 assert(primal->nsols == 0 || SCIPsolGetOrigin(primal->sols[0]) == SCIP_SOLORIGIN_ORIGINAL);
558
559 /* check current order of primal solutions */
560 for( i = 1; i < primal->nsols; ++i )
561 {
562 assert(SCIPsolGetOrigin(primal->sols[i]) == SCIP_SOLORIGIN_ORIGINAL);
563 assert(SCIPsetIsLE(set, SCIPsolGetOrigObj(primal->sols[i-1]), SCIPsolGetOrigObj(primal->sols[i])));
564 }
565#endif
566
567 /* check current order of primal solutions */
568 for( i = 0; i < primal->nexistingsols; ++i )
569 {
570 assert(primal->existingsols[i] != NULL);
571 SCIPsolOrigAddObjval(primal->existingsols[i], addval);
572 }
573}
574
575/** returns whether the current primal bound is justified with a feasible primal solution; if not, the primal bound
576 * was set from the user as objective limit
577 */
579 SCIP_PRIMAL* primal, /**< primal data */
580 SCIP_SET* set, /**< global SCIP settings */
581 SCIP_PROB* transprob, /**< tranformed problem data */
582 SCIP_PROB* origprob /**< original problem data */
583 )
584{
585 assert(primal != NULL);
586
587 return (primal->nsols > 0 && SCIPsetIsEQ(set, primal->upperbound, SCIPsolGetObj(primal->sols[0], set, transprob, origprob)));
588}
589
590/** returns the primal ray thats proves unboundedness */
592 SCIP_PRIMAL* primal /**< primal data */
593 )
594{
595 assert(primal != NULL);
596
597 return primal->primalray;
598}
599
600/** update the primal ray thats proves unboundedness */
602 SCIP_PRIMAL* primal, /**< primal data */
603 SCIP_SET* set, /**< global SCIP settings */
604 SCIP_STAT* stat, /**< dynamic SCIP statistics */
605 SCIP_SOL* primalray, /**< the new primal ray */
606 BMS_BLKMEM* blkmem /**< block memory */
607 )
608{
609 assert(primal != NULL);
610 assert(set != NULL);
611 assert(stat != NULL);
612 assert(primalray != NULL);
613 assert(blkmem != NULL);
614
615 /* clear previously stored primal ray, if any */
616 if( primal->primalray != NULL )
617 {
618 SCIP_CALL( SCIPsolFree(&primal->primalray, blkmem, primal) );
619 }
620
621 assert(primal->primalray == NULL);
622
623 SCIP_CALL( SCIPsolCopy(&primal->primalray, blkmem, set, stat, primal, primalray) );
624
625 return SCIP_OKAY;
626}
627
628/** adds primal solution to solution storage at given position */
629static
631 SCIP_PRIMAL* primal, /**< primal data */
632 BMS_BLKMEM* blkmem, /**< block memory */
633 SCIP_SET* set, /**< global SCIP settings */
634 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
635 SCIP_STAT* stat, /**< problem statistics data */
636 SCIP_PROB* origprob, /**< original problem */
637 SCIP_PROB* transprob, /**< transformed problem after presolve */
638 SCIP_TREE* tree, /**< branch and bound tree */
639 SCIP_REOPT* reopt, /**< reoptimization data structure */
640 SCIP_LP* lp, /**< current LP data */
641 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
642 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
643 SCIP_SOL** solptr, /**< pointer to primal CIP solution */
644 int insertpos, /**< position in solution storage to add solution to */
645 SCIP_Bool replace /**< should the solution at insertpos be replaced by the new solution? */
646 )
647{
648 SCIP_SOL* sol;
649 /* cppcheck-suppress unassignedVariable */
650 SCIP_EVENT event;
651 SCIP_Real obj;
652 int pos;
653
654 assert(primal != NULL);
655 assert(set != NULL);
656 assert(solptr != NULL);
657 assert(stat != NULL);
658 assert(transprob != NULL);
659 assert(origprob != NULL);
660 assert(0 <= insertpos && insertpos < set->limit_maxsol);
661 assert(tree == NULL || !SCIPtreeInRepropagation(tree));
662
663 sol = *solptr;
664 assert(sol != NULL);
665
666 /* if the solution is added during presolving and it is not defined on original variables,
667 * presolving operations will destroy its validity, so we retransform it to the original space
668 */
669 if( set->stage < SCIP_STAGE_PRESOLVED && !SCIPsolIsOriginal(sol) )
670 {
671 SCIP_Bool hasinfval;
672
673 SCIP_CALL( SCIPsolUnlink(sol, set, transprob) );
674 SCIP_CALL( SCIPsolRetransform(sol, set, stat, origprob, transprob, &hasinfval) );
675 }
676
677 obj = SCIPsolGetObj(sol, set, transprob, origprob);
678
679 SCIPsetDebugMsg(set, "insert primal solution %p with obj %g at position %d (replace=%u):\n",
680 (void*)sol, obj, insertpos, replace);
681
682 /* make sure that the primal bound is at least the lower bound */
684 {
685 if( origprob->objsense == SCIP_OBJSENSE_MINIMIZE )
686 {
687 SCIPmessagePrintWarning(messagehdlr, "Dual bound %g is larger than the objective of the primal solution %g. The solution might not be optimal.\n",
688 SCIPprobExternObjval(transprob, origprob, set, SCIPgetLowerbound(set->scip)), SCIPprobExternObjval(transprob, origprob, set, obj));
689 }
690 else
691 {
692 SCIPmessagePrintWarning(messagehdlr, "Dual bound %g is smaller than the objective of the primal solution %g. The solution might not be optimal.\n",
693 SCIPprobExternObjval(transprob, origprob, set, SCIPgetLowerbound(set->scip)), SCIPprobExternObjval(transprob, origprob, set, obj));
694 }
695#ifdef WITH_DEBUG_SOLUTION
696 SCIPABORT();
697#endif
698 }
699
700 SCIPdebug( SCIP_CALL( SCIPsolPrint(sol, set, messagehdlr, stat, transprob, NULL, NULL, FALSE, FALSE) ) );
701
702#ifdef SCIP_DISABLED_CODE
703 /* this is not a valid debug check, but can be used to track down numerical troubles */
704#ifndef NDEBUG
705 /* check solution again completely
706 * it fail for different reasons:
707 * - in the LP solver, the feasibility tolerance is a relative measure against the row's norm
708 * - in SCIP, the feasibility tolerance is a relative measure against the row's rhs/lhs
709 * - the rhs/lhs of a row might drastically change during presolving when variables are fixed or (multi-)aggregated
710 */
711 if( !SCIPsolIsOriginal(sol) )
712 {
713 SCIP_Bool feasible;
714
715 SCIP_CALL( SCIPsolCheck(sol, set, messagehdlr, blkmem, stat, transprob, TRUE, TRUE, TRUE, TRUE, &feasible) );
716
717 if( !feasible )
718 {
719 SCIPerrorMessage("infeasible solution accepted:\n");
720 SCIP_CALL( SCIPsolPrint(sol, set, messagehdlr, stat, origprob, transprob, NULL, FALSE, FALSE) );
721 }
722 assert(feasible);
723 }
724#endif
725#endif
726
727 /* completely fill the solution's own value array to unlink it from the LP or pseudo solution */
728 SCIP_CALL( SCIPsolUnlink(sol, set, transprob) );
729
730 /* allocate memory for solution storage */
731 SCIP_CALL( ensureSolsSize(primal, set, set->limit_maxsol) );
732
733 /* if set->limit_maxsol was decreased in the meantime, free all solutions exceeding the limit */
734 for( pos = set->limit_maxsol; pos < primal->nsols; ++pos )
735 {
736 SCIP_CALL( SCIPsolFree(&primal->sols[pos], blkmem, primal) );
737 }
738 primal->nsols = MIN(primal->nsols, set->limit_maxsol);
739
740 /* if the solution should replace an existing one, free this solution, otherwise,
741 * free the last solution if the solution storage is full;
742 */
743 if( replace )
744 {
745 SCIP_CALL( SCIPsolTransform(primal->sols[insertpos], solptr, blkmem, set, primal) );
746 sol = primal->sols[insertpos];
747 }
748 else
749 {
750 if( primal->nsols == set->limit_maxsol )
751 {
752 SCIP_CALL( SCIPsolFree(&primal->sols[set->limit_maxsol - 1], blkmem, primal) );
753 }
754 else
755 {
756 primal->nsols = primal->nsols + 1;
757 assert(primal->nsols <= set->limit_maxsol);
758 }
759
760 /* move all solutions with worse objective value than the new solution */
761 for( pos = primal->nsols-1; pos > insertpos; --pos )
762 primal->sols[pos] = primal->sols[pos-1];
763
764 /* insert solution at correct position */
765 assert(0 <= insertpos && insertpos < primal->nsols);
766 primal->sols[insertpos] = sol;
767 primal->nsolsfound++;
768
769 /* check if solution is better than objective limit */
770 if( SCIPsetIsFeasLE(set, obj, SCIPprobInternObjval(transprob, origprob, set, SCIPprobGetObjlim(origprob, set))) )
771 primal->nlimsolsfound++;
772 }
773
774 /* if its the first primal solution, store the relevant statistics */
775 if( primal->nsolsfound == 1 )
776 {
777 SCIP_Real primalsolval;
778
781 stat->firstprimalheur = SCIPsolGetHeur(sol);
782 stat->firstprimaltime = SCIPsolGetTime(sol);
784
785 primalsolval = obj;
786 stat->firstprimalbound = SCIPprobExternObjval(transprob, origprob, set, primalsolval);
787
788 SCIPsetDebugMsg(set, "First Solution stored in problem specific statistics.\n");
789 SCIPsetDebugMsg(set, "-> %" SCIP_LONGINT_FORMAT " nodes, %d runs, %.2g time, %d depth, %.15g objective\n", stat->nnodesbeforefirst, stat->nrunsbeforefirst,
791 }
792
793 SCIPsetDebugMsg(set, " -> stored at position %d of %d solutions, found %" SCIP_LONGINT_FORMAT " solutions\n",
794 insertpos, primal->nsols, primal->nsolsfound);
795
796 /* update the solution value sums in variables */
797 if( !SCIPsolIsOriginal(sol) )
798 {
799 SCIPsolUpdateVarsum(sol, set, stat, transprob,
800 (SCIP_Real)(primal->nsols - insertpos)/(SCIP_Real)(2.0*primal->nsols - 1.0));
801 }
802
803 /* change color of node in visualization output */
804 SCIPvisualFoundSolution(stat->visual, set, stat, SCIPtreeGetCurrentNode(tree), insertpos == 0 ? TRUE : FALSE, sol);
805
806 /* check, if the global upper bound has to be updated */
807 if( obj < primal->cutoffbound && insertpos == 0 )
808 {
809 /* issue BESTSOLFOUND event */
811 SCIP_CALL( SCIPeventChgSol(&event, sol) );
812 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
813
814 /* update the upper bound */
815 SCIP_CALL( SCIPprimalSetUpperbound(primal, blkmem, set, stat, eventfilter, eventqueue, transprob, tree, reopt, lp, obj) );
816
817 primal->nbestsolsfound++;
818 stat->bestsolnode = stat->nnodes;
819 }
820 else
821 {
822 /* issue POORSOLFOUND event */
824 SCIP_CALL( SCIPeventChgSol(&event, sol) );
825 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
826 }
827
828
829 /* display node information line */
830 if( insertpos == 0 && !replace && set->stage >= SCIP_STAGE_SOLVING )
831 {
832 SCIP_CALL( SCIPdispPrintLine(set, messagehdlr, stat, NULL, TRUE, TRUE) );
833 }
834
835 /* if an original solution was added during solving, try to transfer it to the transformed space */
836 if( SCIPsolIsOriginal(sol) && SCIPsetGetStage(set) == SCIP_STAGE_SOLVING && set->misc_transorigsols )
837 {
838 SCIP_Bool added;
839
840 SCIP_CALL( SCIPprimalTransformSol(primal, sol, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt,
841 lp, eventqueue, eventfilter, NULL, NULL, 0, &added) );
842
843 SCIPsetDebugMsg(set, "original solution %p was successfully transferred to the transformed problem space\n",
844 (void*)sol);
845 } /*lint !e438*/
846
847 return SCIP_OKAY;
848}
849
850/** adds primal solution to solution storage at given position */
851static
853 SCIP_PRIMAL* primal, /**< primal data */
854 BMS_BLKMEM* blkmem, /**< block memory */
855 SCIP_SET* set, /**< global SCIP settings */
856 SCIP_PROB* prob, /**< original problem data */
857 SCIP_SOL* sol, /**< primal CIP solution */
858 int insertpos /**< position in solution storage to add solution to */
859 )
860{
861 int pos;
862
863 assert(primal != NULL);
864 assert(set != NULL);
865 assert(prob != NULL);
866 assert(sol != NULL);
867 assert(0 <= insertpos && insertpos < set->limit_maxorigsol);
868 assert(!set->reopt_enable);
869
870 SCIPsetDebugMsg(set, "insert primal solution candidate %p with obj %g at position %d:\n", (void*)sol, SCIPsolGetOrigObj(sol), insertpos);
871
872 /* allocate memory for solution storage */
873 SCIP_CALL( ensureSolsSize(primal, set, set->limit_maxorigsol) );
874
875 /* if the solution storage is full, free the last solution(s)
876 * more than one solution may be freed, if set->limit_maxorigsol was decreased in the meantime
877 */
878 for( pos = set->limit_maxorigsol-1; pos < primal->nsols; ++pos )
879 {
880 SCIP_CALL( SCIPsolFree(&primal->sols[pos], blkmem, primal) );
881 }
882
883 /* insert solution at correct position */
884 primal->nsols = MIN(primal->nsols+1, set->limit_maxorigsol);
885 for( pos = primal->nsols-1; pos > insertpos; --pos )
886 primal->sols[pos] = primal->sols[pos-1];
887
888 assert(0 <= insertpos && insertpos < primal->nsols);
889 primal->sols[insertpos] = sol;
890 primal->nsolsfound++;
891
892 /* check if solution is better than objective limit */
894 primal->nlimsolsfound++;
895
896 SCIPsetDebugMsg(set, " -> stored at position %d of %d solutions, found %" SCIP_LONGINT_FORMAT " solutions\n",
897 insertpos, primal->nsols, primal->nsolsfound);
898
899 return SCIP_OKAY;
900}
901
902/** adds primal solution to solution storage */
903static
905 SCIP_PRIMAL* primal, /**< primal data */
906 SCIP_SET* set, /**< global SCIP settings */
907 SCIP_PROB* prob, /**< original problem data */
908 SCIP_SOL* sol /**< primal CIP solution */
909 )
910{ /*lint --e{715}*/
911 assert(primal != NULL);
912 assert(set != NULL);
913 assert(prob != NULL);
914 assert(sol != NULL);
915
916 if( primal->npartialsols >= set->limit_maxorigsol )
917 {
918 SCIPerrorMessage("Cannot add partial solution to storage: limit reached.\n");
919 return SCIP_INVALIDCALL;
920 }
921
922 SCIPsetDebugMsg(set, "insert partial solution candidate %p:\n", (void*)sol);
923
924 /* allocate memory for solution storage */
925 SCIP_CALL( ensurePartialsolsSize(primal, set, primal->npartialsols+1) );
926
927 primal->partialsols[primal->npartialsols] = sol;
928 ++primal->npartialsols;
929
930 return SCIP_OKAY;
931}
932
933/** uses binary search to find position in solution storage */
934static
936 SCIP_PRIMAL* primal, /**< primal data */
937 SCIP_SET* set, /**< global SCIP settings */
938 SCIP_PROB* transprob, /**< tranformed problem data */
939 SCIP_PROB* origprob, /**< original problem data */
940 SCIP_SOL* sol /**< primal solution to search position for */
941 )
942{
943 SCIP_SOL** sols;
944 SCIP_Real obj;
945 SCIP_Real middleobj;
946 int left;
947 int right;
948 int middle;
949
950 assert(primal != NULL);
951
952 obj = SCIPsolGetObj(sol, set, transprob, origprob);
953 sols = primal->sols;
954
955 left = -1;
956 right = primal->nsols;
957 while( left < right-1 )
958 {
959 middle = (left+right)/2;
960 assert(left < middle && middle < right);
961 assert(0 <= middle && middle < primal->nsols);
962
963 middleobj = SCIPsolGetObj(sols[middle], set, transprob, origprob);
964
965 if( obj < middleobj )
966 right = middle;
967 else
968 left = middle;
969 }
970 assert(left == right-1);
971
972 /* prefer solutions that live in the transformed space */
973 if( !SCIPsolIsOriginal(sol) )
974 {
975 while( right > 0 && SCIPsolIsOriginal(sols[right-1])
976 && SCIPsetIsEQ(set, SCIPsolGetObj(sols[right-1], set, transprob, origprob), obj) )
977 --right;
978 }
979
980 return right;
981}
982
983/** uses binary search to find position in solution storage */
984static
986 SCIP_PRIMAL* primal, /**< primal data */
987 SCIP_SOL* sol /**< primal solution to search position for */
988 )
989{
990 SCIP_Real obj;
991 SCIP_Real middleobj;
992 int left;
993 int right;
994 int middle;
995
996 assert(primal != NULL);
997
998 obj = SCIPsolGetOrigObj(sol);
999
1000 left = -1;
1001 right = primal->nsols;
1002 while( left < right-1 )
1003 {
1004 middle = (left+right)/2;
1005 assert(left < middle && middle < right);
1006 assert(0 <= middle && middle < primal->nsols);
1007 middleobj = SCIPsolGetOrigObj(primal->sols[middle]);
1008 if( obj < middleobj )
1009 right = middle;
1010 else
1011 left = middle;
1012 }
1013 assert(left == right-1);
1014
1015 return right;
1016}
1017
1018/** returns whether the given primal solution is already existent in the solution storage */
1019static
1021 SCIP_PRIMAL* primal, /**< primal data */
1022 SCIP_SET* set, /**< global SCIP settings */
1023 SCIP_STAT* stat, /**< problem statistics data */
1024 SCIP_PROB* origprob, /**< original problem */
1025 SCIP_PROB* transprob, /**< transformed problem after presolve */
1026 SCIP_SOL* sol, /**< primal solution to search position for */
1027 int* insertpos, /**< pointer to insertion position returned by primalSearchSolPos(); the
1028 * position might be changed if an existing solution should be replaced */
1029 SCIP_Bool* replace /**< pointer to store whether the solution at insertpos should be replaced */
1030 )
1031{
1032 SCIP_Real obj;
1033 int i;
1034
1035 assert(primal != NULL);
1036 assert(insertpos != NULL);
1037 assert(replace != NULL);
1038 assert(0 <= (*insertpos) && (*insertpos) <= primal->nsols);
1039
1040 obj = SCIPsolGetObj(sol, set, transprob, origprob);
1041
1042 assert(primal->sols != NULL || primal->nsols == 0);
1043 assert(primal->sols != NULL || (*insertpos) == 0);
1044
1045 /* search in the better solutions */
1046 for( i = (*insertpos)-1; i >= 0; --i )
1047 {
1048 SCIP_Real solobj;
1049
1050 solobj = SCIPsolGetObj(primal->sols[i], set, transprob, origprob);
1051
1052 /* due to transferring the objective value of transformed solutions to the original space, small numerical errors might occur
1053 * which can lead to SCIPsetIsLE() failing in case of high absolute numbers
1054 */
1055 assert(SCIPsetIsLE(set, solobj, obj) || (REALABS(obj) > 1e+13 * SCIPsetEpsilon(set) && SCIPsetIsFeasLE(set, solobj, obj)));
1056
1057 if( SCIPsetIsLT(set, solobj, obj) )
1058 break;
1059
1060 if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, origprob, transprob) )
1061 {
1062 if( set->stage >= SCIP_STAGE_PRESOLVED && SCIPsolIsOriginal(primal->sols[i]) && !SCIPsolIsOriginal(sol) )
1063 {
1064 (*insertpos) = i;
1065 (*replace) = TRUE;
1066 }
1067 return TRUE;
1068 }
1069 }
1070
1071 /* search in the worse solutions */
1072 for( i = (*insertpos); i < primal->nsols; ++i )
1073 {
1074 SCIP_Real solobj;
1075
1076 solobj = SCIPsolGetObj(primal->sols[i], set, transprob, origprob);
1077
1078 /* due to transferring the objective value of transformed solutions to the original space, small numerical errors might occur
1079 * which can lead to SCIPsetIsLE() failing in case of high absolute numbers
1080 */
1081 assert( SCIPsetIsGE(set, solobj, obj) || (REALABS(obj) > 1e+13 * SCIPsetEpsilon(set) && SCIPsetIsFeasGE(set, solobj, obj)));
1082
1083 if( SCIPsetIsGT(set, solobj, obj) )
1084 break;
1085
1086 if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, origprob, transprob) )
1087 {
1088 if( set->stage >= SCIP_STAGE_PRESOLVED && SCIPsolIsOriginal(primal->sols[i]) && !SCIPsolIsOriginal(sol) )
1089 {
1090 (*insertpos) = i;
1091 (*replace) = TRUE;
1092 }
1093 return TRUE;
1094 }
1095 }
1096
1097 return FALSE;
1098}
1099
1100/** returns whether the given primal solution is already existent in the original solution candidate storage */
1101static
1103 SCIP_PRIMAL* primal, /**< primal data */
1104 SCIP_SET* set, /**< global SCIP settings */
1105 SCIP_STAT* stat, /**< problem statistics data */
1106 SCIP_PROB* prob, /**< original problem */
1107 SCIP_SOL* sol, /**< primal solution to search position for */
1108 int insertpos /**< insertion position returned by primalSearchOrigSolPos() */
1109 )
1110{
1111 SCIP_Real obj;
1112 int i;
1113
1114 assert(primal != NULL);
1115 assert(0 <= insertpos && insertpos <= primal->nsols);
1116
1117 obj = SCIPsolGetOrigObj(sol);
1118
1119 /* search in the better solutions */
1120 for( i = insertpos-1; i >= 0; --i )
1121 {
1122 SCIP_Real solobj;
1123
1124 solobj = SCIPsolGetOrigObj(primal->sols[i]);
1125 assert( SCIPsetIsLE(set, solobj, obj) );
1126
1127 if( SCIPsetIsLT(set, solobj, obj) )
1128 break;
1129
1130 if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, prob, NULL) )
1131 return TRUE;
1132 }
1133
1134 /* search in the worse solutions */
1135 for( i = insertpos; i < primal->nsols; ++i )
1136 {
1137 SCIP_Real solobj;
1138
1139 solobj = SCIPsolGetOrigObj(primal->sols[i]);
1140 assert( SCIPsetIsGE(set, solobj, obj) );
1141
1142 if( SCIPsetIsGT(set, solobj, obj) )
1143 break;
1144
1145 if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, prob, NULL) )
1146 return TRUE;
1147 }
1148
1149 return FALSE;
1150}
1151
1152/** check if we are willing to check the solution for feasibility */
1153static
1155 SCIP_PRIMAL* primal, /**< primal data */
1156 SCIP_SET* set, /**< global SCIP settings */
1157 SCIP_STAT* stat, /**< problem statistics data */
1158 SCIP_PROB* origprob, /**< original problem */
1159 SCIP_PROB* transprob, /**< transformed problem after presolve */
1160 SCIP_SOL* sol, /**< primal CIP solution */
1161 int* insertpos, /**< pointer to store the insert position of that solution */
1162 SCIP_Bool* replace /**< pointer to store whether the solution at insertpos should be replaced
1163 * (e.g., because it lives in the original space) */
1164 )
1165{
1166 SCIP_Real obj;
1167
1168 obj = SCIPsolGetObj(sol, set, transprob, origprob);
1169
1170 /* check if we are willing to check worse solutions; a solution is better if the objective is smaller than the
1171 * current cutoff bound; solutions with infinite objective value are never accepted
1172 */
1173 if( (!set->misc_improvingsols || obj < primal->cutoffbound) && !SCIPsetIsInfinity(set, obj) )
1174 {
1175 /* find insert position for the solution */
1176 (*insertpos) = primalSearchSolPos(primal, set, transprob, origprob, sol);
1177 (*replace) = FALSE;
1178
1179 /* the solution should be added, if the insertpos is smaller than the maximum number of solutions to be stored
1180 * and it does not already exist or it does exist, but the existing solution should be replaced by the new one
1181 */
1182 if( (*insertpos) < set->limit_maxsol &&
1183 (!primalExistsSol(primal, set, stat, origprob, transprob, sol, insertpos, replace) || (*replace)) )
1184 return TRUE;
1185 }
1186
1187 return FALSE;
1188}
1189
1190/** check if we are willing to store the solution candidate for later checking */
1191static
1193 SCIP_PRIMAL* primal, /**< primal data */
1194 SCIP_SET* set, /**< global SCIP settings */
1195 SCIP_STAT* stat, /**< problem statistics data */
1196 SCIP_PROB* origprob, /**< original problem */
1197 SCIP_SOL* sol, /**< primal CIP solution */
1198 int* insertpos /**< pointer to store the insert position of that solution */
1199 )
1200{
1201 assert(SCIPsolIsOriginal(sol));
1202
1203 /* find insert position for the solution */
1204 (*insertpos) = primalSearchOrigSolPos(primal, sol);
1205
1206 if( !set->reopt_enable && (*insertpos) < set->limit_maxorigsol && !primalExistsOrigSol(primal, set, stat, origprob, sol, *insertpos) )
1207 return TRUE;
1208
1209 return FALSE;
1210}
1211
1212/** adds primal solution to solution storage by copying it */
1214 SCIP_PRIMAL* primal, /**< primal data */
1215 BMS_BLKMEM* blkmem, /**< block memory */
1216 SCIP_SET* set, /**< global SCIP settings */
1217 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1218 SCIP_STAT* stat, /**< problem statistics data */
1219 SCIP_PROB* origprob, /**< original problem */
1220 SCIP_PROB* transprob, /**< transformed problem after presolve */
1221 SCIP_TREE* tree, /**< branch and bound tree */
1222 SCIP_REOPT* reopt, /**< reoptimization data structure */
1223 SCIP_LP* lp, /**< current LP data */
1224 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1225 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1226 SCIP_SOL* sol, /**< primal CIP solution */
1227 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1228 )
1229{
1230 SCIP_Bool replace;
1231 int insertpos;
1232
1233 assert(primal != NULL);
1234 assert(blkmem != NULL);
1235 assert(set != NULL);
1236 assert(messagehdlr != NULL);
1237 assert(stat != NULL);
1238 assert(origprob != NULL);
1239 assert(transprob != NULL);
1240 assert(tree != NULL);
1241 assert(lp != NULL);
1242 assert(eventqueue != NULL);
1243 assert(eventfilter != NULL);
1244 assert(sol != NULL);
1245 assert(stored != NULL);
1246
1247 insertpos = -1;
1248
1249 assert(!SCIPsolIsPartial(sol));
1250
1251 if( solOfInterest(primal, set, stat, origprob, transprob, sol, &insertpos, &replace) )
1252 {
1253 SCIP_SOL* solcopy;
1254#ifdef SCIP_MORE_DEBUG
1255 int i;
1256#endif
1257
1258 assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1259
1260 /* create a copy of the solution */
1261 SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1262
1263 /* insert copied solution into solution storage */
1264 SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1265 tree, reopt, lp, eventqueue, eventfilter, &solcopy, insertpos, replace) );
1266#ifdef SCIP_MORE_DEBUG
1267 for( i = 0; i < primal->nsols - 1; ++i )
1268 {
1269 assert(SCIPsetIsLE(set, SCIPsolGetObj(primal->sols[i], set, transprob, origprob), SCIPsolGetObj(primal->sols[i+1], set, transprob, origprob)));
1270 }
1271#endif
1272 *stored = TRUE;
1273 }
1274 else
1275 *stored = FALSE;
1276
1277 return SCIP_OKAY;
1278}
1279
1280/** adds primal solution to solution storage, frees the solution afterwards */
1282 SCIP_PRIMAL* primal, /**< primal data */
1283 BMS_BLKMEM* blkmem, /**< block memory */
1284 SCIP_SET* set, /**< global SCIP settings */
1285 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1286 SCIP_STAT* stat, /**< problem statistics data */
1287 SCIP_PROB* origprob, /**< original problem */
1288 SCIP_PROB* transprob, /**< transformed problem after presolve */
1289 SCIP_TREE* tree, /**< branch and bound tree */
1290 SCIP_REOPT* reopt, /**< reoptimization data structure */
1291 SCIP_LP* lp, /**< current LP data */
1292 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1293 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1294 SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1295 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1296 )
1297{
1298 SCIP_Bool replace;
1299 int insertpos;
1300
1301 assert(primal != NULL);
1302 assert(transprob != NULL);
1303 assert(origprob != NULL);
1304 assert(sol != NULL);
1305 assert(*sol != NULL);
1306 assert(stored != NULL);
1307
1308 insertpos = -1;
1309
1310 if( solOfInterest(primal, set, stat, origprob, transprob, *sol, &insertpos, &replace) )
1311 {
1312 assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1313
1314 /* insert solution into solution storage */
1315 SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1316 tree, reopt, lp, eventqueue, eventfilter, sol, insertpos, replace) );
1317
1318 /* clear the pointer, such that the user cannot access the solution anymore */
1319 *sol = NULL;
1320
1321 *stored = TRUE;
1322 }
1323 else
1324 {
1325 /* the solution is too bad -> free it immediately */
1326 SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1327
1328 *stored = FALSE;
1329 }
1330 assert(*sol == NULL);
1331
1332 return SCIP_OKAY;
1333}
1334
1335/** adds primal solution to solution candidate storage of original problem space */
1337 SCIP_PRIMAL* primal, /**< primal data */
1338 BMS_BLKMEM* blkmem, /**< block memory */
1339 SCIP_SET* set, /**< global SCIP settings */
1340 SCIP_STAT* stat, /**< problem statistics data */
1341 SCIP_PROB* prob, /**< original problem data */
1342 SCIP_SOL* sol, /**< primal CIP solution; is cleared in function call */
1343 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1344 )
1345{
1346 int insertpos;
1347
1348 assert(primal != NULL);
1349 assert(blkmem != NULL);
1350 assert(set != NULL);
1351 assert(stat != NULL);
1352 assert(sol != NULL);
1353 assert(SCIPsolIsOriginal(sol));
1354 assert(stored != NULL);
1355
1356 insertpos = -1;
1357
1358 if( SCIPsolIsPartial(sol) )
1359 {
1360 SCIP_SOL* solcopy;
1361
1362 /* create a copy of the solution */
1363 SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1364
1365 SCIP_CALL( primalAddOrigPartialSol(primal, set, prob, solcopy) );
1366
1367 *stored = TRUE;
1368 }
1369 else if( origsolOfInterest(primal, set, stat, prob, sol, &insertpos) )
1370 {
1371 SCIP_SOL* solcopy;
1372
1373 assert(insertpos >= 0 && insertpos < set->limit_maxorigsol);
1374 assert(!set->reopt_enable);
1375
1376 /* create a copy of the solution */
1377 SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1378
1379 /* insert solution into solution storage */
1380 SCIP_CALL( primalAddOrigSol(primal, blkmem, set, prob, solcopy, insertpos) );
1381
1382 *stored = TRUE;
1383 }
1384 else
1385 *stored = FALSE;
1386
1387 return SCIP_OKAY;
1388}
1389
1390/** adds primal solution to solution candidate storage of original problem space, frees the solution afterwards */
1392 SCIP_PRIMAL* primal, /**< primal data */
1393 BMS_BLKMEM* blkmem, /**< block memory */
1394 SCIP_SET* set, /**< global SCIP settings */
1395 SCIP_STAT* stat, /**< problem statistics data */
1396 SCIP_PROB* prob, /**< original problem data */
1397 SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1398 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1399 )
1400{
1401 int insertpos;
1402
1403 assert(primal != NULL);
1404 assert(sol != NULL);
1405 assert(*sol != NULL);
1406 assert(SCIPsolIsOriginal(*sol));
1407 assert(stored != NULL);
1408
1409 insertpos = -1;
1410
1411 if( SCIPsolIsPartial(*sol) )
1412 {
1413 /* insert solution into solution storage */
1414 SCIP_CALL( primalAddOrigPartialSol(primal, set, prob, *sol) );
1415
1416 /* clear the pointer, such that the user cannot access the solution anymore */
1417 *sol = NULL;
1418
1419 *stored = TRUE;
1420 }
1421 else if( origsolOfInterest(primal, set, stat, prob, *sol, &insertpos) )
1422 {
1423 assert(insertpos >= 0 && insertpos < set->limit_maxorigsol);
1424 assert(!set->reopt_enable);
1425
1426 /* insert solution into solution storage */
1427 SCIP_CALL( primalAddOrigSol(primal, blkmem, set, prob, *sol, insertpos) );
1428
1429 /* clear the pointer, such that the user cannot access the solution anymore */
1430 *sol = NULL;
1431
1432 *stored = TRUE;
1433 }
1434 else
1435 {
1436 /* the solution is too bad -> free it immediately */
1437 SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1438
1439 *stored = FALSE;
1440 }
1441 assert(*sol == NULL);
1442
1443 return SCIP_OKAY;
1444}
1445
1446/** links temporary solution of primal data to current solution */
1447static
1449 SCIP_PRIMAL* primal, /**< primal data */
1450 BMS_BLKMEM* blkmem, /**< block memory */
1451 SCIP_SET* set, /**< global SCIP settings */
1452 SCIP_STAT* stat, /**< problem statistics data */
1453 SCIP_PROB* prob, /**< transformed problem data */
1454 SCIP_TREE* tree, /**< branch and bound tree */
1455 SCIP_LP* lp, /**< current LP data */
1456 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
1457 )
1458{
1459 assert(primal != NULL);
1460
1461 if( primal->currentsol == NULL )
1462 {
1463 SCIP_CALL( SCIPsolCreateCurrentSol(&primal->currentsol, blkmem, set, stat, prob, primal, tree, lp, heur) );
1464 }
1465 else
1466 {
1467 SCIP_CALL( SCIPsolLinkCurrentSol(primal->currentsol, set, stat, prob, tree, lp) );
1468 SCIPsolSetHeur(primal->currentsol, heur);
1469 }
1470
1471 return SCIP_OKAY;
1472}
1473
1474/** adds current LP/pseudo solution to solution storage */
1476 SCIP_PRIMAL* primal, /**< primal data */
1477 BMS_BLKMEM* blkmem, /**< block memory */
1478 SCIP_SET* set, /**< global SCIP settings */
1479 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1480 SCIP_STAT* stat, /**< problem statistics data */
1481 SCIP_PROB* origprob, /**< original problem */
1482 SCIP_PROB* transprob, /**< transformed problem after presolve */
1483 SCIP_TREE* tree, /**< branch and bound tree */
1484 SCIP_REOPT* reopt, /**< reoptimization data structure */
1485 SCIP_LP* lp, /**< current LP data */
1486 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1487 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1488 SCIP_HEUR* heur, /**< heuristic that found the solution (or NULL if it's from the tree) */
1489 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1490 )
1491{
1492 assert(primal != NULL);
1493
1494 /* link temporary solution to current solution */
1495 SCIP_CALL( primalLinkCurrentSol(primal, blkmem, set, stat, transprob, tree, lp, heur) );
1496
1497 /* add solution to solution storage */
1498 SCIP_CALL( SCIPprimalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1499 tree, reopt, lp, eventqueue, eventfilter, primal->currentsol, stored) );
1500
1501 return SCIP_OKAY;
1502}
1503
1504/** checks primal solution; if feasible, adds it to storage by copying it */
1506 SCIP_PRIMAL* primal, /**< primal data */
1507 BMS_BLKMEM* blkmem, /**< block memory */
1508 SCIP_SET* set, /**< global SCIP settings */
1509 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1510 SCIP_STAT* stat, /**< problem statistics data */
1511 SCIP_PROB* origprob, /**< original problem */
1512 SCIP_PROB* transprob, /**< transformed problem after presolve */
1513 SCIP_TREE* tree, /**< branch and bound tree */
1514 SCIP_REOPT* reopt, /**< reoptimization data structure */
1515 SCIP_LP* lp, /**< current LP data */
1516 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1517 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1518 SCIP_SOL* sol, /**< primal CIP solution */
1519 SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
1520 SCIP_Bool completely, /**< Should all violations be checked? */
1521 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
1522 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1523 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1524 SCIP_Bool* stored /**< stores whether given solution was feasible and good enough to keep */
1525 )
1526{
1527 SCIP_Bool feasible;
1528 SCIP_Bool replace;
1529 int insertpos;
1530
1531 assert(primal != NULL);
1532 assert(set != NULL);
1533 assert(transprob != NULL);
1534 assert(origprob != NULL);
1535 assert(tree != NULL);
1536 assert(sol != NULL);
1537 assert(stored != NULL);
1538
1539 /* if we want to solve exactly, the constraint handlers cannot rely on the LP's feasibility */
1540 checklprows = checklprows || set->misc_exactsolve;
1541
1542 insertpos = -1;
1543
1544 if( solOfInterest(primal, set, stat, origprob, transprob, sol, &insertpos, &replace) )
1545 {
1546 /* check solution for feasibility */
1547 SCIP_CALL( SCIPsolCheck(sol, set, messagehdlr, blkmem, stat, transprob, printreason, completely, checkbounds,
1548 checkintegrality, checklprows, &feasible) );
1549 }
1550 else
1551 feasible = FALSE;
1552
1553 if( feasible )
1554 {
1555 SCIP_SOL* solcopy;
1556
1557 assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1558
1559 /* create a copy of the solution */
1560 SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1561
1562 /* insert copied solution into solution storage */
1563 SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1564 tree, reopt, lp, eventqueue, eventfilter, &solcopy, insertpos, replace) );
1565
1566 *stored = TRUE;
1567 }
1568 else
1569 *stored = FALSE;
1570
1571 return SCIP_OKAY;
1572}
1573
1574/** checks primal solution; if feasible, adds it to storage; solution is freed afterwards */
1576 SCIP_PRIMAL* primal, /**< primal data */
1577 BMS_BLKMEM* blkmem, /**< block memory */
1578 SCIP_SET* set, /**< global SCIP settings */
1579 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1580 SCIP_STAT* stat, /**< problem statistics data */
1581 SCIP_PROB* origprob, /**< original problem */
1582 SCIP_PROB* transprob, /**< transformed problem after presolve */
1583 SCIP_TREE* tree, /**< branch and bound tree */
1584 SCIP_REOPT* reopt, /**< reoptimization data structure */
1585 SCIP_LP* lp, /**< current LP data */
1586 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1587 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1588 SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1589 SCIP_Bool printreason, /**< Should all the reasons of violations be printed? */
1590 SCIP_Bool completely, /**< Should all violations be checked? */
1591 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
1592 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1593 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1594 SCIP_Bool* stored /**< stores whether solution was feasible and good enough to keep */
1595 )
1596{
1597 SCIP_Bool feasible;
1598 SCIP_Bool replace;
1599 int insertpos;
1600
1601 assert(primal != NULL);
1602 assert(transprob != NULL);
1603 assert(origprob != NULL);
1604 assert(tree != NULL);
1605 assert(sol != NULL);
1606 assert(*sol != NULL);
1607 assert(stored != NULL);
1608
1609 *stored = FALSE;
1610
1611 /* if we want to solve exactly, the constraint handlers cannot rely on the LP's feasibility */
1612 checklprows = checklprows || set->misc_exactsolve;
1613
1614 insertpos = -1;
1615
1616 if( solOfInterest(primal, set, stat, origprob, transprob, *sol, &insertpos, &replace) )
1617 {
1618 /* check solution for feasibility */
1619 SCIP_CALL( SCIPsolCheck(*sol, set, messagehdlr, blkmem, stat, transprob, printreason, completely, checkbounds,
1620 checkintegrality, checklprows, &feasible) );
1621 }
1622 else
1623 feasible = FALSE;
1624
1625 if( feasible )
1626 {
1627 assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1628
1629 /* insert solution into solution storage */
1630 SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1631 tree, reopt, lp, eventqueue, eventfilter, sol, insertpos, replace) );
1632
1633 /* clear the pointer, such that the user cannot access the solution anymore */
1634 *sol = NULL;
1635 *stored = TRUE;
1636 }
1637 else
1638 {
1639 /* the solution is too bad or infeasible -> free it immediately */
1640 SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1641 *stored = FALSE;
1642 }
1643 assert(*sol == NULL);
1644
1645 return SCIP_OKAY;
1646}
1647
1648/** checks current LP/pseudo solution; if feasible, adds it to storage */
1650 SCIP_PRIMAL* primal, /**< primal data */
1651 BMS_BLKMEM* blkmem, /**< block memory */
1652 SCIP_SET* set, /**< global SCIP settings */
1653 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1654 SCIP_STAT* stat, /**< problem statistics data */
1655 SCIP_PROB* origprob, /**< original problem */
1656 SCIP_PROB* transprob, /**< transformed problem after presolve */
1657 SCIP_TREE* tree, /**< branch and bound tree */
1658 SCIP_REOPT* reopt, /**< reoptimization data structure */
1659 SCIP_LP* lp, /**< current LP data */
1660 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1661 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1662 SCIP_HEUR* heur, /**< heuristic that found the solution (or NULL if it's from the tree) */
1663 SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
1664 SCIP_Bool completely, /**< Should all violations be checked? */
1665 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1666 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1667 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1668 )
1669{
1670 assert(primal != NULL);
1671
1672 /* link temporary solution to current solution */
1673 SCIP_CALL( primalLinkCurrentSol(primal, blkmem, set, stat, transprob, tree, lp, heur) );
1674
1675 /* add solution to solution storage */
1676 SCIP_CALL( SCIPprimalTrySol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1677 tree, reopt, lp, eventqueue, eventfilter, primal->currentsol,
1678 printreason, completely, FALSE, checkintegrality, checklprows, stored) );
1679
1680 return SCIP_OKAY;
1681}
1682
1683/** inserts solution into the global array of all existing primal solutions */
1685 SCIP_PRIMAL* primal, /**< primal data */
1686 SCIP_SET* set, /**< global SCIP settings */
1687 SCIP_SOL* sol /**< primal CIP solution */
1688 )
1689{
1690 assert(primal != NULL);
1691 assert(sol != NULL);
1692 assert(SCIPsolGetPrimalIndex(sol) == -1);
1693
1694 /* allocate memory for solution storage */
1695 SCIP_CALL( ensureExistingsolsSize(primal, set, primal->nexistingsols+1) );
1696
1697 /* append solution */
1699 primal->existingsols[primal->nexistingsols] = sol;
1700 primal->nexistingsols++;
1701
1702 return SCIP_OKAY;
1703}
1704
1705/** removes solution from the global array of all existing primal solutions */
1707 SCIP_PRIMAL* primal, /**< primal data */
1708 SCIP_SOL* sol /**< primal CIP solution */
1709 )
1710{
1711 int idx;
1712
1713 assert(primal != NULL);
1714 assert(sol != NULL);
1715
1716#ifndef NDEBUG
1717 for( idx = 0; idx < primal->nexistingsols; ++idx )
1718 {
1719 assert(idx == SCIPsolGetPrimalIndex(primal->existingsols[idx]));
1720 }
1721#endif
1722
1723 /* remove solution */
1724 idx = SCIPsolGetPrimalIndex(sol);
1725 assert(0 <= idx && idx < primal->nexistingsols);
1726 assert(sol == primal->existingsols[idx]);
1727 if( idx < primal->nexistingsols-1 )
1728 {
1729 primal->existingsols[idx] = primal->existingsols[primal->nexistingsols-1];
1730 SCIPsolSetPrimalIndex(primal->existingsols[idx], idx);
1731 }
1732 primal->nexistingsols--;
1733}
1734
1735/** updates all existing primal solutions after a change in a variable's objective value */
1737 SCIP_PRIMAL* primal, /**< primal data */
1738 SCIP_VAR* var, /**< problem variable */
1739 SCIP_Real oldobj, /**< old objective value */
1740 SCIP_Real newobj /**< new objective value */
1741 )
1742{
1743 int i;
1744
1745 assert(primal != NULL);
1746
1747 for( i = 0; i < primal->nexistingsols; ++i )
1748 {
1749 if( !SCIPsolIsOriginal(primal->existingsols[i]) )
1750 SCIPsolUpdateVarObj(primal->existingsols[i], var, oldobj, newobj);
1751 }
1752}
1753
1754/** retransforms all existing solutions to original problem space
1755 *
1756 * @note as a side effect, the objective value of the solutions can change (numerical errors)
1757 * so we update the objective cutoff value and upper bound accordingly
1758 */
1760 SCIP_PRIMAL* primal, /**< primal data */
1761 BMS_BLKMEM* blkmem, /**< block memory */
1762 SCIP_SET* set, /**< global SCIP settings */
1763 SCIP_STAT* stat, /**< problem statistics data */
1764 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1765 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1766 SCIP_PROB* origprob, /**< original problem */
1767 SCIP_PROB* transprob, /**< transformed problem */
1768 SCIP_TREE* tree, /**< branch and bound tree */
1769 SCIP_REOPT* reopt, /**< reoptimization data structure */
1770 SCIP_LP* lp /**< current LP data */
1771 )
1772{
1773 SCIP_Bool hasinfval;
1774 int i;
1775
1776 assert(primal != NULL);
1777
1778 for( i = 0; i < primal->nsols; ++i )
1779 {
1780 if( SCIPsolGetOrigin(primal->sols[i]) == SCIP_SOLORIGIN_ZERO )
1781 {
1782 SCIP_CALL( SCIPsolRetransform(primal->sols[i], set, stat, origprob, transprob, &hasinfval) );
1783 }
1784 }
1785
1786 sortPrimalSols(primal, set, origprob, transprob);
1787
1788 /* check if the global upper bound has to be updated
1789 * @todo we do not inform anybody about this change; if this leads to some
1790 * problem, a possible solution is to issue a BESTSOLFOUND event
1791 */
1792 if( primal->nsols > 0 )
1793 {
1794 SCIP_Real obj;
1795
1796 obj = SCIPsolGetObj(primal->sols[0], set, transprob, origprob);
1797 if( obj < primal->cutoffbound )
1798 {
1799 /* update the upper bound */
1800 SCIP_CALL( SCIPprimalSetUpperbound(primal, blkmem, set, stat, eventfilter, eventqueue, transprob, tree, reopt, lp, obj) );
1801 }
1802 }
1803
1804 return SCIP_OKAY;
1805}
1806
1807/** tries to transform original solution to the transformed problem space */
1809 SCIP_PRIMAL* primal, /**< primal data */
1810 SCIP_SOL* sol, /**< primal solution */
1811 BMS_BLKMEM* blkmem, /**< block memory */
1812 SCIP_SET* set, /**< global SCIP settings */
1813 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1814 SCIP_STAT* stat, /**< problem statistics data */
1815 SCIP_PROB* origprob, /**< original problem */
1816 SCIP_PROB* transprob, /**< transformed problem after presolve */
1817 SCIP_TREE* tree, /**< branch and bound tree */
1818 SCIP_REOPT* reopt, /**< reoptimization data structure */
1819 SCIP_LP* lp, /**< current LP data */
1820 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1821 SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1822 SCIP_Real* solvals, /**< array for internal use to store solution values, or NULL;
1823 * if the method is called multiple times in a row, an array with size >=
1824 * number of active variables should be given for performance reasons */
1825 SCIP_Bool* solvalset, /**< array for internal use to store which solution values were set, or NULL;
1826 * if the method is called multiple times in a row, an array with size >=
1827 * number of active variables should be given for performance reasons */
1828 int solvalssize, /**< size of solvals and solvalset arrays, should be >= number of active
1829 * variables */
1830 SCIP_Bool* added /**< pointer to store whether the solution was added */
1831 )
1832{
1833 SCIP_VAR** origvars;
1834 SCIP_VAR** transvars;
1835 SCIP_VAR* var;
1836 SCIP_Real* localsolvals;
1837 SCIP_Bool* localsolvalset;
1838 SCIP_Real solval;
1839 SCIP_Real scalar;
1840 SCIP_Real constant;
1841 SCIP_Bool localarrays;
1842 SCIP_Bool feasible;
1843 int norigvars;
1844 int ntransvars;
1845 int nvarsset;
1846 int v;
1847
1848 assert(origprob != NULL);
1849 assert(transprob != NULL);
1850 assert(SCIPsolIsOriginal(sol));
1851 assert(solvalssize == 0 || solvals != NULL);
1852 assert(solvalssize == 0 || solvalset != NULL);
1853
1854 origvars = origprob->vars;
1855 norigvars = origprob->nvars;
1856 transvars = transprob->vars;
1857 ntransvars = transprob->nvars;
1858 assert(solvalssize == 0 || solvalssize >= ntransvars);
1859
1860 SCIPsetDebugMsg(set, "try to transfer original solution %p with objective %g into the transformed problem space\n",
1861 (void*)sol, SCIPsolGetOrigObj(sol));
1862
1863 /* if no solvals and solvalset arrays are given, allocate local ones, otherwise use the given ones */
1864 localarrays = (solvalssize == 0);
1865 if( localarrays )
1866 {
1867 SCIP_CALL( SCIPsetAllocBufferArray(set, &localsolvals, ntransvars) );
1868 SCIP_CALL( SCIPsetAllocBufferArray(set, &localsolvalset, ntransvars) );
1869 }
1870 else
1871 {
1872 localsolvals = solvals;
1873 localsolvalset = solvalset;
1874 }
1875
1876 BMSclearMemoryArray(localsolvalset, ntransvars);
1877 feasible = TRUE;
1878 (*added) = FALSE;
1879 nvarsset = 0;
1880
1881 /* for each original variable, get the corresponding active, fixed or multi-aggregated variable;
1882 * if it resolves to an active variable, we set its solution value or check whether an already stored solution value
1883 * is consistent; if it resolves to a fixed variable, we check that the fixing matches the original solution value;
1884 * multi-aggregated variables are skipped, because their value is defined by setting solution values for the active
1885 * variables, anyway
1886 */
1887 for( v = 0; v < norigvars && feasible; ++v )
1888 {
1889 var = origvars[v];
1890
1891 solval = SCIPsolGetVal(sol, set, stat, var);
1892
1893 /* get corresponding active, fixed, or multi-aggregated variable */
1894 scalar = 1.0;
1895 constant = 0.0;
1896 SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
1899
1900 /* check whether the fixing corresponds to the solution value of the original variable */
1901 if( scalar == 0.0 )
1902 {
1903 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED ||
1904 (SCIPsetIsInfinity(set, constant) || SCIPsetIsInfinity(set, -constant)));
1905
1906 if( !SCIPsetIsEQ(set, solval, constant) )
1907 {
1908 SCIPsetDebugMsg(set, "original variable <%s> (solval=%g) resolves to fixed variable <%s> (original solval=%g)\n",
1909 SCIPvarGetName(origvars[v]), solval, SCIPvarGetName(var), constant);
1910 feasible = FALSE;
1911 }
1912 }
1913 else if( SCIPvarIsActive(var) )
1914 {
1915 /* if we already assigned a solution value to the transformed variable, check that it corresponds to the
1916 * value obtained from the currently regarded original variable
1917 */
1918 if( localsolvalset[SCIPvarGetProbindex(var)] )
1919 {
1920 if( !SCIPsetIsEQ(set, solval, scalar * localsolvals[SCIPvarGetProbindex(var)] + constant) )
1921 {
1922 SCIPsetDebugMsg(set, "original variable <%s> (solval=%g) resolves to active variable <%s> with assigned solval %g (original solval=%g)\n",
1923 SCIPvarGetName(origvars[v]), solval, SCIPvarGetName(var), localsolvals[SCIPvarGetProbindex(var)],
1924 scalar * localsolvals[SCIPvarGetProbindex(var)] + constant);
1925 feasible = FALSE;
1926 }
1927 }
1928 /* assign solution value to the transformed variable */
1929 else
1930 {
1931 assert(scalar != 0.0);
1932
1933 localsolvals[SCIPvarGetProbindex(var)] = (solval - constant) / scalar;
1934 localsolvalset[SCIPvarGetProbindex(var)] = TRUE;
1935 ++nvarsset;
1936 }
1937 }
1938#ifndef NDEBUG
1939 /* we do not have to handle multi-aggregated variables here, since by assigning values to all active variabes,
1940 * we implicitly assign values to the multi-aggregated variables, too
1941 */
1942 else
1944#endif
1945 }
1946
1947 /* if the solution values of fixed and active variables lead to no contradiction, construct solution and try it */
1948 if( feasible )
1949 {
1950 SCIP_SOL* transsol;
1951
1952 SCIP_CALL( SCIPsolCreate(&transsol, blkmem, set, stat, primal, tree, SCIPsolGetHeur(sol)) );
1953
1954 /* set solution values for variables to which we assigned a value */
1955 for( v = 0; v < ntransvars; ++v )
1956 {
1957 if( localsolvalset[v] )
1958 {
1959 SCIP_CALL( SCIPsolSetVal(transsol, set, stat, tree, transvars[v], localsolvals[v]) );
1960 }
1961 }
1962
1963 SCIP_CALL( SCIPprimalTrySolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1964 tree, reopt, lp, eventqueue, eventfilter, &transsol, FALSE, FALSE, TRUE, TRUE, TRUE, added) );
1965
1966 SCIPsetDebugMsg(set, "solution transferred, %d/%d active variables set (stored=%u)\n", nvarsset, ntransvars, *added);
1967 }
1968 else
1969 (*added) = FALSE;
1970
1971 /* free local arrays, if needed */
1972 if( localarrays )
1973 {
1974 SCIPsetFreeBufferArray(set, &localsolvalset);
1975 SCIPsetFreeBufferArray(set, &localsolvals);
1976 }
1977
1978 return SCIP_OKAY;
1979}
1980
1981
1982/** is the updating of violations enabled for this problem? */
1984 SCIP_PRIMAL* primal /**< problem data */
1985 )
1986{
1987 assert(primal != NULL);
1988
1989 return primal->updateviolations;
1990}
1991
1992/** set whether the updating of violations is turned on */
1994 SCIP_PRIMAL* primal, /**< problem data */
1995 SCIP_Bool updateviolations /**< marks whether the updating of violations is turned on */
1996 )
1997{
1998 assert(primal != NULL);
1999
2000 primal->updateviolations = updateviolations;
2001}
common defines and data types used in all packages of SCIP
#define NULL
Definition: def.h:266
#define SCIP_INVALID
Definition: def.h:192
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:242
#define SCIP_ALLOC(x)
Definition: def.h:384
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_LONGINT_FORMAT
Definition: def.h:164
#define SCIPABORT()
Definition: def.h:345
#define REALABS(x)
Definition: def.h:196
#define SCIP_CALL(x)
Definition: def.h:373
SCIP_RETCODE SCIPdispPrintLine(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, FILE *file, SCIP_Bool forcedisplay, SCIP_Bool endline)
Definition: disp.c:415
internal methods for displaying runtime statistics
SCIP_RETCODE SCIPeventChgSol(SCIP_EVENT *event, SCIP_SOL *sol)
Definition: event.c:1354
SCIP_RETCODE SCIPeventProcess(SCIP_EVENT *event, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1574
SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
Definition: event.c:1040
internal methods for managing events
SCIP_SOLORIGIN SCIPsolGetOrigin(SCIP_SOL *sol)
Definition: sol.c:2711
SCIP_Real SCIPsolGetOrigObj(SCIP_SOL *sol)
Definition: sol.c:2741
SCIP_Real SCIPsolGetTime(SCIP_SOL *sol)
Definition: sol.c:2764
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition: sol.c:2784
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2804
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition: sol.c:2721
int SCIPsolGetDepth(SCIP_SOL *sol)
Definition: sol.c:2794
SCIP_Bool SCIPsolIsPartial(SCIP_SOL *sol)
Definition: sol.c:2731
int SCIPsolGetRunnum(SCIP_SOL *sol)
Definition: sol.c:2774
void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
Definition: sol.c:2849
SCIP_Real SCIPgetLowerbound(SCIP *scip)
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17747
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17537
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17767
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17418
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10201
internal methods for LP management
#define BMSfreeMemory(ptr)
Definition: memory.h:145
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:127
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:437
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:148
#define BMSallocMemory(ptr)
Definition: memory.h:118
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:427
SCIP_RETCODE SCIPprimalAddCurrentSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_HEUR *heur, SCIP_Bool *stored)
Definition: primal.c:1475
void SCIPprimalSetUpdateViolations(SCIP_PRIMAL *primal, SCIP_Bool updateviolations)
Definition: primal.c:1993
SCIP_RETCODE SCIPprimalUpdateRay(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *primalray, BMS_BLKMEM *blkmem)
Definition: primal.c:601
void SCIPprimalSolFreed(SCIP_PRIMAL *primal, SCIP_SOL *sol)
Definition: primal.c:1706
static SCIP_RETCODE primalAddSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **solptr, int insertpos, SCIP_Bool replace)
Definition: primal.c:630
static SCIP_Bool origsolOfInterest(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_SOL *sol, int *insertpos)
Definition: primal.c:1192
SCIP_RETCODE SCIPprimalSetUpperbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real upperbound)
Definition: primal.c:416
static int primalSearchSolPos(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SOL *sol)
Definition: primal.c:935
SCIP_RETCODE SCIPprimalAddOrigSolFree(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_SOL **sol, SCIP_Bool *stored)
Definition: primal.c:1391
SCIP_RETCODE SCIPprimalTryCurrentSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_HEUR *heur, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: primal.c:1649
static SCIP_RETCODE ensureExistingsolsSize(SCIP_PRIMAL *primal, SCIP_SET *set, int num)
Definition: primal.c:108
SCIP_RETCODE SCIPprimalClear(SCIP_PRIMAL **primal, BMS_BLKMEM *blkmem)
Definition: primal.c:203
void SCIPprimalAddOrigObjoffset(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_Real addval)
Definition: primal.c:544
SCIP_RETCODE SCIPprimalFree(SCIP_PRIMAL **primal, BMS_BLKMEM *blkmem)
Definition: primal.c:160
static SCIP_Bool primalExistsOrigSol(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_SOL *sol, int insertpos)
Definition: primal.c:1102
static SCIP_RETCODE primalAddOrigSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_SOL *sol, int insertpos)
Definition: primal.c:852
SCIP_SOL * SCIPprimalGetRay(SCIP_PRIMAL *primal)
Definition: primal.c:591
SCIP_RETCODE SCIPprimalTrySolFree(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: primal.c:1575
SCIP_Bool SCIPprimalUpdateViolations(SCIP_PRIMAL *primal)
Definition: primal.c:1983
SCIP_Bool SCIPprimalUpperboundIsSol(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: primal.c:578
static SCIP_RETCODE ensureSolsSize(SCIP_PRIMAL *primal, SCIP_SET *set, int num)
Definition: primal.c:60
static void sortPrimalSols(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_PROB *origprob, SCIP_PROB *transprob)
Definition: primal.c:247
SCIP_RETCODE SCIPprimalAddOrigSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_SOL *sol, SCIP_Bool *stored)
Definition: primal.c:1336
static SCIP_RETCODE primalSetCutoffbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real cutoffbound)
Definition: primal.c:274
void SCIPprimalUpdateVarObj(SCIP_PRIMAL *primal, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: primal.c:1736
SCIP_RETCODE SCIPprimalCreate(SCIP_PRIMAL **primal)
Definition: primal.c:130
SCIP_RETCODE SCIPprimalUpdateObjoffset(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp)
Definition: primal.c:488
static SCIP_RETCODE primalLinkCurrentSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
Definition: primal.c:1448
SCIP_RETCODE SCIPprimalTrySol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: primal.c:1505
SCIP_RETCODE SCIPprimalTransformSol(SCIP_PRIMAL *primal, SCIP_SOL *sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Real *solvals, SCIP_Bool *solvalset, int solvalssize, SCIP_Bool *added)
Definition: primal.c:1808
SCIP_RETCODE SCIPprimalUpdateObjlimit(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp)
Definition: primal.c:448
SCIP_RETCODE SCIPprimalAddSolFree(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **sol, SCIP_Bool *stored)
Definition: primal.c:1281
static SCIP_RETCODE primalSetUpperbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real upperbound)
Definition: primal.c:361
SCIP_RETCODE SCIPprimalAddSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL *sol, SCIP_Bool *stored)
Definition: primal.c:1213
static int primalSearchOrigSolPos(SCIP_PRIMAL *primal, SCIP_SOL *sol)
Definition: primal.c:985
SCIP_RETCODE SCIPprimalSetCutoffbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real cutoffbound, SCIP_Bool useforobjlimit)
Definition: primal.c:307
static SCIP_Bool solOfInterest(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_SOL *sol, int *insertpos, SCIP_Bool *replace)
Definition: primal.c:1154
SCIP_RETCODE SCIPprimalSolCreated(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_SOL *sol)
Definition: primal.c:1684
SCIP_RETCODE SCIPprimalRetransformSolutions(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp)
Definition: primal.c:1759
static SCIP_Bool primalExistsSol(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_SOL *sol, int *insertpos, SCIP_Bool *replace)
Definition: primal.c:1020
static SCIP_RETCODE ensurePartialsolsSize(SCIP_PRIMAL *primal, SCIP_SET *set, int num)
Definition: primal.c:83
static SCIP_RETCODE primalAddOrigPartialSol(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_PROB *prob, SCIP_SOL *sol)
Definition: primal.c:904
internal methods for collecting primal CIP solutions and primal informations
SCIP_Real SCIPprobGetObjlim(SCIP_PROB *prob, SCIP_SET *set)
Definition: prob.c:2362
void SCIPprobSetObjlim(SCIP_PROB *prob, SCIP_Real objlim)
Definition: prob.c:1505
SCIP_Bool SCIPprobIsObjIntegral(SCIP_PROB *prob)
Definition: prob.c:2338
SCIP_Real SCIPprobExternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
Definition: prob.c:2157
SCIP_Real SCIPprobInternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
Definition: prob.c:2179
internal methods for storing and manipulating the main problem
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebug(x)
Definition: pub_message.h:93
public methods for problem variables
data structures and methods for collecting reoptimization information
public methods for querying solving statistics
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6293
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6775
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6663
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6641
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6257
SCIP_Real SCIPsetEpsilon(SCIP_SET *set)
Definition: set.c:6086
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6221
SCIP_STAGE SCIPsetGetStage(SCIP_SET *set)
Definition: set.c:2952
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6064
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6239
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6199
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6275
SCIP_Real SCIPsetCutoffbounddelta(SCIP_SET *set)
Definition: set.c:6164
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6685
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5764
internal methods for global SCIP settings
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1755
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1748
#define SCIPsetDebugMsg
Definition: set.h:1784
void SCIPsolUpdateVarObj(SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: sol.c:1588
void SCIPsolSetPrimalIndex(SCIP_SOL *sol, int primalindex)
Definition: sol.c:2824
int SCIPsolGetPrimalIndex(SCIP_SOL *sol)
Definition: sol.c:2814
SCIP_RETCODE SCIPsolLinkCurrentSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
Definition: sol.c:988
SCIP_RETCODE SCIPsolCheck(SCIP_SOL *sol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
Definition: sol.c:1838
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition: sol.c:801
SCIP_RETCODE SCIPsolRetransform(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_Bool *hasinfval)
Definition: sol.c:2059
SCIP_RETCODE SCIPsolCreateCurrentSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
Definition: sol.c:703
SCIP_RETCODE SCIPsolTransform(SCIP_SOL *sol, SCIP_SOL **transsol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal)
Definition: sol.c:426
SCIP_RETCODE SCIPsolSetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real val)
Definition: sol.c:1077
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1372
SCIP_RETCODE SCIPsolUnlink(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *prob)
Definition: sol.c:1048
SCIP_Bool SCIPsolsAreEqual(SCIP_SOL *sol1, SCIP_SOL *sol2, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob)
Definition: sol.c:2221
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1571
SCIP_RETCODE SCIPsolPrint(SCIP_SOL *sol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PROB *transprob, FILE *file, SCIP_Bool mipstart, SCIP_Bool printzeros)
Definition: sol.c:2286
void SCIPsolUpdateVarsum(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_Real weight)
Definition: sol.c:2031
SCIP_RETCODE SCIPsolCopy(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_SOL *sourcesol)
Definition: sol.c:362
SCIP_RETCODE SCIPsolCreate(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_HEUR *heur)
Definition: sol.c:288
void SCIPsolOrigAddObjval(SCIP_SOL *sol, SCIP_Real addval)
Definition: sol.c:2752
internal methods for storing primal CIP solutions
internal methods for problem statistics
SCIP_SOL * currentsol
Definition: struct_primal.h:60
int partialsolssize
Definition: struct_primal.h:64
int existingsolssize
Definition: struct_primal.h:67
SCIP_SOL ** partialsols
Definition: struct_primal.h:58
SCIP_SOL ** sols
Definition: struct_primal.h:57
SCIP_Longint nbestsolsfound
Definition: struct_primal.h:51
SCIP_Bool updateviolations
Definition: struct_primal.h:70
SCIP_SOL * primalray
Definition: struct_primal.h:61
SCIP_Longint nsolsfound
Definition: struct_primal.h:48
SCIP_Longint nlimsolsfound
Definition: struct_primal.h:49
SCIP_Real cutoffbound
Definition: struct_primal.h:55
SCIP_SOL ** existingsols
Definition: struct_primal.h:59
SCIP_Real upperbound
Definition: struct_primal.h:54
SCIP_OBJSENSE objsense
Definition: struct_prob.h:87
SCIP_VAR ** vars
Definition: struct_prob.h:64
SCIP_Longint nnodes
Definition: struct_stat.h:82
int firstprimaldepth
Definition: struct_stat.h:272
SCIP_VISUAL * visual
Definition: struct_stat.h:184
SCIP_Real firstprimaltime
Definition: struct_stat.h:134
int nrunsbeforefirst
Definition: struct_stat.h:271
SCIP_HEUR * firstprimalheur
Definition: struct_stat.h:185
SCIP_Longint nnodesbeforefirst
Definition: struct_stat.h:122
SCIP_Longint bestsolnode
Definition: struct_stat.h:113
SCIP_Real firstprimalbound
Definition: struct_stat.h:133
datastructures for managing events
Definition: heur_padm.c:135
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8485
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8502
SCIP_RETCODE SCIPtreeCutoff(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real cutoffbound)
Definition: tree.c:5222
SCIP_Bool SCIPtreeInRepropagation(SCIP_TREE *tree)
Definition: tree.c:8475
internal methods for branch and bound tree
#define SCIP_EVENTTYPE_POORSOLFOUND
Definition: type_event.h:104
#define SCIP_EVENTTYPE_BESTSOLFOUND
Definition: type_event.h:105
@ SCIP_OBJSENSE_MINIMIZE
Definition: type_prob.h:48
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_PROBLEM
Definition: type_set.h:45
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
@ SCIP_STAGE_PRESOLVED
Definition: type_set.h:51
@ SCIP_SOLORIGIN_ZERO
Definition: type_sol.h:43
@ SCIP_SOLORIGIN_ORIGINAL
Definition: type_sol.h:42
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:52
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:54
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12646
internal methods for problem variables
void SCIPvisualUpperbound(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real upperbound)
Definition: visual.c:805
void SCIPvisualFoundSolution(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node, SCIP_Bool bettersol, SCIP_SOL *sol)
Definition: visual.c:669
methods for creating output for visualization tools (VBC, BAK)