SCIP Doxygen Documentation
 
Loading...
Searching...
No Matches
nlp.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-2023 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 nlp.c
26 * @ingroup OTHER_CFILES
27 * @brief NLP management methods
28 * @author Thorsten Gellermann
29 * @author Stefan Vigerske
30 *
31 * In NLP management, we have to distinguish between the current NLP and the NLPI problem
32 * stored in the NLP solver. All NLP methods affect the current NLP only.
33 * Before solving the current NLP with the NLP solver, the NLP solvers data
34 * has to be updated to the current NLP with a call to SCIPnlpFlush().
35 *
36 * @todo handle linear rows from LP
37 */
38
39/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
40
41
42#include "scip/nlpi.h"
43#include "scip/pub_expr.h"
44#include "scip/expr.h"
45#include "scip/expr_varidx.h"
46#include "scip/clock.h"
47#include "scip/event.h"
48#include "scip/nlp.h"
49#include "scip/primal.h"
50#include "scip/pub_event.h"
51#include "scip/pub_lp.h"
52#include "scip/pub_message.h"
53#include "scip/pub_misc.h"
54#include "scip/pub_misc_sort.h"
55#include "scip/pub_nlp.h"
56#include "scip/pub_var.h"
57#include "scip/set.h"
58#include "scip/sol.h"
59#include "scip/struct_nlp.h"
60/* to get nlp, set, ... in event handling and mapvar2varidx */
61#include "scip/struct_scip.h"
62/* to get value of parameter "nlp/solver" and nlpis array and to get access to set->lp for releasing a variable */
63#include "scip/struct_set.h"
64#include "scip/struct_stat.h"
65#include "scip/var.h"
66#include <string.h>
67
68/* defines */
69
70#define EVENTHDLR_NAME "nlpEventHdlr" /**< name of NLP event handler that catches variable events */
71#define EVENTHDLR_DESC "handles all events necessary for maintaining NLP data" /**< description of NLP event handler */
72#define ADDNAMESTONLPI 0 /**< whether to give variable and row names to NLPI */
73
74/*lint -e440*/
75/*lint -e441*/
76/*lint -e777*/
77
78#ifdef __cplusplus
79extern "C" {
80#endif
81
82/* avoid inclusion of scip.h */ /*lint -e{2701}*/
84 SCIP* scip /**< SCIP data structure */
85 );
86
87#ifdef __cplusplus
88}
89#endif
90
91/*
92 * forward declarations
93 */
94
95/** NLP event handler execution method */
96static
98
99/** announces, that a row of the NLP was modified
100 *
101 * adjusts status of current solution;
102 * calling method has to ensure that change is passed on to the NLPI!
103 */
104static
106 SCIP_NLP* nlp, /**< current NLP data */
107 SCIP_SET* set, /**< global SCIP settings */
108 SCIP_STAT* stat, /**< problem statistics data */
109 SCIP_NLROW* nlrow /**< nonlinear row which was changed */
110 );
111
112/*
113 * private NLP nonlinear row methods
114 */
115
116/** announces, that the given linear coefficient in the constraint matrix changed */
117static
119 SCIP_NLROW* nlrow, /**< nonlinear row */
120 SCIP_SET* set, /**< global SCIP settings */
121 SCIP_STAT* stat, /**< problem statistics data */
122 SCIP_VAR* var, /**< variable which coefficient changed */
123 SCIP_Real coef, /**< new coefficient of variable, 0.0 if deleted */
124 SCIP_NLP* nlp /**< current NLP data */
125 )
126{
127 assert(nlrow != NULL);
128 assert(var != NULL);
129
130 nlrow->activity = SCIP_INVALID;
131 nlrow->validactivitynlp = -1;
133 nlrow->validpsactivitydomchg = -1;
134 nlrow->minactivity = SCIP_INVALID;
135 nlrow->maxactivity = SCIP_INVALID;
136 nlrow->validactivitybdsdomchg = -1;
137
138 if( nlrow->nlpindex >= 0 )
139 {
140 assert(nlp != NULL);
141
142 /* notify NLP that row has changed */
143 SCIP_CALL( nlpRowChanged(nlp, set, stat, nlrow) );
144
145 /* update NLPI problem, if row is in NLPI already */
146 if( nlrow->nlpiindex >= 0 )
147 {
148 int idx;
149
150 /* get index of variable in NLPI */
153 assert(idx >= 0 && idx < nlp->nvars);
154
155 idx = nlp->varmap_nlp2nlpi[idx];
156 assert(idx >= 0 && idx < nlp->nvars_solver);
157
158 /* change coefficient in NLPI problem */
159 SCIP_CALL( SCIPnlpiChgLinearCoefs(set, nlp->solver, nlp->problem, nlrow->nlpiindex, 1, &idx, &coef) );
160 }
161 }
162
163 return SCIP_OKAY;
164}
165
166/** create varidx expression for var expression
167 *
168 * called when expr is duplicated for addition to NLPI
169 */
170static
172{
173 SCIP_NLP* nlp;
174 int nlpidx;
175
176 assert(sourcescip != NULL);
177 assert(sourcescip == targetscip);
182
183 nlp = (SCIP_NLP*)mapexprdata;
184
185 /* do not provide map if not variable */
186 if( !SCIPexprIsVar(sourcescip->set, sourceexpr) )
187 return SCIP_OKAY;
188
189 assert(SCIPvarIsActive(SCIPgetVarExprVar(sourceexpr))); /* because we simplified exprs */
190
194
195 assert(nlp->varmap_nlp2nlpi[nlpidx] >= 0);
198
199 return SCIP_OKAY;
200}
201
202/** announces, that an expression changed */
203static
205 SCIP_NLROW* nlrow, /**< nonlinear row */
206 BMS_BLKMEM* blkmem, /**< block memory */
207 SCIP_SET* set, /**< global SCIP settings */
208 SCIP_STAT* stat, /**< problem statistics data */
209 SCIP_NLP* nlp /**< current NLP data */
210 )
211{
212 assert(nlrow != NULL);
213
214 nlrow->activity = SCIP_INVALID;
215 nlrow->validactivitynlp = -1;
217 nlrow->validpsactivitydomchg = -1;
218 nlrow->minactivity = SCIP_INVALID;
219 nlrow->maxactivity = SCIP_INVALID;
220 nlrow->validactivitybdsdomchg = -1;
221
222 if( nlrow->nlpindex >= 0 )
223 {
224 assert(nlp != NULL);
225
226 /* notify NLP that row has changed */
227 SCIP_CALL( nlpRowChanged(nlp, set, stat, nlrow) );
228
229 if( nlrow->nlpiindex >= 0 )
230 {
231 /* change expression tree in NLPI problem */
233
234 SCIP_CALL( SCIPexprCopy(set, stat, blkmem, set, stat, blkmem, nlrow->expr, &nlpiexpr, mapvar2varidx, (void*)nlp, NULL, NULL) );
235 SCIP_CALL( SCIPnlpiChgExpr(set, nlp->solver, nlp->problem, nlrow->nlpiindex, nlpiexpr) );
236 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlpiexpr) );
237 }
238 }
239
240 return SCIP_OKAY;
241}
242
243/** notifies nonlinear row, that its sides were changed */
244static
246 SCIP_NLROW* nlrow, /**< nonlinear row */
247 SCIP_SET* set, /**< global SCIP settings */
248 SCIP_STAT* stat, /**< problem statistics data */
249 SCIP_NLP* nlp /**< current NLP data */
250 )
251{
252 assert(nlrow != NULL);
253
254 if( nlrow->nlpindex >= 0 )
255 {
256 assert(nlp != NULL);
257
258 /* notify NLP that row has changed */
259 SCIP_CALL( nlpRowChanged(nlp, set, stat, nlrow) );
260
261 if( nlrow->nlpiindex >= 0 )
262 {
263 SCIP_Real lhs;
264 SCIP_Real rhs;
265
266 /* change sides in NLPI problem */
267 lhs = nlrow->lhs;
268 rhs = nlrow->rhs;
269 if( !SCIPsetIsInfinity(set, -lhs) )
270 lhs -= nlrow->constant;
271 if( !SCIPsetIsInfinity(set, rhs) )
272 rhs -= nlrow->constant;
273
274 SCIP_CALL( SCIPnlpiChgConsSides(set, nlp->solver, nlp->problem, 1, &nlrow->nlpiindex, &lhs, &rhs) );
275 }
276 }
277
278 return SCIP_OKAY;
279}
280
281/** notifies nonlinear row, that its constant was changed */
282static
284 SCIP_NLROW* nlrow, /**< nonlinear row */
285 SCIP_SET* set, /**< global SCIP settings */
286 SCIP_STAT* stat, /**< problem statistics data */
287 SCIP_NLP* nlp /**< current NLP data */
288 )
289{
290 assert(nlrow != NULL);
291
292 nlrow->activity = SCIP_INVALID;
293 nlrow->validactivitynlp = -1;
295 nlrow->validpsactivitydomchg = -1;
296 nlrow->minactivity = SCIP_INVALID;
297 nlrow->maxactivity = SCIP_INVALID;
298 nlrow->validactivitybdsdomchg = -1;
299
300 if( nlrow->nlpindex >= 0 )
301 {
302 assert(nlp != NULL);
303
304 /* notify NLP that row has changed */
305 SCIP_CALL( nlpRowChanged(nlp, set, stat, nlrow) );
306
307 if( nlrow->nlpiindex >= 0 )
308 {
309 SCIP_Real lhs;
310 SCIP_Real rhs;
311
312 lhs = nlrow->lhs;
313 rhs = nlrow->rhs;
314 if( !SCIPsetIsInfinity(set, -lhs) )
315 lhs -= nlrow->constant;
316 if( !SCIPsetIsInfinity(set, rhs) )
317 rhs -= nlrow->constant;
318
319 /* change sides in NLPI problem */
320 SCIP_CALL( SCIPnlpiChgConsSides(set, nlp->solver, nlp->problem, 1, &nlrow->nlpiindex, &lhs, &rhs) );
321 }
322 }
323
324 return SCIP_OKAY;
325}
326
327/** sorts linear part of row entries such that lower variable indices precede higher ones */
328static
330 SCIP_NLROW* nlrow /**< nonlinear row to be sorted */
331 )
332{
333 assert(nlrow != NULL);
334
335 /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
336 if( nlrow->linvarssorted )
337 return;
338
339 /* sort linear coefficients */
340 SCIPsortPtrReal((void**)nlrow->linvars, nlrow->lincoefs, SCIPvarComp, nlrow->nlinvars);
341
342 nlrow->linvarssorted = TRUE;
343}
344
345/** searches linear variable in nonlinear row, returns position in linvars vector or -1 if not found */
346static
348 SCIP_NLROW* nlrow, /**< nonlinear row to be searched in */
349 SCIP_VAR* var /**< variable to be searched for */
350 )
351{
352 int pos;
353
354 assert(nlrow != NULL);
355 assert(var != NULL);
356
357 if( nlrow->nlinvars == 0 )
358 return -1;
359
360 nlrowSortLinear(nlrow);
361 if( !SCIPsortedvecFindPtr((void**)nlrow->linvars, SCIPvarComp, (void*)var, nlrow->nlinvars, &pos) )
362 return -1;
363
364 return pos;
365}
366
367/** moves a coefficient in a nonlinear row to a different place, and updates all corresponding data structures */
368static
370 SCIP_NLROW* nlrow, /**< NLP row */
371 int oldpos, /**< old position of coefficient */
372 int newpos /**< new position of coefficient */
373 )
374{
375 assert(nlrow != NULL);
376 assert(0 <= oldpos && oldpos < nlrow->nlinvars);
377 assert(0 <= newpos && newpos < nlrow->nlinvars);
378 assert(nlrow->linvars[oldpos] != NULL);
379
380 if( oldpos == newpos )
381 return;
382
383 nlrow->linvars[newpos] = nlrow->linvars[oldpos];
384 nlrow->lincoefs[newpos] = nlrow->lincoefs[oldpos];
385
386 /* update sorted flags */
387 nlrow->linvarssorted = FALSE;
388}
389
390/** adds a previously non existing linear coefficient to a nonlinear row */
391static
393 SCIP_NLROW* nlrow, /**< nonlinear row */
394 BMS_BLKMEM* blkmem, /**< block memory */
395 SCIP_SET* set, /**< global SCIP settings */
396 SCIP_STAT* stat, /**< problem statistics data */
397 SCIP_NLP* nlp, /**< current NLP data */
398 SCIP_VAR* var, /**< variable */
399 SCIP_Real coef /**< value of coefficient */
400 )
401{
402 int pos;
403
404 assert(nlrow != NULL);
405 assert(blkmem != NULL);
406 assert(var != NULL);
407 assert(coef != 0.0);
408
409 /* assert that only active variables are added once the row is in the NLP */
410 assert(nlrow->nlpindex == -1 || SCIPvarIsActive(var) );
411
412 SCIP_CALL( SCIPnlrowEnsureLinearSize(nlrow, blkmem, set, nlrow->nlinvars+1) );
413 assert(nlrow->linvars != NULL);
414 assert(nlrow->lincoefs != NULL);
415
416 pos = nlrow->nlinvars;
417 nlrow->nlinvars++;
418
419 /* insert the variable */
420 nlrow->linvars [pos] = var;
421 nlrow->lincoefs[pos] = coef;
422
423 SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, var, coef, nlp) );
424
425 /* update sorted flag */
426 if( pos > 0 && SCIPvarCompare(nlrow->linvars[pos-1], nlrow->linvars[pos]) > 0 )
427 nlrow->linvarssorted = FALSE;
428
429 SCIPsetDebugMsg(set, "added linear coefficient %g * <%s> at position %d to nonlinear row <%s>\n",
430 coef, SCIPvarGetName(var), pos, nlrow->name);
431
432 return SCIP_OKAY;
433}
434
435#ifdef SCIP_DISABLED_CODE
436/** adds a linear coefficient to a nonlinear row
437 * if the variable exists in the linear part of the row already, the coefficients are added
438 * otherwise the variable is added to the row */
439static
441 SCIP_NLROW* nlrow, /**< nonlinear row */
442 BMS_BLKMEM* blkmem, /**< block memory */
443 SCIP_SET* set, /**< global SCIP settings */
444 SCIP_STAT* stat, /**< problem statistics data */
445 SCIP_NLP* nlp, /**< current NLP data */
446 SCIP_VAR* var, /**< variable */
447 SCIP_Real coef, /**< value of coefficient */
448 SCIP_Bool removefixed /**< whether to disaggregate var before adding */
449 )
450{
451 int pos;
452
453 assert(nlrow != NULL);
454 assert(blkmem != NULL);
455 assert(var != NULL);
456
458 {
459 SCIP_Real constant;
460
461 constant = 0.0;
462 SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &coef, &constant) );
463 if( constant != 0.0 )
464 {
465 nlrow->constant += constant;
466 SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
467 }
468
469 if( SCIPsetIsZero(set, coef) )
470 return SCIP_OKAY;
471
472 if( !SCIPvarIsActive(var) )
473 {
474 int j;
475
476 /* if var is still not active, then it is multi-aggregated */
478
479 if( SCIPvarGetMultaggrConstant(var) != 0.0 )
480 {
481 nlrow->constant += coef * SCIPvarGetMultaggrConstant(var);
482 SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
483 }
484
485 for( j = 0; j < SCIPvarGetMultaggrNVars(var); ++j )
486 {
488 }
489
490 return SCIP_OKAY;
491 }
492 }
493 else if( SCIPsetIsZero(set, coef) )
494 return SCIP_OKAY;
495
497
498 pos = nlrowSearchLinearCoef(nlrow, var);
499
500 if( pos == -1 )
501 {
502 /* add as new coefficient */
503 SCIP_CALL( nlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, var, coef) );
504 }
505 else
506 {
507 assert(pos >= 0);
508 assert(pos < nlrow->nlinvars);
509 assert(nlrow->linvars[pos] == var);
510
511 /* add to previously existing coefficient */
512 nlrow->lincoefs[pos] += coef;
513 }
514
515 return SCIP_OKAY;
516}
517#endif
518
519/** deletes coefficient at given position from row */
520static
522 SCIP_NLROW* nlrow, /**< nonlinear row to be changed */
523 SCIP_SET* set, /**< global SCIP settings */
524 SCIP_STAT* stat, /**< problem statistics data */
525 SCIP_NLP* nlp, /**< current NLP data */
526 int pos /**< position in row vector to delete */
527 )
528{
529 SCIP_VAR* var;
530
531 assert(nlrow != NULL);
532 assert(set != NULL);
533 assert(0 <= pos && pos < nlrow->nlinvars);
534 assert(nlrow->linvars[pos] != NULL);
535
536 var = nlrow->linvars[pos];
537
538 /* move last coefficient to position of empty slot (should set sorted flag to FALSE, if not last variable was deleted) */
539 nlrowMoveLinearCoef(nlrow, nlrow->nlinvars-1, pos);
540 nlrow->nlinvars--;
541 assert(pos == nlrow->nlinvars || nlrow->linvarssorted == FALSE);
542
543 SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, var, 0.0, nlp) );
544
545 return SCIP_OKAY;
546}
547
548/** changes a coefficient at given position of a nonlinear row */
549static
551 SCIP_NLROW* nlrow, /**< NLP row */
552 SCIP_SET* set, /**< global SCIP settings */
553 SCIP_STAT* stat, /**< problem statistics data */
554 SCIP_NLP* nlp, /**< current NLP data */
555 int pos, /**< position in row vector to change */
556 SCIP_Real coef /**< new value of coefficient */
557 )
558{
559 assert(nlrow != NULL);
560 assert(0 <= pos && pos < nlrow->nlinvars);
561 assert(nlrow->linvars != NULL);
562 assert(nlrow->linvars[pos] != NULL);
563
564 if( SCIPsetIsZero(set, coef) )
565 {
566 /* delete existing coefficient */
567 SCIP_CALL( nlrowDelLinearCoefPos(nlrow, set, stat, nlp, pos) );
568 }
569 else if( !SCIPsetIsEQ(set, nlrow->lincoefs[pos], coef) )
570 {
571 /* change existing coefficient */
572 nlrow->lincoefs[pos] = coef;
573 SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, nlrow->linvars[pos], coef, nlp) );
574 }
575
576 return SCIP_OKAY;
577}
578
579/** calculates minimal and maximal activity of row w.r.t. the variable's bounds */
580static
582 SCIP_NLROW* nlrow, /**< nonlinear row */
583 BMS_BLKMEM* blkmem, /**< block memory */
584 SCIP_SET* set, /**< global SCIP settings */
585 SCIP_STAT* stat /**< problem statistics data */
586 )
587{
588 SCIP_Real inf;
589 SCIP_INTERVAL activity;
590 SCIP_INTERVAL bounds;
591 int i;
592
593 assert(nlrow != NULL);
594 assert(set != NULL);
595 assert(stat != NULL);
596
597 inf = SCIPsetInfinity(set);
598
599 /* calculate activity bounds */
600 SCIPintervalSet(&activity, nlrow->constant);
601 for( i = 0; i < nlrow->nlinvars && !SCIPintervalIsEntire(inf, activity); ++i )
602 {
604 SCIPintervalMulScalar(inf, &bounds, bounds, nlrow->lincoefs[i]);
605 SCIPintervalAdd(inf, &activity, activity, bounds);
606 }
607
608 if( nlrow->expr != NULL && !SCIPintervalIsEntire(inf, activity) )
609 {
610 SCIP_CALL( SCIPexprEvalActivity(set, stat, blkmem, nlrow->expr) );
611 SCIPintervalAdd(inf, &activity, activity, SCIPexprGetActivity(nlrow->expr));
612 }
613
614 nlrow->minactivity = SCIPintervalGetInf(activity);
615 nlrow->maxactivity = SCIPintervalGetSup(activity);
616
617 nlrow->validactivitybdsdomchg = stat->domchgcount;
618
619 return SCIP_OKAY;
620}
621
622/** makes sure that there is no fixed variable at position pos of the linear part of a nonlinear row
623 *
624 * a fixed variable is replaced with the corresponding constant or disaggregated term
625 */
626static
628 SCIP_NLROW* nlrow, /**< nonlinear row */
629 BMS_BLKMEM* blkmem, /**< block memory */
630 SCIP_SET* set, /**< global SCIP settings */
631 SCIP_STAT* stat, /**< problem statistics data */
632 SCIP_NLP* nlp, /**< current NLP data */
633 int pos /**< position of variable in linear variables array */
634 )
635{
636 SCIP_Real oldconstant;
637 SCIP_VAR* var;
638
639 assert(nlrow != NULL);
640 assert(blkmem != NULL);
641 assert(pos >= 0);
642 assert(pos < nlrow->nlinvars);
643
644 var = nlrow->linvars[pos];
645
646 if( SCIPvarIsActive(var) )
647 return SCIP_OKAY;
648
649 oldconstant = nlrow->constant;
650
651 /* replace fixed, aggregated, or negated variable */
652 SCIP_CALL( SCIPvarGetProbvarSum( &nlrow->linvars[pos], set, &nlrow->lincoefs[pos], &nlrow->constant) );
653
654 /* if var had been fixed, entry should be removed from row */
655 if( nlrow->lincoefs[pos] == 0.0 )
656 {
657 nlrowMoveLinearCoef(nlrow, nlrow->nlinvars-1, pos);
658 nlrow->nlinvars--;
659
660 if( pos < nlrow->nlinvars )
661 {
662 SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, pos) );
663 }
664
665 return SCIP_OKAY;
666 }
667 nlrow->linvarssorted = FALSE;
668
669 /* notify nlrow that coefficient of var is now 0.0 in row */
670 SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, var, 0.0, nlp) );
671
672 /* notify nlrow that constant of row has changed */
673 if( oldconstant != nlrow->constant )
674 SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
675
676 if( SCIPvarIsActive(nlrow->linvars[pos]) )
677 {
678 /* if var was aggregated or negated, notify nlrow about new coefficient */
679 SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, nlrow->linvars[pos], nlrow->lincoefs[pos], nlp) );
680 }
681 else
682 {
683 SCIP_Real coef;
684 int i;
685
686 /* if not removed or active, the new variable should be multi-aggregated */
688
689 var = nlrow->linvars[pos];
690 coef = nlrow->lincoefs[pos];
691
692 /* remove the variable from the row */
693 SCIP_CALL( nlrowDelLinearCoefPos(nlrow, set, stat, nlp, pos) );
694
695 /* add multi-aggregated term to row */
696 if( SCIPvarGetMultaggrConstant(var) != 0.0 )
697 {
698 nlrow->constant += coef * SCIPvarGetMultaggrConstant(var);
699 SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
700 }
702 for( i = 0; i < SCIPvarGetMultaggrNVars(var); ++i )
703 {
705 continue;
706 SCIP_CALL( nlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, SCIPvarGetMultaggrVars(var)[i], coef * SCIPvarGetMultaggrScalars(var)[i]) );
707 assert(SCIPvarGetMultaggrVars(var)[i] == nlrow->linvars[nlrow->nlinvars-1]);
709 {
710 /* if newly added variable is fixed, replace it now */
711 SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, nlrow->nlinvars-1) );
712 }
713 }
714
715 /* due to nlrowDelLinearCoefPos, an inactive variable may have moved to position pos
716 * if that is the case, call ourself recursively
717 */
718 if( pos < nlrow->nlinvars && !SCIPvarIsActive(nlrow->linvars[pos]) )
719 {
720 SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, pos) );
721 }
722 }
723
724 return SCIP_OKAY;
725}
726
727/** removes fixed variables from the linear part of a nonlinear row */
728static
730 SCIP_NLROW* nlrow, /**< nonlinear row */
731 BMS_BLKMEM* blkmem, /**< block memory */
732 SCIP_SET* set, /**< global SCIP settings */
733 SCIP_STAT* stat, /**< problem statistics data */
734 SCIP_NLP* nlp /**< current NLP data */
735 )
736{
737 int i;
738 int oldlen;
739
740 assert(nlrow != NULL);
741 assert(nlrow->linvars != NULL || nlrow->nlinvars == 0);
742
743 oldlen = nlrow->nlinvars;
744 for( i = 0; i < MIN(oldlen, nlrow->nlinvars); ++i )
745 {
746 assert(nlrow->linvars[i] != NULL);
747 SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, i) );
748 }
749
750 return SCIP_OKAY;
751}
752
753/** removes fixed variables from expression of a nonlinear row */
754static
756 SCIP_NLROW* nlrow, /**< nonlinear row */
757 BMS_BLKMEM* blkmem, /**< block memory */
758 SCIP_SET* set, /**< global SCIP settings */
759 SCIP_STAT* stat, /**< problem statistics data */
760 SCIP_NLP* nlp /**< current NLP data */
761 )
762{
764 SCIP_Bool changed;
765 SCIP_Bool infeasible;
766
767 if( nlrow->expr == NULL )
768 return SCIP_OKAY;
769
770 SCIP_CALL( SCIPexprSimplify(set, stat, blkmem, nlrow->expr, &simplified, &changed, &infeasible, NULL, NULL) );
771 assert(!infeasible);
772
773 if( !changed )
774 {
775 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &simplified) );
776 return SCIP_OKAY;
777 }
778
779 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlrow->expr) );
780 nlrow->expr = simplified;
781
782 if( SCIPexprIsValue(set, nlrow->expr) )
783 {
784 /* if expression tree is constant, remove it */
785 SCIP_CALL( SCIPnlrowChgConstant(nlrow, set, stat, nlp, nlrow->constant + SCIPgetValueExprValue(nlrow->expr)) );
786
787 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlrow->expr) );
788 }
789
790 SCIP_CALL( nlrowExprChanged(nlrow, blkmem, set, stat, nlp) );
791
792 return SCIP_OKAY;
793}
794
795/** removes fixed variable from nonlinear row */
796static
798 SCIP_NLROW* nlrow, /**< nonlinear row */
799 BMS_BLKMEM* blkmem, /**< block memory */
800 SCIP_SET* set, /**< global SCIP settings */
801 SCIP_STAT* stat, /**< problem statistics data */
802 SCIP_NLP* nlp, /**< current NLP data */
803 SCIP_VAR* var /**< variable that had been fixed */
804 )
805{
806 int pos;
807
808 assert(nlrow != NULL);
809 assert(var != NULL);
811
812 /* search for variable in linear part and remove if existing */
813 pos = nlrowSearchLinearCoef(nlrow, var);
814 if( pos >= 0 )
815 {
816 SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, pos) );
817 }
818
819 /* search for variable in nonlinear part and remove all fixed variables in expression if existing
820 * TODO only call simplify if var appears in expr, but currently we don't store the vars in a separate array
821 */
822 if( nlrow->expr != NULL )
823 {
824 SCIP_CALL( nlrowSimplifyExpr(nlrow, blkmem, set, stat, nlp) );
825 }
826
827 return SCIP_OKAY;
828}
829
830/*
831 * public NLP nonlinear row methods
832 */
833/**@addtogroup PublicNLRowMethods
834 *
835 * @{
836 */
837
838/** create a new nonlinear row
839 *
840 * the new row is already captured
841 */
843 SCIP_NLROW** nlrow, /**< buffer to store pointer to nonlinear row */
844 BMS_BLKMEM* blkmem, /**< block memory */
845 SCIP_SET* set, /**< global SCIP settings */
846 SCIP_STAT* stat, /**< problem statistics data */
847 const char* name, /**< name of nonlinear row */
848 SCIP_Real constant, /**< constant */
849 int nlinvars, /**< number of linear variables */
850 SCIP_VAR** linvars, /**< linear variables, or NULL if nlinvars == 0 */
851 SCIP_Real* lincoefs, /**< linear coefficients, or NULL if nlinvars == 0 */
852 SCIP_EXPR* expr, /**< expression, or NULL */
853 SCIP_Real lhs, /**< left hand side */
854 SCIP_Real rhs, /**< right hand side */
855 SCIP_EXPRCURV curvature /**< curvature of the nonlinear row */
856 )
857{
858#ifndef NDEBUG
859 int i;
860#endif
861
862 assert(nlrow != NULL);
863 assert(blkmem != NULL);
864 assert(set != NULL);
865 assert(name != NULL);
866 assert(!SCIPsetIsInfinity(set, ABS(constant)));
867 assert(nlinvars == 0 || linvars != NULL);
868 assert(nlinvars == 0 || lincoefs != NULL);
869 assert(SCIPsetIsRelLE(set, lhs, rhs));
870
871 SCIP_ALLOC( BMSallocBlockMemory(blkmem, nlrow) );
872
873 /* constant part */
874 assert(!SCIPsetIsInfinity(set, REALABS(constant)));
875 (*nlrow)->constant = constant;
876
877#ifndef NDEBUG
878 for( i = 0; i < nlinvars; ++i )
879 {
880 assert(linvars[i] != NULL);
881 assert(!SCIPsetIsInfinity(set, REALABS(lincoefs[i])));
882 }
883#endif
884
885 /* linear part */
886 (*nlrow)->nlinvars = nlinvars;
887 (*nlrow)->linvarssize = nlinvars;
888 if( nlinvars > 0 )
889 {
890 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*nlrow)->linvars, linvars, nlinvars) );
891 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*nlrow)->lincoefs, lincoefs, nlinvars) );
892 (*nlrow)->linvarssorted = FALSE;
893 }
894 else
895 {
896 (*nlrow)->linvars = NULL;
897 (*nlrow)->lincoefs = NULL;
898 (*nlrow)->linvarssorted = TRUE;
899 }
900
901 /* nonlinear part */
902 if( expr != NULL )
903 {
904 /* TODO preserve common subexpressions, or at least use only one varexpr per var */
905 SCIP_CALL( SCIPexprCopy(set, stat, blkmem, set, stat, blkmem, expr, &(*nlrow)->expr, NULL, NULL, NULL, NULL) );
906 }
907 else
908 {
909 (*nlrow)->expr = NULL;
910 }
911
912 /* left and right hand sides, asserted above that lhs is relatively less equal than rhs */
913 (*nlrow)->lhs = MIN(lhs, rhs);
914 (*nlrow)->rhs = MAX(lhs, rhs);
915
916 /* miscellaneous */
917 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*nlrow)->name, name, strlen(name)+1) );
918 (*nlrow)->activity = SCIP_INVALID;
919 (*nlrow)->validactivitynlp = FALSE;
920 (*nlrow)->pseudoactivity = SCIP_INVALID;
921 (*nlrow)->validpsactivitydomchg = FALSE;
922 (*nlrow)->minactivity = SCIP_INVALID;
923 (*nlrow)->maxactivity = SCIP_INVALID;
924 (*nlrow)->validactivitybdsdomchg = FALSE;
925 (*nlrow)->nlpindex = -1;
926 (*nlrow)->nlpiindex = -1;
927 (*nlrow)->nuses = 0;
928 (*nlrow)->dualsol = 0.0;
929 (*nlrow)->curvature = curvature;
930
931 /* capture the nonlinear row */
932 SCIPnlrowCapture(*nlrow);
933
934 return SCIP_OKAY;
935}
936
937/** create a nonlinear row that is a copy of a given row
938 *
939 * the new row is already captured
940 */
942 SCIP_NLROW** nlrow, /**< buffer to store pointer to nonlinear row */
943 BMS_BLKMEM* blkmem, /**< block memory */
944 SCIP_SET* set, /**< global SCIP settings */
945 SCIP_STAT* stat, /**< problem statistics data */
946 SCIP_NLROW* sourcenlrow /**< nonlinear row to copy */
947 )
948{
949 assert(nlrow != NULL);
950 assert(blkmem != NULL);
951 assert(set != NULL);
953
954 SCIP_CALL( SCIPnlrowCreate(nlrow, blkmem, set, stat, sourcenlrow->name,
955 sourcenlrow->constant,
956 sourcenlrow->nlinvars, sourcenlrow->linvars, sourcenlrow->lincoefs,
957 sourcenlrow->expr,
958 sourcenlrow->lhs, sourcenlrow->rhs, sourcenlrow->curvature) );
959
960 (*nlrow)->linvarssorted = sourcenlrow->linvarssorted;
961 (*nlrow)->activity = sourcenlrow->activity;
962 (*nlrow)->validactivitynlp = sourcenlrow->validactivitynlp;
963 (*nlrow)->pseudoactivity = sourcenlrow->pseudoactivity;
964 (*nlrow)->validpsactivitydomchg = sourcenlrow->validpsactivitydomchg;
965 (*nlrow)->minactivity = sourcenlrow->minactivity;
966 (*nlrow)->maxactivity = sourcenlrow->maxactivity;
967 (*nlrow)->validactivitybdsdomchg = sourcenlrow->validactivitybdsdomchg;
968
969 return SCIP_OKAY;
970}
971
972/** create a new nonlinear row from a linear row
973 *
974 * the new row is already captured
975 */
977 SCIP_NLROW** nlrow, /**< buffer to store pointer to nonlinear row */
978 BMS_BLKMEM* blkmem, /**< block memory */
979 SCIP_SET* set, /**< global SCIP settings */
980 SCIP_STAT* stat, /**< problem statistics data */
981 SCIP_ROW* row /**< the linear row to copy */
982 )
983{
984 int rownz;
985
986 assert(nlrow != NULL);
987 assert(blkmem != NULL);
988 assert(set != NULL);
989 assert(row != NULL);
990
991 rownz = SCIProwGetNNonz(row);
992
993 if( rownz > 1 )
994 {
996 int i;
997
999
1000 for( i = 0; i < rownz; ++i )
1001 {
1003 assert(rowvars[i] != NULL);
1004 }
1005
1006 SCIP_CALL( SCIPnlrowCreate(nlrow, blkmem, set, stat, SCIProwGetName(row),
1007 SCIProwGetConstant(row),
1009 SCIProwGetLhs(row), SCIProwGetRhs(row),
1011
1013 }
1014 else if( rownz == 1 )
1015 {
1017
1019
1020 SCIP_CALL( SCIPnlrowCreate(nlrow, blkmem, set, stat, SCIProwGetName(row),
1021 SCIProwGetConstant(row),
1022 1, &rowvar, SCIProwGetVals(row), NULL,
1023 SCIProwGetLhs(row), SCIProwGetRhs(row),
1025 }
1026 else
1027 {
1028 SCIP_CALL( SCIPnlrowCreate(nlrow, blkmem, set, stat, SCIProwGetName(row),
1029 SCIProwGetConstant(row),
1030 0, NULL, NULL, NULL,
1031 SCIProwGetLhs(row), SCIProwGetRhs(row),
1033 }
1034
1035 return SCIP_OKAY;
1036}
1037
1038/** output nonlinear row to file stream */
1040 SCIP_NLROW* nlrow, /**< NLP row */
1041 BMS_BLKMEM* blkmem, /**< block memory */
1042 SCIP_SET* set, /**< global SCIP settings */
1043 SCIP_STAT* stat, /**< problem statistics data */
1044 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1045 FILE* file /**< output file (or NULL for standard output) */
1046 )
1047{
1048 int i;
1049
1050 assert(nlrow != NULL);
1051
1052 /* print row name */
1053 if( nlrow->name != NULL && nlrow->name[0] != '\0' )
1054 {
1055 SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", nlrow->name);
1056 }
1057
1058 /* print left hand side */
1059 SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", nlrow->lhs);
1060
1061 /* print constant */
1062 SCIPmessageFPrintInfo(messagehdlr, file, "%.15g ", nlrow->constant);
1063
1064 /* print linear coefficients */
1065 for( i = 0; i < nlrow->nlinvars; ++i )
1066 {
1067 assert(nlrow->linvars[i] != NULL);
1068 assert(SCIPvarGetName(nlrow->linvars[i]) != NULL);
1069 SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", nlrow->lincoefs[i], SCIPvarGetName(nlrow->linvars[i]));
1070 }
1071
1072 /* print nonlinear part */
1073 if( nlrow->expr != NULL )
1074 {
1075 SCIPmessageFPrintInfo(messagehdlr, file, " + ");
1076 SCIP_CALL( SCIPexprPrint(set, stat, blkmem, messagehdlr, file, nlrow->expr) );
1077 }
1078
1079 /* print right hand side */
1080 SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", nlrow->rhs);
1081
1082 return SCIP_OKAY;
1083}
1084
1085/** increases usage counter of nonlinear row */
1087 SCIP_NLROW* nlrow /**< nonlinear row to capture */
1088 )
1089{
1090 assert(nlrow != NULL);
1091 assert(nlrow->nuses >= 0);
1092
1093 SCIPdebugMessage("capture nonlinear row <%s> with nuses=%d\n", nlrow->name, nlrow->nuses);
1094 nlrow->nuses++;
1095}
1096
1097/** decreases usage counter of nonlinear row */
1099 SCIP_NLROW** nlrow, /**< nonlinear row to free */
1100 BMS_BLKMEM* blkmem, /**< block memory */
1101 SCIP_SET* set, /**< global SCIP settings */
1102 SCIP_STAT* stat /**< problem statistics data */
1103 )
1104{
1105 assert(blkmem != NULL);
1106 assert(nlrow != NULL);
1107 assert(*nlrow != NULL);
1108 assert((*nlrow)->nuses >= 1);
1109
1110 SCIPsetDebugMsg(set, "release nonlinear row <%s> with nuses=%d\n", (*nlrow)->name, (*nlrow)->nuses);
1111 (*nlrow)->nuses--;
1112 if( (*nlrow)->nuses > 0 )
1113 {
1114 *nlrow = NULL;
1115 return SCIP_OKAY;
1116 }
1117
1118 /* free row */
1119
1120 assert((*nlrow)->nuses == 0);
1121 assert((*nlrow)->nlpindex == -1);
1122 assert((*nlrow)->nlpiindex == -1);
1123
1124 /* linear part */
1125 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlrow)->linvars, (*nlrow)->linvarssize);
1126 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlrow)->lincoefs, (*nlrow)->linvarssize);
1127
1128 /* nonlinear part */
1129 if( (*nlrow)->expr != NULL )
1130 {
1131 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &(*nlrow)->expr) );
1132 }
1133
1134 /* miscellaneous */
1135 BMSfreeBlockMemoryArray(blkmem, &(*nlrow)->name, strlen((*nlrow)->name)+1);
1136
1137 BMSfreeBlockMemory(blkmem, nlrow);
1138
1139 return SCIP_OKAY;
1140}
1141
1142/** ensures, that linear coefficient array of nonlinear row can store at least num entries */
1144 SCIP_NLROW* nlrow, /**< NLP row */
1145 BMS_BLKMEM* blkmem, /**< block memory */
1146 SCIP_SET* set, /**< global SCIP settings */
1147 int num /**< minimum number of entries to store */
1148 )
1149{
1150 assert(nlrow != NULL);
1151 assert(nlrow->nlinvars <= nlrow->linvarssize);
1152
1153 if( num > nlrow->linvarssize )
1154 {
1155 int newsize;
1156
1160 nlrow->linvarssize = newsize;
1161 }
1162 assert(num <= nlrow->linvarssize);
1163
1164 return SCIP_OKAY;
1165}
1166
1167/** adds a previously non existing linear coefficient to a nonlinear row */
1169 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1170 BMS_BLKMEM* blkmem, /**< block memory */
1171 SCIP_SET* set, /**< global SCIP settings */
1172 SCIP_STAT* stat, /**< problem statistics data */
1173 SCIP_NLP* nlp, /**< current NLP data */
1174 SCIP_VAR* var, /**< variable */
1175 SCIP_Real val /**< value of coefficient */
1176 )
1177{
1178 /* if row is in NLP already, make sure that only active variables are added */
1179 if( nlrow->nlpindex >= 0 )
1180 {
1181 SCIP_Real constant;
1182
1183 /* get corresponding active or multi-aggregated variable */
1184 constant = 0.0;
1185 SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &val, &constant) );
1186
1187 /* add constant */
1188 SCIP_CALL( SCIPnlrowChgConstant(nlrow, set, stat, nlp, nlrow->constant + constant) );
1189
1190 if( val == 0.0 )
1191 /* var has been fixed */
1192 return SCIP_OKAY;
1193
1194 if( !SCIPvarIsActive(var) )
1195 {
1196 /* var should be multi-aggregated, so call this function recursively */
1197 int i;
1198
1200 for( i = 0; i < SCIPvarGetMultaggrNVars(var); ++i )
1201 {
1203 }
1204 return SCIP_OKAY;
1205 }
1206
1207 /* var is active, so can go on like normal */
1208 }
1209
1210 SCIP_CALL( nlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, var, val) );
1211
1212 return SCIP_OKAY;
1213}
1214
1215/** deletes linear coefficient from nonlinear row */
1217 SCIP_NLROW* nlrow, /**< nonlinear row to be changed */
1218 SCIP_SET* set, /**< global SCIP settings */
1219 SCIP_STAT* stat, /**< problem statistics data */
1220 SCIP_NLP* nlp, /**< current NLP data */
1221 SCIP_VAR* var /**< coefficient to be deleted */
1222 )
1223{
1224 int pos;
1225
1226 assert(nlrow != NULL);
1227 assert(var != NULL);
1228
1229 /* if the row is in the NLP already, we can only have active variables, so var should also be active; in non-debug mode, one gets an error below */
1230 assert(nlrow->nlpindex == -1 || SCIPvarIsActive(var) );
1231
1232 /* search the position of the variable in the row's variable vector */
1233 pos = nlrowSearchLinearCoef(nlrow, var);
1234 if( pos == -1 )
1235 {
1236 SCIPerrorMessage("coefficient for variable <%s> doesn't exist in nonlinear row <%s>\n", SCIPvarGetName(var), nlrow->name);
1237 return SCIP_INVALIDDATA;
1238 }
1239 assert(0 <= pos && pos < nlrow->nlinvars);
1240 assert(nlrow->linvars[pos] == var);
1241
1242 /* delete the variable from the row's variable vector */
1243 SCIP_CALL( nlrowDelLinearCoefPos(nlrow, set, stat, nlp, pos) );
1244
1245 return SCIP_OKAY;
1246}
1247
1248/** changes or adds a linear coefficient to a nonlinear row */
1250 SCIP_NLROW* nlrow, /**< nonlinear row */
1251 BMS_BLKMEM* blkmem, /**< block memory */
1252 SCIP_SET* set, /**< global SCIP settings */
1253 SCIP_STAT* stat, /**< problem statistics data */
1254 SCIP_NLP* nlp, /**< current NLP data */
1255 SCIP_VAR* var, /**< variable */
1256 SCIP_Real coef /**< new value of coefficient */
1257 )
1258{
1259 int pos;
1260
1261 assert(nlrow != NULL);
1262 assert(nlp != NULL);
1263 assert(var != NULL);
1264
1265 /* search the position of the variable in the row's linvars vector */
1266 pos = nlrowSearchLinearCoef(nlrow, var);
1267
1268 /* check, if column already exists in the row's linear variables vector */
1269 if( pos == -1 )
1270 {
1271 if( !SCIPsetIsZero(set, coef) )
1272 {
1273 /* add previously not existing coefficient */
1274 SCIP_CALL( nlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, var, coef) );
1275 }
1276 }
1277 else
1278 {
1279 /* change the coefficient in the row */
1280 SCIP_CALL( nlrowChgLinearCoefPos(nlrow, set, stat, nlp, pos, coef) );
1281 }
1282
1283 return SCIP_OKAY;
1284}
1285
1286/** replaces or deletes an expression in a nonlinear row */
1288 SCIP_NLROW* nlrow, /**< nonlinear row */
1289 BMS_BLKMEM* blkmem, /**< block memory */
1290 SCIP_SET* set, /**< global SCIP settings */
1291 SCIP_STAT* stat, /**< problem statistics data */
1292 SCIP_NLP* nlp, /**< current NLP data */
1293 SCIP_EXPR* expr /**< new expression */
1294 )
1295{
1296 assert(nlrow != NULL);
1297 assert(blkmem != NULL);
1298
1299 /* free previous expression tree */
1300 if( nlrow->expr != NULL )
1301 {
1302 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlrow->expr) );
1303 assert(nlrow->expr == NULL);
1304 }
1305
1306 /* adds new expression tree */
1307 if( expr != NULL )
1308 {
1309 /* TODO preserve common subexpressions, or at least use only one varexpr per var */
1310 SCIP_CALL( SCIPexprCopy(set, stat, blkmem, set, stat, blkmem, expr, &nlrow->expr, NULL, NULL, NULL, NULL) );
1311
1312 /* if row is already in NLP, ensure that expr has only active variables */
1313 if( nlrow->nlpindex >= 0 )
1314 {
1316 SCIP_Bool changed;
1317 SCIP_Bool infeasible;
1318
1319 SCIP_CALL( SCIPexprSimplify(set, stat, blkmem, nlrow->expr, &simplified, &changed, &infeasible, NULL, NULL) );
1320 assert(!infeasible);
1321
1322 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlrow->expr) );
1323 nlrow->expr = simplified;
1324 }
1325 }
1326
1327 /* notify row about the change */
1328 SCIP_CALL( nlrowExprChanged(nlrow, blkmem, set, stat, nlp) );
1329
1330 return SCIP_OKAY;
1331}
1332
1333/** changes constant of nonlinear row */
1335 SCIP_NLROW* nlrow, /**< nonlinear row */
1336 SCIP_SET* set, /**< global SCIP settings */
1337 SCIP_STAT* stat, /**< problem statistics data */
1338 SCIP_NLP* nlp, /**< current NLP data */
1339 SCIP_Real constant /**< new constant */
1340 )
1341{
1342 assert(nlrow != NULL);
1343
1344 if( !SCIPsetIsEQ(set, nlrow->constant, constant) )
1345 {
1346 nlrow->constant = constant;
1347 SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
1348 }
1349
1350 return SCIP_OKAY;
1351}
1352
1353/** changes left hand side of nonlinear row */
1355 SCIP_NLROW* nlrow, /**< nonlinear row */
1356 SCIP_SET* set, /**< global SCIP settings */
1357 SCIP_STAT* stat, /**< problem statistics data */
1358 SCIP_NLP* nlp, /**< current NLP data */
1359 SCIP_Real lhs /**< new left hand side */
1360 )
1361{
1362 assert(nlrow != NULL);
1363
1364 if( !SCIPsetIsEQ(set, nlrow->lhs, lhs) )
1365 {
1366 nlrow->lhs = lhs;
1367 SCIP_CALL( nlrowSideChanged(nlrow, set, stat, nlp) );
1368 }
1369
1370 return SCIP_OKAY;
1371}
1372
1373/** changes right hand side of nonlinear row */
1375 SCIP_NLROW* nlrow, /**< nonlinear row */
1376 SCIP_SET* set, /**< global SCIP settings */
1377 SCIP_STAT* stat, /**< problem statistics data */
1378 SCIP_NLP* nlp, /**< current NLP data */
1379 SCIP_Real rhs /**< new right hand side */
1380 )
1381{
1382 assert(nlrow != NULL);
1383
1384 if( !SCIPsetIsEQ(set, nlrow->rhs, rhs) )
1385 {
1386 nlrow->rhs = rhs;
1387 SCIP_CALL( nlrowSideChanged(nlrow, set, stat, nlp) );
1388 }
1389
1390 return SCIP_OKAY;
1391}
1392
1393/** removes (or substitutes) all fixed, negated, aggregated, multi-aggregated variables from the linear and nonlinear part of a nonlinear row and simplifies its expression */
1395 SCIP_NLROW* nlrow, /**< nonlinear row */
1396 BMS_BLKMEM* blkmem, /**< block memory */
1397 SCIP_SET* set, /**< global SCIP settings */
1398 SCIP_STAT* stat, /**< problem statistics data */
1399 SCIP_NLP* nlp /**< current NLP data */
1400 )
1401{
1402 SCIP_CALL( nlrowRemoveFixedLinearCoefs(nlrow, blkmem, set, stat, nlp) );
1403 SCIP_CALL( nlrowSimplifyExpr(nlrow, blkmem, set, stat, nlp) );
1404
1405 return SCIP_OKAY;
1406}
1407
1408/** recalculates the current activity of a nonlinear row in the current NLP solution */
1410 SCIP_NLROW* nlrow, /**< nonlinear row */
1411 BMS_BLKMEM* blkmem, /**< block memory */
1412 SCIP_SET* set, /**< global SCIP settings */
1413 SCIP_STAT* stat, /**< problem statistics data */
1414 SCIP_PRIMAL* primal, /**< primal data */
1415 SCIP_TREE* tree, /**< branch and bound tree */
1416 SCIP_NLP* nlp /**< current NLP data */
1417 )
1418{
1419 int i;
1420
1421 assert(nlrow != NULL);
1422 assert(stat != NULL);
1423 assert(nlp != NULL);
1424
1426 {
1427 SCIPerrorMessage("do not have NLP solution for computing NLP activity\n");
1428 return SCIP_ERROR;
1429 }
1430
1431 nlrow->activity = nlrow->constant;
1432 for( i = 0; i < nlrow->nlinvars; ++i )
1433 {
1434 assert(nlrow->linvars[i] != NULL);
1436
1437 nlrow->activity += nlrow->lincoefs[i] * SCIPvarGetNLPSol(nlrow->linvars[i]);
1438 }
1439
1440 if( nlrow->expr != NULL )
1441 {
1442 SCIP_SOL* sol;
1443
1444 SCIP_CALL( SCIPsolCreateNLPSol(&sol, blkmem, set, stat, primal, tree, nlp, NULL) );
1445
1446 SCIP_CALL( SCIPexprEval(set, stat, blkmem, nlrow->expr, sol, 0L) );
1447 if( SCIPexprGetEvalValue(nlrow->expr) == SCIP_INVALID )
1448 nlrow->activity = SCIP_INVALID;
1449 else
1450 nlrow->activity += SCIPexprGetEvalValue(nlrow->expr);
1451
1452 SCIP_CALL( SCIPsolFree(&sol, blkmem, primal) );
1453 }
1454
1455 nlrow->validactivitynlp = stat->nnlps;
1456
1457 return SCIP_OKAY;
1458}
1459
1460/** gives the activity of a nonlinear row in the current NLP solution */
1462 SCIP_NLROW* nlrow, /**< nonlinear row */
1463 BMS_BLKMEM* blkmem, /**< block memory */
1464 SCIP_SET* set, /**< global SCIP settings */
1465 SCIP_STAT* stat, /**< problem statistics data */
1466 SCIP_PRIMAL* primal, /**< primal data */
1467 SCIP_TREE* tree, /**< branch and bound tree */
1468 SCIP_NLP* nlp, /**< current NLP data */
1469 SCIP_Real* activity /**< buffer to store activity value */
1470 )
1471{
1472 assert(nlrow != NULL);
1473 assert(stat != NULL);
1474 assert(activity != NULL);
1475
1476 assert(nlrow->validactivitynlp <= stat->nnlps);
1477
1478 if( nlrow->validactivitynlp != stat->nnlps )
1479 {
1480 SCIP_CALL( SCIPnlrowRecalcNLPActivity(nlrow, blkmem, set, stat, primal, tree, nlp) );
1481 }
1482 assert(nlrow->validactivitynlp == stat->nnlps);
1483 assert(nlrow->activity < SCIP_INVALID);
1484
1485 *activity = nlrow->activity;
1486
1487 return SCIP_OKAY;
1488}
1489
1490/** gives the feasibility of a nonlinear row in the current NLP solution: negative value means infeasibility */
1492 SCIP_NLROW* nlrow, /**< nonlinear row */
1493 BMS_BLKMEM* blkmem, /**< block memory */
1494 SCIP_SET* set, /**< global SCIP settings */
1495 SCIP_STAT* stat, /**< problem statistics data */
1496 SCIP_PRIMAL* primal, /**< primal data */
1497 SCIP_TREE* tree, /**< branch and bound tree */
1498 SCIP_NLP* nlp, /**< current NLP data */
1499 SCIP_Real* feasibility /**< buffer to store feasibility value */
1500 )
1501{
1502 SCIP_Real activity;
1503
1504 assert(nlrow != NULL);
1506
1507 SCIP_CALL( SCIPnlrowGetNLPActivity(nlrow, blkmem, set, stat, primal, tree, nlp, &activity) );
1508 *feasibility = MIN(nlrow->rhs - activity, activity - nlrow->lhs);
1509
1510 return SCIP_OKAY;
1511}
1512
1513/** calculates the current pseudo activity of a nonlinear row */
1515 SCIP_NLROW* nlrow, /**< nonlinear row */
1516 BMS_BLKMEM* blkmem, /**< block memory */
1517 SCIP_SET* set, /**< global SCIP settings */
1518 SCIP_STAT* stat, /**< problem statistics data */
1519 SCIP_PROB* prob, /**< SCIP problem */
1520 SCIP_PRIMAL* primal, /**< primal data */
1521 SCIP_TREE* tree, /**< branch and bound tree */
1522 SCIP_LP* lp /**< SCIP LP */
1523 )
1524{
1525 SCIP_Real val1;
1526 int i;
1527
1528 assert(nlrow != NULL);
1529 assert(stat != NULL);
1530
1531 nlrow->pseudoactivity = nlrow->constant;
1532 for( i = 0; i < nlrow->nlinvars; ++i )
1533 {
1534 assert(nlrow->linvars[i] != NULL);
1535
1537 nlrow->pseudoactivity += nlrow->lincoefs[i] * val1;
1538 }
1539
1540 if( nlrow->expr != NULL )
1541 {
1542 SCIP_SOL* sol;
1543
1544 SCIP_CALL( SCIPsolCreatePseudoSol(&sol, blkmem, set, stat, prob, primal, tree, lp, NULL) );
1545
1546 SCIP_CALL( SCIPexprEval(set, stat, blkmem, nlrow->expr, sol, 0L) );
1547 if( SCIPexprGetEvalValue(nlrow->expr) == SCIP_INVALID )
1549 else
1550 nlrow->pseudoactivity += SCIPexprGetEvalValue(nlrow->expr);
1551
1552 SCIP_CALL( SCIPsolFree(&sol, blkmem, primal) );
1553 }
1554
1555 nlrow->validpsactivitydomchg = stat->domchgcount;
1556
1557 return SCIP_OKAY;
1558}
1559
1560/** returns the pseudo activity of a nonlinear row in the current pseudo solution */
1562 SCIP_NLROW* nlrow, /**< nonlinear row */
1563 BMS_BLKMEM* blkmem, /**< block memory */
1564 SCIP_SET* set, /**< global SCIP settings */
1565 SCIP_STAT* stat, /**< problem statistics data */
1566 SCIP_PROB* prob, /**< SCIP problem */
1567 SCIP_PRIMAL* primal, /**< primal data */
1568 SCIP_TREE* tree, /**< branch and bound tree */
1569 SCIP_LP* lp, /**< SCIP LP */
1570 SCIP_Real* pseudoactivity /**< buffer to store pseudo activity value */
1571 )
1572{
1573 assert(nlrow != NULL);
1574 assert(stat != NULL);
1575 assert(pseudoactivity != NULL);
1576 assert(nlrow->validpsactivitydomchg <= stat->domchgcount);
1577
1578 /* check, if pseudo activity has to be calculated */
1579 if( nlrow->validpsactivitydomchg != stat->domchgcount )
1580 {
1581 SCIP_CALL( SCIPnlrowRecalcPseudoActivity(nlrow, blkmem, set, stat, prob, primal, tree, lp) );
1582 }
1583 assert(nlrow->validpsactivitydomchg == stat->domchgcount);
1585
1586 *pseudoactivity = nlrow->pseudoactivity;
1587
1588 return SCIP_OKAY;
1589}
1590
1591/** returns the pseudo feasibility of a nonlinear row in the current pseudo solution: negative value means infeasibility */
1593 SCIP_NLROW* nlrow, /**< nonlinear row */
1594 BMS_BLKMEM* blkmem, /**< block memory */
1595 SCIP_SET* set, /**< global SCIP settings */
1596 SCIP_STAT* stat, /**< problem statistics data */
1597 SCIP_PROB* prob, /**< SCIP problem */
1598 SCIP_PRIMAL* primal, /**< primal data */
1599 SCIP_TREE* tree, /**< branch and bound tree */
1600 SCIP_LP* lp, /**< SCIP LP */
1601 SCIP_Real* pseudofeasibility /**< buffer to store pseudo feasibility value */
1602 )
1603{
1604 SCIP_Real pseudoactivity;
1605
1606 assert(nlrow != NULL);
1607 assert(stat != NULL);
1609
1610 SCIP_CALL( SCIPnlrowGetPseudoActivity(nlrow, blkmem, set, stat, prob, primal, tree, lp, &pseudoactivity) );
1611 *pseudofeasibility = MIN(nlrow->rhs - pseudoactivity, pseudoactivity - nlrow->lhs);
1612
1613 return SCIP_OKAY;
1614}
1615
1616/** returns the activity of a nonlinear row for a given solution */
1618 SCIP_NLROW* nlrow, /**< nonlinear row */
1619 BMS_BLKMEM* blkmem, /**< block memory */
1620 SCIP_SET* set, /**< global SCIP settings */
1621 SCIP_STAT* stat, /**< problem statistics data */
1622 SCIP_SOL* sol, /**< primal CIP solution */
1623 SCIP_Real* activity /**< buffer to store activity value */
1624 )
1625{
1626 SCIP_Real inf;
1627 SCIP_Real val1;
1628 int i;
1629
1630 assert(nlrow != NULL);
1631 assert(set != NULL);
1632 assert(stat != NULL);
1633 assert(activity != NULL);
1634
1635 *activity = nlrow->constant;
1636 for( i = 0; i < nlrow->nlinvars; ++i )
1637 {
1638 assert(nlrow->linvars[i] != NULL);
1639
1640 val1 = SCIPsolGetVal(sol, set, stat, nlrow->linvars[i]);
1641 if( val1 == SCIP_UNKNOWN )
1642 {
1643 *activity = SCIP_INVALID;
1644 return SCIP_OKAY;
1645 }
1646 *activity += nlrow->lincoefs[i] * val1;
1647 }
1648
1649 if( nlrow->expr != NULL )
1650 {
1651 SCIP_CALL( SCIPexprEval(set, stat, blkmem, nlrow->expr, sol, 0L) );
1652 if( SCIPexprGetEvalValue(nlrow->expr) == SCIP_INVALID )
1653 *activity = SCIP_INVALID;
1654 else
1655 *activity += SCIPexprGetEvalValue(nlrow->expr);
1656 }
1657
1658 inf = SCIPsetInfinity(set);
1659 *activity = MAX(*activity, -inf);
1660 *activity = MIN(*activity, +inf);
1661
1662 return SCIP_OKAY;
1663}
1664
1665/** returns the feasibility of a nonlinear row for the given solution */
1667 SCIP_NLROW* nlrow, /**< nonlinear row */
1668 BMS_BLKMEM* blkmem, /**< block memory */
1669 SCIP_SET* set, /**< global SCIP settings */
1670 SCIP_STAT* stat, /**< problem statistics data */
1671 SCIP_SOL* sol, /**< primal CIP solution */
1672 SCIP_Real* feasibility /**< buffer to store feasibility value */
1673 )
1674{
1675 SCIP_Real activity;
1676
1677 assert(nlrow != NULL);
1679
1680 SCIP_CALL( SCIPnlrowGetSolActivity(nlrow, blkmem, set, stat, sol, &activity) );
1681
1682 *feasibility = MIN(nlrow->rhs - activity, activity - nlrow->lhs);
1683
1684 return SCIP_OKAY;
1685}
1686
1687/** returns the minimal activity of a nonlinear row w.r.t. the variables' bounds */
1689 SCIP_NLROW* nlrow, /**< nonlinear row */
1690 BMS_BLKMEM* blkmem, /**< block memory */
1691 SCIP_SET* set, /**< global SCIP settings */
1692 SCIP_STAT* stat, /**< problem statistics data */
1693 SCIP_Real* minactivity, /**< buffer to store minimal activity, or NULL */
1694 SCIP_Real* maxactivity /**< buffer to store maximal activity, or NULL */
1695 )
1696{
1697 assert(nlrow != NULL);
1698 assert(set != NULL);
1699 assert(stat != NULL);
1700 assert(nlrow->validactivitybdsdomchg <= stat->domchgcount);
1701
1702 /* check, if activity bounds has to be calculated */
1703 if( nlrow->validactivitybdsdomchg != stat->domchgcount )
1704 {
1705 SCIP_CALL( nlrowCalcActivityBounds(nlrow, blkmem, set, stat) );
1706 }
1707 assert(nlrow->validactivitybdsdomchg == stat->domchgcount);
1710
1711 if( minactivity != NULL )
1712 *minactivity = nlrow->minactivity;
1713 if( maxactivity != NULL )
1714 *maxactivity = nlrow->maxactivity;
1715
1716 return SCIP_OKAY;
1717}
1718
1719/** returns whether the nonlinear row is redundant w.r.t. the variables' bounds */
1721 SCIP_NLROW* nlrow, /**< nonlinear row */
1722 BMS_BLKMEM* blkmem, /**< block memory */
1723 SCIP_SET* set, /**< global SCIP settings */
1724 SCIP_STAT* stat, /**< problem statistics data */
1725 SCIP_Bool* isredundant /**< buffer to store whether row is redundant */
1726 )
1727{
1728 SCIP_Real minactivity;
1729 SCIP_Real maxactivity;
1730
1731 assert(nlrow != NULL);
1732 assert(set != NULL);
1734
1735 SCIP_CALL( SCIPnlrowGetActivityBounds(nlrow, blkmem, set, stat, &minactivity, &maxactivity) );
1736
1737 *isredundant = TRUE;
1738 if( (!SCIPsetIsInfinity(set, -nlrow->lhs) && SCIPsetIsFeasLT(set, minactivity, nlrow->lhs)) ||
1739 ( !SCIPsetIsInfinity(set, nlrow->rhs) && SCIPsetIsFeasGT(set, maxactivity, nlrow->rhs)) )
1740 *isredundant = FALSE;
1741
1742 return SCIP_OKAY;
1743}
1744
1745#ifdef NDEBUG
1746/* Undo the defines from pub_nlhdlr.h, which exist if NDEBUG is defined. */
1747#undef SCIPnlrowGetConstant
1748#undef SCIPnlrowGetNLinearVars
1749#undef SCIPnlrowGetLinearVars
1750#undef SCIPnlrowGetLinearCoefs
1751#undef SCIPnlrowGetExpr
1752#undef SCIPnlrowGetLhs
1753#undef SCIPnlrowGetRhs
1754#undef SCIPnlrowGetCurvature
1755#undef SCIPnlrowSetCurvature
1756#undef SCIPnlrowGetName
1757#undef SCIPnlrowGetNLPPos
1758#undef SCIPnlrowIsInNLP
1759#undef SCIPnlrowGetDualsol
1760#endif
1761
1762/** gets constant */
1764 SCIP_NLROW* nlrow /**< NLP row */
1765 )
1766{
1767 assert(nlrow != NULL);
1768
1769 return nlrow->constant;
1770}
1771
1772/** gets number of variables of linear part */
1774 SCIP_NLROW* nlrow /**< NLP row */
1775 )
1776{
1777 assert(nlrow != NULL);
1778
1779 return nlrow->nlinvars;
1780}
1781
1782/** gets array with variables of linear part */
1784 SCIP_NLROW* nlrow /**< NLP row */
1785 )
1786{
1787 assert(nlrow != NULL);
1788
1789 return nlrow->linvars;
1790}
1791
1792/** gets array with coefficients in linear part */
1794 SCIP_NLROW* nlrow /**< NLP row */
1795 )
1796{
1797 assert(nlrow != NULL);
1798
1799 return nlrow->lincoefs;
1800}
1801
1802/** gets expression */
1804 SCIP_NLROW* nlrow /**< NLP row */
1805 )
1806{
1807 assert(nlrow != NULL);
1808
1809 return nlrow->expr;
1810}
1811
1812/** returns the left hand side of a nonlinear row */
1814 SCIP_NLROW* nlrow /**< NLP row */
1815 )
1816{
1817 assert(nlrow != NULL);
1818
1819 return nlrow->lhs;
1820}
1821
1822/** returns the right hand side of a nonlinear row */
1824 SCIP_NLROW* nlrow /**< NLP row */
1825 )
1826{
1827 assert(nlrow != NULL);
1828
1829 return nlrow->rhs;
1830}
1831
1832/** returns the curvature of a nonlinear row */
1834 SCIP_NLROW* nlrow /**< NLP row */
1835 )
1836{
1837 assert(nlrow != NULL);
1838 return nlrow->curvature;
1839}
1840
1841/** sets the curvature of a nonlinear row */
1843 SCIP_NLROW* nlrow, /**< NLP row */
1844 SCIP_EXPRCURV curvature /**< curvature of NLP row */
1845 )
1846{
1847 assert(nlrow != NULL);
1848 nlrow->curvature = curvature;
1849}
1850
1851/** returns the name of a nonlinear row */
1853 SCIP_NLROW* nlrow /**< NLP row */
1854 )
1855{
1856 assert(nlrow != NULL);
1857
1858 return nlrow->name;
1859}
1860
1861/** gets position of a nonlinear row in current NLP, or -1 if not in NLP */
1863 SCIP_NLROW* nlrow /**< NLP row */
1864 )
1865{
1866 assert(nlrow != NULL);
1867
1868 return nlrow->nlpindex;
1869}
1870
1871/** returns TRUE iff row is member of current NLP */
1873 SCIP_NLROW* nlrow /**< NLP row */
1874 )
1875{
1876 assert(nlrow != NULL);
1877
1878 return nlrow->nlpindex != -1;
1879}
1880
1881/** gets the dual NLP solution of a nlrow
1882 *
1883 * for a ranged constraint, the dual value is positive if the right hand side is active and negative if the left hand side is active
1884 */
1886 SCIP_NLROW* nlrow /**< NLP row */
1887 )
1888{
1889 assert(nlrow != NULL);
1890
1891 return nlrow->nlpiindex >= 0 ? nlrow->dualsol : 0.0;
1892}
1893
1894/** @} */
1895
1896/*
1897 * local NLP methods
1898 */
1899
1900/** announces, that a row of the NLP was modified
1901 * adjusts status of current solution
1902 * calling method has to ensure that change is passed to the NLPI!
1903 */ /*lint -e{715}*/
1904static
1906 SCIP_NLP* nlp, /**< current NLP data */
1907 SCIP_SET* set, /**< global SCIP settings */
1908 SCIP_STAT* stat, /**< problem statistics data */
1909 SCIP_NLROW* nlrow /**< nonlinear row which was changed */
1910 )
1911{ /*lint --e{715}*/
1912 assert(nlp != NULL);
1913 assert(nlrow != NULL);
1914 assert(!nlp->indiving);
1915 assert(nlrow->nlpindex >= 0);
1916
1917 /* nlrow is a row in the NLP, so changes effect feasibility */
1918 /* if we have a feasible NLP solution and it satisfies the modified row, then it is still feasible
1919 * if the NLP was globally or locally infeasible or unbounded, then this may not be the case anymore
1920 */
1921 if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
1922 {
1923 /* TODO bring this back? then everything that may call nlpRowChanged will need to pass on blkmem, primal, tree as well
1924 SCIP_Real feasibility;
1925 SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, blkmem, set, stat, primal, tree, nlp, &feasibility) );
1926 if( !SCIPsetIsFeasNegative(set, feasibility) )
1927 nlp->solstat = SCIP_NLPSOLSTAT_FEASIBLE;
1928 else */
1930 }
1931 else
1932 {
1934 }
1935
1936 return SCIP_OKAY;
1937}
1938
1939/** adds a set of nonlinear rows to the NLP and captures them */
1940static
1942 SCIP_NLP* nlp, /**< NLP data */
1943 BMS_BLKMEM* blkmem, /**< block memory */
1944 SCIP_SET* set, /**< global SCIP settings */
1945 SCIP_STAT* stat, /**< problem statistics data */
1946 int nnlrows, /**< number of nonlinear rows to add */
1947 SCIP_NLROW** nlrows /**< nonlinear rows to add */
1948 )
1949{
1950#ifndef NDEBUG
1951 int i;
1952#endif
1953 int j;
1954 SCIP_NLROW* nlrow;
1955
1956 assert(nlp != NULL);
1957 assert(blkmem != NULL);
1958 assert(set != NULL);
1959 assert(nlrows != NULL || nnlrows == 0);
1960 assert(!nlp->indiving);
1961
1962 SCIP_CALL( SCIPnlpEnsureNlRowsSize(nlp, blkmem, set, nlp->nnlrows + nnlrows) );
1963
1964 for( j = 0; j < nnlrows; ++j )
1965 {
1966 nlrow = nlrows[j]; /*lint !e613*/
1967
1968 /* assert that row is not in NLP (or even NLPI) yet */
1969 assert(nlrow->nlpindex == -1);
1970 assert(nlrow->nlpiindex == -1);
1971
1972 /* make sure there are only active variables in row */
1973 SCIP_CALL( SCIPnlrowSimplify(nlrow, blkmem, set, stat, nlp) );
1974
1975#ifndef NDEBUG
1976 /* assert that variables of row are in NLP */
1977 for( i = 0; i < nlrow->nlinvars; ++i )
1978 assert(SCIPhashmapExists(nlp->varhash, nlrow->linvars[i]));
1979
1980 if( nlrow->expr != NULL )
1981 {
1983 SCIP_EXPR* expr;
1984
1985 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
1987 for( expr = nlrow->expr; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
1990 }
1991#endif
1992
1993 /* add row to NLP and capture it */
1994 nlp->nlrows[nlp->nnlrows + j] = nlrow;
1995 nlrow->nlpindex = nlp->nnlrows + j;
1996
1997 SCIPnlrowCapture(nlrow);
1998
1999 /* if we have a feasible NLP solution and it satisfies the new solution, then it is still feasible
2000 * if the NLP was globally or locally infeasible, then it stays that way
2001 * if the NLP was unbounded, then this may not be the case anymore
2002 */
2003 if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2004 {
2005 /* TODO bring this back? then everything that may call nlpAddNlRows will need to pass on primal, tree as well
2006 SCIP_Real feasibility;
2007 SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, blkmem, set, stat, primal, tree, nlp, &feasibility) );
2008 if( !SCIPsetIsFeasNegative(set, feasibility) )
2009 nlp->solstat = SCIP_NLPSOLSTAT_FEASIBLE;
2010 else
2011 */
2013 }
2014 else if( nlp->solstat == SCIP_NLPSOLSTAT_UNBOUNDED )
2015 {
2017 }
2018 }
2019
2020 nlp->nnlrows += nnlrows;
2021 nlp->nunflushednlrowadd += nnlrows;
2022
2023 return SCIP_OKAY;
2024}
2025
2026/** moves a nonlinear row to a different place, and updates all corresponding data structures */
2027static
2029 SCIP_NLP* nlp, /**< NLP data structure */
2030 int oldpos, /**< old position of nonlinear row */
2031 int newpos /**< new position of nonlinear row */
2032 )
2033{
2034 assert(nlp != NULL);
2035 assert(0 <= oldpos && oldpos < nlp->nnlrows);
2036 assert(0 <= newpos && newpos < nlp->nnlrows);
2037 assert(nlp->nlrows[oldpos] != NULL);
2038
2039 if( oldpos == newpos )
2040 return;
2041
2042 nlp->nlrows[newpos] = nlp->nlrows[oldpos];
2043 nlp->nlrows[newpos]->nlpindex = newpos;
2044
2045 /* update nlpi to nlp row index mapping */
2046 if( nlp->nlrows[newpos]->nlpiindex >= 0 )
2047 {
2048 assert(nlp->nlrowmap_nlpi2nlp != NULL);
2051 }
2052}
2053
2054/** deletes nonlinear row with given position from NLP */
2055static
2057 SCIP_NLP* nlp, /**< NLP data structure */
2058 BMS_BLKMEM* blkmem, /**< block memory */
2059 SCIP_SET* set, /**< global SCIP settings */
2060 SCIP_STAT* stat, /**< problem statistics data */
2061 int pos /**< position of nonlinear row that is to be removed */
2062 )
2063{
2064 SCIP_NLROW* nlrow;
2065
2066 assert(nlp != NULL);
2067 assert(blkmem != NULL);
2068 assert(set != NULL);
2069 assert(pos >= 0);
2070 assert(pos < nlp->nnlrows);
2071 assert(!nlp->indiving);
2072 assert(nlp->nlrows != NULL);
2073
2074 nlrow = nlp->nlrows[pos];
2075 assert(nlrow != NULL);
2076 assert(nlrow->nlpindex == pos);
2077
2078 /* if row is in NLPI, then mark that it has to be removed in the next flush
2079 * if row was not in NLPI yet, then we have one unflushed nlrow addition less */
2080 if( nlrow->nlpiindex >= 0 )
2081 {
2082 assert(nlrow->nlpiindex < nlp->nnlrows_solver);
2083 nlp->nlrowmap_nlpi2nlp[nlrow->nlpiindex] = -1;
2084 nlrow->nlpiindex = -1;
2085 ++nlp->nunflushednlrowdel;
2086 }
2087 else
2088 {
2089 assert(nlrow->nlpiindex == -1);
2090 --nlp->nunflushednlrowadd;
2091 }
2092
2093 /* move NLP row from the end to pos and mark nlrow to be not in NLP anymore */
2094 nlpMoveNlrow(nlp, nlp->nnlrows-1, pos);
2095 nlrow->nlpindex = -1;
2096
2097 /* forget about restriction */
2098 SCIP_CALL( SCIPnlrowRelease(&nlrow, blkmem, set, stat) );
2099 --nlp->nnlrows;
2100
2101 if( nlp->solstat < SCIP_NLPSOLSTAT_LOCOPT )
2103 else if( nlp->solstat == SCIP_NLPSOLSTAT_GLOBINFEASIBLE )
2105
2106 return SCIP_OKAY; /*lint !e438*/
2107}
2108
2109/** updates bounds on a variable in the NLPI problem */
2110static
2112 SCIP_NLP* nlp, /**< NLP data */
2113 SCIP_SET* set, /**< global SCIP settings */
2114 SCIP_VAR* var, /**< variable which bounds have changed */
2115 SCIP_Bool tightened /**< whether the bound change was a bound tightening */
2116 )
2117{
2118 int pos;
2119 SCIP_Real lb;
2120 SCIP_Real ub;
2121
2122 assert(nlp != NULL);
2123 assert(var != NULL);
2125
2126 /* original variable bounds are ignored during diving
2127 * (all variable bounds are reset to their current value in exitDiving) */
2128 if( nlp->indiving )
2129 return SCIP_OKAY;
2130
2131 /* get position of variable in NLP */
2132 pos = SCIPhashmapGetImageInt(nlp->varhash, var);
2133
2134 /* if variable not in NLPI yet, nothing to do */
2135 if( nlp->varmap_nlp2nlpi[pos] == -1 )
2136 return SCIP_OKAY;
2137
2138 /* update bounds in NLPI problem */
2139 assert(nlp->solver != NULL);
2140 assert(nlp->problem != NULL);
2141
2142 pos = nlp->varmap_nlp2nlpi[pos];
2143 lb = SCIPvarGetLbLocal(var);
2144 ub = SCIPvarGetUbLocal(var);
2145 SCIP_CALL( SCIPnlpiChgVarBounds(set, nlp->solver, nlp->problem, 1, &pos, &lb, &ub) );
2146
2147 /* if we have a feasible NLP solution and it satisfies the new bounds, then it is still feasible
2148 * if the NLP was globally or locally infeasible and we tightened a bound, then it stays that way
2149 * if the NLP was unbounded and we tightened a bound, then this may not be the case anymore
2150 */
2151 if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2152 {
2153 if( !tightened ||
2157 else
2159 }
2160 else if( !tightened || nlp->solstat == SCIP_NLPSOLSTAT_UNBOUNDED )
2161 {
2163 }
2164
2165 return SCIP_OKAY;
2166}
2167
2168/** updates coefficient of a variable in the objective */
2169static
2171 SCIP_SET* set, /**< global SCIP settings */
2172 SCIP_NLP* nlp, /**< NLP data */
2173 SCIP_VAR* var /**< variable which bounds have changed */
2174 )
2175{
2176 int pos;
2177 int objidx;
2178 SCIP_Real coef;
2179
2180 assert(nlp != NULL);
2181 assert(var != NULL);
2183
2184 /* if the objective in the NLPI is not up to date, then we do not need to do something here */
2185 if( !nlp->objflushed )
2186 return SCIP_OKAY;
2187
2188 /* original objective is ignored during diving
2189 * we just need to remember that at end of diving we have to flush the objective */
2190 if( nlp->indiving )
2191 {
2192 nlp->objflushed = FALSE;
2193 return SCIP_OKAY;
2194 }
2195
2196 /* get position of variable in NLP and objective coefficient */
2197 pos = SCIPhashmapGetImageInt(nlp->varhash, var);
2198 assert(nlp->varmap_nlp2nlpi[pos] == -1 || nlp->solver != NULL);
2199
2200 /* actually we only need to remember flushing the objective if we also have an NLPI */
2201 if( nlp->solver == NULL )
2202 return SCIP_OKAY;
2203
2204 coef = SCIPvarGetObj(var);
2205
2206 /* if variable not in NLPI yet, then we only need to remember to update the objective after variable additions were flushed */
2207 if( nlp->varmap_nlp2nlpi[pos] == -1 && coef != 0.0 )
2208 {
2209 nlp->objflushed = FALSE;
2210
2211 return SCIP_OKAY;
2212 }
2213
2214 /* if we are here, then the objective in the NLPI is up to date,
2215 * we keep it this way by changing the coefficient of var in the NLPI problem objective */
2216 assert(nlp->solver != NULL);
2217 assert(nlp->problem != NULL);
2218
2219 pos = nlp->varmap_nlp2nlpi[pos];
2220 objidx = -1;
2221 SCIP_CALL( SCIPnlpiChgLinearCoefs(set, nlp->solver, nlp->problem, objidx, 1, &pos, &coef) );
2222
2223 /* if we had a solution and it was locally (or globally) optimal, then now we can only be sure that it is still feasible */
2226
2227 return SCIP_OKAY;
2228}
2229
2230/** adds new variables to the NLP */
2231static
2233 SCIP_NLP* nlp, /**< NLP data structure */
2234 BMS_BLKMEM* blkmem, /**< block memory */
2235 SCIP_SET* set, /**< global SCIP settings */
2236 int nvars, /**< number of variables to add */
2237 SCIP_VAR** vars /**< variable to add to NLP */
2238 )
2239{
2240 int i;
2241 SCIP_VAR* var;
2242
2243 assert(nlp != NULL);
2244 assert(blkmem != NULL);
2245 assert(set != NULL);
2246 assert(vars != NULL || nvars == 0);
2247 assert(!nlp->indiving || nvars == 0);
2248
2249 if( nvars == 0 )
2250 return SCIP_OKAY;
2251
2252 SCIP_CALL( SCIPnlpEnsureVarsSize(nlp, blkmem, set, nlp->nvars + nvars) );
2253 assert(nlp->sizevars >= nlp->nvars + nvars);
2254
2255 for( i = 0; i < nvars; ++i )
2256 {
2257 var = vars[i]; /*lint !e613*/
2258
2262
2264
2265 nlp->vars[nlp->nvars+i] = var;
2266 nlp->varmap_nlp2nlpi[nlp->nvars+i] = -1;
2268
2269 nlp->varlbdualvals[nlp->nvars+i] = 0.0;
2270 nlp->varubdualvals[nlp->nvars+i] = 0.0;
2271
2272 /* update objective, if necessary (new variables have coefficient 0.0 anyway) */
2273 if( SCIPvarGetObj(var) != 0.0 )
2274 {
2276 }
2277
2278 /* let's keep the previous initial guess and set it for the new variable to the best bound
2279 * (since there can be no row that uses this variable yet, this seems a good guess) */
2280 if( nlp->haveinitguess )
2281 {
2282 assert(nlp->initialguess != NULL);
2283
2285 }
2286
2287 /* if we have a feasible NLP solution, then it remains feasible
2288 * but we have to update the objective function
2289 */
2290 if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2291 {
2295 }
2296
2297 /* catch events on variable */
2298 SCIP_CALL( SCIPvarCatchEvent(var, blkmem, set, \
2300 nlp->eventhdlr, (SCIP_EVENTDATA*)nlp, NULL) ); /* @todo should store event filter position in nlp? */
2301 }
2302
2303 nlp->nvars += nvars;
2304 nlp->nunflushedvaradd += nvars;
2305
2306 return SCIP_OKAY;
2307}
2308
2309/** moves a variable to a different place, and updates all corresponding data structures */
2310static
2312 SCIP_NLP* nlp, /**< NLP data structure */
2313 int oldpos, /**< old position of variable */
2314 int newpos /**< new position of variable */
2315 )
2316{
2317 int nlpipos;
2318
2319 assert(nlp != NULL);
2322 assert(nlp->vars[oldpos] != NULL);
2323
2324 if( oldpos == newpos )
2325 return SCIP_OKAY;
2326
2328 nlp->vars[newpos] = nlp->vars[oldpos];
2332 if( nlp->initialguess != NULL )
2333 nlp->initialguess[newpos] = nlp->initialguess[oldpos];
2334
2336 if( nlpipos > 0 )
2338
2339 return SCIP_OKAY;
2340}
2341
2342/** deletes variable with given position from NLP */
2343static
2345 SCIP_NLP* nlp, /**< NLP data structure */
2346 BMS_BLKMEM* blkmem, /**< block memory */
2347 SCIP_SET* set, /**< global SCIP settings */
2348 SCIP_STAT* stat, /**< problem statistics data */
2349 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2350 SCIP_LP* lp, /**< SCIP LP, needed if a column-variable is freed */
2351 int pos /**< position of nonlinear row that is to be removed */
2352 )
2353{
2354 SCIP_VAR* var;
2355#ifndef NDEBUG
2356 int i;
2357#endif
2358 int nlpipos;
2359
2360 assert(nlp != NULL);
2361 assert(blkmem != NULL);
2362 assert(set != NULL);
2363 assert(pos >= 0);
2365 assert(!nlp->indiving);
2366
2367 var = nlp->vars[pos];
2368 assert(var != NULL);
2369
2370#ifndef NDEBUG
2371 /* assert that variable is not used by any nonlinear row */
2372 for( i = 0; i < nlp->nnlrows; ++i )
2373 {
2374 int j;
2375 SCIP_NLROW* nlrow;
2376
2377 nlrow = nlp->nlrows[i];
2378 assert(nlrow != NULL);
2379
2380 /* use nlrowSearchLinearCoef only if already sorted, since otherwise we may change the solving process slightly */
2381 if( nlrow->linvarssorted )
2382 assert( nlrowSearchLinearCoef(nlrow, var) == -1 );
2383 else
2384 for( j = 0; j < nlrow->nlinvars; ++j )
2385 assert( nlrow->linvars[j] != var );
2386
2387 if( nlrow->expr != NULL )
2388 {
2390 SCIP_EXPR* expr;
2391 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2393 for( expr = nlrow->expr; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2394 assert(!SCIPexprIsVar(set, expr) || SCIPgetVarExprVar(expr) != var);
2396 }
2397 }
2398#endif
2399
2400 /* if we had a feasible solution, then adjust objective function value
2401 * if NLP was unbounded before, then maybe it is not anymore */
2402 if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2404 else if( nlp->solstat == SCIP_NLPSOLSTAT_UNBOUNDED )
2406
2407 /* if variable is in NLPI problem, mark that we have to remember to delete it there
2408 * if it was not in the NLPI yet, then we have one unflushed var addition less now */
2409 nlpipos = nlp->varmap_nlp2nlpi[pos];
2410 if( nlpipos >= 0 )
2411 {
2412 assert(nlpipos < nlp->nvars_solver);
2413
2414 nlp->varmap_nlpi2nlp[nlpipos] = -1;
2415 ++nlp->nunflushedvardel;
2416 }
2417 else
2418 --nlp->nunflushedvaradd;
2419
2420 /* drop events on variable */
2421 SCIP_CALL( SCIPvarDropEvent(var, blkmem, set, \
2423 nlp->eventhdlr, (SCIP_EVENTDATA*)nlp, -1) );
2424
2425 /* move variable from end to pos */
2426 SCIP_CALL( nlpMoveVar(nlp, nlp->nvars-1, pos) );
2427
2428 /* forget about variable */
2430 SCIP_CALL( SCIPvarRelease(&var, blkmem, set, eventqueue, lp) );
2431 --nlp->nvars;
2432
2433 return SCIP_OKAY;
2434}
2435
2436/** notifies NLP that a variable was fixed, so it is removed from objective, all rows, and the NLP variables */
2437static
2439 SCIP_NLP* nlp, /**< NLP data */
2440 BMS_BLKMEM* blkmem, /**< block memory */
2441 SCIP_SET* set, /**< global SCIP settings */
2442 SCIP_STAT* stat, /**< problem statistics data */
2443 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2444 SCIP_LP* lp, /**< SCIP LP, needed to release variable */
2445 SCIP_VAR* var /**< variable that has been fixed */
2446 )
2447{
2448 int i;
2449
2450 assert(nlp != NULL);
2451 assert(var != NULL);
2453 assert(!nlp->indiving);
2455
2456 /* remove var from all rows */
2457 for( i = 0; i < nlp->nnlrows; ++i )
2458 {
2459 SCIP_CALL( nlrowRemoveFixedVar(nlp->nlrows[i], blkmem, set, stat, nlp, var) );
2460 }
2461
2462 /* remove variable from NLP */
2463 SCIP_CALL( SCIPnlpDelVar(nlp, blkmem, set, stat, eventqueue, lp, var) );
2464
2465 return SCIP_OKAY;
2466}
2467
2468/** creates arrays with NLPI variable indices of linear variables in a nonlinear row */
2469static
2471 SCIP_NLP* nlp, /**< NLP data */
2472 SCIP_SET* set, /**< global SCIP settings */
2473 SCIP_NLROW* nlrow, /**< nonlinear row */
2474 int** linidxs /**< buffer to store pointer to NLPI indices of linear variables */
2475 )
2476{
2477 int i;
2478 SCIP_VAR* var;
2479
2480 assert(nlp != NULL);
2481 assert(set != NULL);
2482 assert(nlrow != NULL);
2483 assert(linidxs != NULL);
2484
2485 /* get indices of variables in linear part of row */
2486 if( nlrow->nlinvars > 0 )
2487 {
2488 assert(nlrow->linvars != NULL);
2489 assert(nlrow->lincoefs != NULL);
2490
2491 SCIP_CALL( SCIPsetAllocBufferArray(set, linidxs, nlrow->nlinvars) );
2492
2493 for( i = 0; i < nlrow->nlinvars; ++i )
2494 {
2495 var = nlrow->linvars[i];
2496 assert(var != NULL);
2497 assert(SCIPvarIsActive(var)); /* at this point, there should be only active variables in the row */
2498
2500 (*linidxs)[i] = nlp->varmap_nlp2nlpi[SCIPhashmapGetImageInt(nlp->varhash, var)];
2501 assert((*linidxs)[i] >= 0);
2502 }
2503 }
2504 else
2505 *linidxs = NULL;
2506
2507 return SCIP_OKAY;
2508}
2509
2510/** ensures, that NLPI variables array of NLP can store at least num entries */
2511static
2513 SCIP_NLP* nlp, /**< NLP data */
2514 BMS_BLKMEM* blkmem, /**< block memory */
2515 SCIP_SET* set, /**< global SCIP settings */
2516 int num /**< minimum number of entries to store */
2517 )
2518{
2519 assert(nlp != NULL);
2520 assert(blkmem != NULL);
2521 assert(set != NULL);
2522 assert(nlp->nvars_solver <= nlp->sizevars_solver);
2523
2524 if( num > nlp->sizevars_solver )
2525 {
2526 int newsize;
2527
2530
2531 nlp->sizevars_solver = newsize;
2532 }
2533 assert(num <= nlp->sizevars_solver);
2534
2535 return SCIP_OKAY;
2536}
2537
2538/** ensures, that NLPI nonlinear rows array of NLP can store at least num entries */
2539static
2541 SCIP_NLP* nlp, /**< NLP data */
2542 BMS_BLKMEM* blkmem, /**< block memory */
2543 SCIP_SET* set, /**< global SCIP settings */
2544 int num /**< minimum number of entries to store */
2545 )
2546{
2547 assert(nlp != NULL);
2548 assert(blkmem != NULL);
2549 assert(set != NULL);
2551
2552 if( num > nlp->sizenlrows_solver )
2553 {
2554 int newsize;
2555
2558
2560 }
2561 assert(num <= nlp->sizenlrows_solver);
2562
2563 return SCIP_OKAY;
2564}
2565
2566/** deletes rows from the NLPI problem that have been marked as to remove */
2567static
2569 SCIP_NLP* nlp, /**< NLP data */
2570 BMS_BLKMEM* blkmem, /**< block memory */
2571 SCIP_SET* set /**< global SCIP settings */
2572 )
2573{
2574 int j;
2575 int c; /* counts the number of rows to delete */
2576 int* rowset; /* marks which rows to delete and stores new indices */
2577 SCIP_NLROW* nlrow;
2578
2579 assert(nlp != NULL);
2580 assert(blkmem != NULL);
2581 assert(set != NULL);
2582 assert(nlp->nunflushednlrowdel >= 0);
2583 assert(!nlp->indiving);
2584
2585 if( nlp->nunflushednlrowdel == 0 )
2586 {
2587#ifndef NDEBUG
2588 /* check that there are really no pending removals of nonlinear rows */
2589 for( j = 0; j < nlp->nnlrows_solver; ++j )
2590 assert(nlp->nlrowmap_nlpi2nlp[j] >= 0);
2591#endif
2592 return SCIP_OKAY;
2593 }
2594
2595 assert(nlp->solver != NULL);
2596 assert(nlp->problem != NULL);
2597
2598 /* create marker which rows have to be deleted */
2600 c = 0;
2601 for( j = 0; j < nlp->nnlrows_solver; ++j )
2602 {
2603 if( nlp->nlrowmap_nlpi2nlp[j] == -1 )
2604 {
2605 rowset[j] = 1;
2606 ++c;
2607 }
2608 else
2609 rowset[j] = 0;
2610 }
2611 assert(c == nlp->nunflushednlrowdel);
2612
2613 /* remove rows from NLPI problem */
2615
2616 /* update NLPI row indices */
2617 for( j = 0; j < nlp->nnlrows_solver; ++j )
2618 {
2619 assert(rowset[j] <= j); /* we assume that the NLP solver did not move a row behind its previous position!! */
2620 if( rowset[j] < 0 )
2621 {
2622 /* assert that row was marked as deleted */
2623 assert(nlp->nlrowmap_nlpi2nlp[j] == -1);
2624 }
2625 else if( rowset[j] < j )
2626 {
2627 /* nlrow at position j moved (forward) to position rowset[j] */
2628 assert(nlp->nlrowmap_nlpi2nlp[j] >= 0);
2629 assert(nlp->nlrowmap_nlpi2nlp[j] < nlp->nnlrows);
2630
2631 nlrow = nlp->nlrows[nlp->nlrowmap_nlpi2nlp[j]];
2632 assert(nlrow->nlpiindex == j);
2633
2634 /* there should be no row at the new position already */
2635 assert(nlp->nlrowmap_nlpi2nlp[rowset[j]] == -1);
2636
2637 nlrow->nlpiindex = rowset[j];
2638 nlp->nlrowmap_nlpi2nlp[rowset[j]] = nlrow->nlpindex;
2639 }
2640 else
2641 {
2642 /* row j stays at position j */
2643 assert(nlp->nlrowmap_nlpi2nlp[j] >= 0);
2644 assert(nlp->nlrowmap_nlpi2nlp[j] < nlp->nnlrows);
2645 assert(nlp->nlrows[nlp->nlrowmap_nlpi2nlp[j]]->nlpiindex == j);
2646 }
2647 }
2648 nlp->nnlrows_solver -= c;
2649 nlp->nunflushednlrowdel = 0;
2650
2651 /* cleanup */
2653
2654 return SCIP_OKAY;
2655}
2656
2657/** deletes variables from the NLPI problem that have been marked as to remove
2658 *
2659 * assumes that there are no pending row deletions (nlpFlushNlRowDeletions() should be called first)
2660 */
2661static
2663 SCIP_NLP* nlp, /**< NLP data */
2664 BMS_BLKMEM* blkmem, /**< block memory */
2665 SCIP_SET* set /**< global SCIP settings */
2666 )
2667{
2668 int i;
2669 int c; /* counter on number of variables to remove in solver */
2670 int* colset; /* marks which variables to delete and stores new indices */
2671
2672 assert(nlp != NULL);
2673 assert(blkmem != NULL);
2674 assert(set != NULL);
2675 assert(nlp->nunflushedvardel >= 0);
2676 assert(nlp->nunflushednlrowdel == 0);
2677 assert(!nlp->indiving);
2678
2679 if( nlp->nunflushedvardel == 0 )
2680 {
2681#ifndef NDEBUG
2682 /* check that there are really no pending removals of variables */
2683 for( i = 0; i < nlp->nvars_solver; ++i )
2684 assert(nlp->varmap_nlpi2nlp[i] >= 0);
2685#endif
2686 return SCIP_OKAY;
2687 }
2688
2689 assert(nlp->solver != NULL);
2690 assert(nlp->problem != NULL);
2691
2692 /* create marker which variables have to be deleted */
2694 c = 0;
2695 for( i = 0; i < nlp->nvars_solver; ++i )
2696 {
2697 if( nlp->varmap_nlpi2nlp[i] == -1 )
2698 {
2699 colset[i] = 1;
2700 ++c;
2701 }
2702 else
2703 colset[i] = 0;
2704 }
2705 assert(c == nlp->nunflushedvardel);
2706
2707 /* delete variables from NLPI problem */
2709
2710 /* update NLPI variable indices */
2711 for( i = 0; i < nlp->nvars_solver; ++i )
2712 {
2713 assert(colset[i] <= i); /* we assume that the NLP solver did not move a variable behind its previous position!! */
2714 if( colset[i] < 0 )
2715 {
2716 /* assert that variable was marked as deleted */
2717 assert(nlp->varmap_nlpi2nlp[i] == -1);
2718 }
2719 else if( colset[i] < i)
2720 {
2721 /* variable at position i moved (forward) to position colset[i] */
2722 int varpos;
2723
2724 varpos = nlp->varmap_nlpi2nlp[i]; /* position of variable i in NLP */
2725 assert(varpos >= 0);
2727 assert(nlp->varmap_nlp2nlpi[varpos] == i);
2728
2729 /* there should be no variable at the new position already */
2730 assert(nlp->varmap_nlpi2nlp[colset[i]] == -1);
2731
2732 nlp->varmap_nlp2nlpi[varpos] = colset[i];
2733 nlp->varmap_nlpi2nlp[colset[i]] = varpos;
2734 }
2735 else
2736 {
2737 /* variable i stays at position i */
2738 assert(nlp->varmap_nlpi2nlp[i] >= 0);
2739 assert(nlp->varmap_nlpi2nlp[i] < nlp->nvars);
2740 assert(nlp->varmap_nlp2nlpi[nlp->varmap_nlpi2nlp[i]] == i);
2741 }
2742 }
2743
2744 nlp->nvars_solver -= c;
2745 nlp->nunflushedvardel = 0;
2746
2747 /* cleanup */
2749
2750 return SCIP_OKAY;
2751}
2752
2753/** adds nonlinear rows to NLPI problem that have been added to NLP before
2754 *
2755 * assumes that there are no pending variable additions or deletions (nlpFlushVarDeletions() and nlpFlushVarAdditions() should be called first)
2756 */
2757static
2759 SCIP_NLP* nlp, /**< NLP data */
2760 BMS_BLKMEM* blkmem, /**< block memory */
2761 SCIP_SET* set, /**< global SCIP settings */
2762 SCIP_STAT* stat /**< problem statistics */
2763 )
2764{
2765 int c, i;
2766 SCIP_NLROW* nlrow;
2767 SCIP_Real* lhss;
2768 SCIP_Real* rhss;
2769 int* nlinvars;
2770 int** linidxs;
2771 SCIP_Real** lincoefs;
2772 SCIP_EXPR** exprs;
2773 const char** names;
2774
2775 assert(nlp != NULL);
2776 assert(blkmem != NULL);
2777 assert(set != NULL);
2778 assert(nlp->nunflushednlrowadd >= 0);
2779 assert(nlp->nunflushedvaradd == 0);
2780 assert(nlp->nunflushedvardel == 0);
2781 assert(!nlp->indiving);
2782
2783 if( nlp->nunflushednlrowadd == 0 )
2784 {
2785#ifndef NDEBUG
2786 /* check that there are really no pending additions of variables */
2787 for( i = 0; i < nlp->nnlrows; ++i )
2788 assert(nlp->nlrows[i]->nlpiindex >= 0);
2789#endif
2790 return SCIP_OKAY;
2791 }
2792
2793 assert(nlp->solver != NULL);
2794 assert(nlp->problem != NULL);
2795
2797
2804#if ADDNAMESTONLPI
2806#else
2807 names = NULL;
2808#endif
2809
2810 c = 0;
2811 for( i = 0; i < nlp->nnlrows; ++i )
2812 {
2813 nlrow = nlp->nlrows[i];
2814 assert(nlrow != NULL);
2815
2816 /* skip nonlinear rows already in NLPI problem */
2817 if( nlrow->nlpiindex >= 0 )
2818 continue;
2819 assert(c < nlp->nunflushednlrowadd);
2820
2821 /* get indices in NLPI */
2822 SCIP_CALL( nlpSetupNlpiIndices(nlp, set, nlrow, &linidxs[c]) );
2823 assert(linidxs[c] != NULL || nlrow->nlinvars == 0);
2824
2825 nlp->nlrowmap_nlpi2nlp[nlp->nnlrows_solver+c] = i;
2826 nlrow->nlpiindex = nlp->nnlrows_solver+c;
2827
2828 lhss[c] = nlrow->lhs;
2829 rhss[c] = nlrow->rhs;
2830 if( nlrow->constant != 0.0 )
2831 {
2832 if( !SCIPsetIsInfinity(set, -nlrow->lhs) )
2833 lhss[c] -= nlrow->constant;
2834 if( !SCIPsetIsInfinity(set, nlrow->rhs) )
2835 rhss[c] -= nlrow->constant;
2836 }
2837 if( rhss[c] < lhss[c] )
2838 {
2840 rhss[c] = lhss[c];
2841 }
2842
2843 nlinvars[c] = nlrow->nlinvars;
2844 lincoefs[c] = nlrow->lincoefs;
2845
2846 if( nlrow->expr != NULL )
2847 {
2848 /* create copy of expr that uses varidx expressions corresponding to variables indices in NLPI */
2849 SCIP_CALL( SCIPexprCopy(set, stat, blkmem, set, stat, blkmem, nlrow->expr, &exprs[c], mapvar2varidx, (void*)nlp, NULL, NULL) );
2850 }
2851 else
2852 exprs[c] = NULL;
2853
2854#if ADDNAMESTONLPI
2855 names[c] = nlrow->name;
2856#endif
2857
2858 ++c;
2859
2860#ifdef NDEBUG
2861 /* have c vars to add already, there can be no more */
2862 if( c == nlp->nunflushednlrowadd )
2863 break;
2864#endif
2865 }
2866 assert(c == nlp->nunflushednlrowadd);
2867
2868 nlp->nnlrows_solver += c;
2869
2871 nlinvars, linidxs, lincoefs,
2872 exprs,
2873 names) );
2874
2875 for( c = nlp->nunflushednlrowadd - 1; c >= 0 ; --c )
2876 {
2877 if( linidxs[c] != NULL )
2878 SCIPsetFreeBufferArray(set, &linidxs[c]);
2879 if( exprs[c] != NULL )
2880 {
2881 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &exprs[c]) );
2882 }
2883 }
2884
2885#if ADDNAMESTONLPI
2887#endif
2888 SCIPsetFreeBufferArray(set, &exprs);
2889 SCIPsetFreeBufferArray(set, &lincoefs);
2890 SCIPsetFreeBufferArray(set, &linidxs);
2891 SCIPsetFreeBufferArray(set, &nlinvars);
2894
2895 nlp->nunflushednlrowadd = 0;
2896
2897 return SCIP_OKAY;
2898}
2899
2900
2901/** adds variables to NLPI problem that have been added to NLP before
2902 *
2903 * may set nlp->objflushed to FALSE if a variable with nonzero objective coefficient is added to the NLPI problem
2904 */
2905static
2907 SCIP_NLP* nlp, /**< NLP data */
2908 BMS_BLKMEM* blkmem, /**< block memory */
2909 SCIP_SET* set /**< global SCIP settings */
2910 )
2911{
2912 int i, c;
2913 SCIP_Real* lbs;
2914 SCIP_Real* ubs;
2915 const char** names;
2916
2917 assert(nlp != NULL);
2918 assert(blkmem != NULL);
2919 assert(set != NULL);
2920 assert(nlp->nunflushedvaradd >= 0);
2921 assert(!nlp->indiving);
2922
2923 if( nlp->nunflushedvaradd == 0 )
2924 {
2925#ifndef NDEBUG
2926 /* check that there are really no pending additions of variables */
2927 for( i = 0; i < nlp->nvars; ++i )
2928 assert(nlp->varmap_nlp2nlpi[i] >= 0);
2929#endif
2930 return SCIP_OKAY;
2931 }
2932
2933 assert(nlp->solver != NULL);
2934 assert(nlp->problem != NULL);
2935
2937
2940#if ADDNAMESTONLPI
2942#else
2943 names = NULL;
2944#endif
2945
2946 c = 0;
2947 for( i = 0; i < nlp->nvars; ++i )
2948 {
2949 /* skip variables already in NLPI problem */
2950 if( nlp->varmap_nlp2nlpi[i] >= 0 )
2951 continue;
2952 assert(c < nlp->nunflushedvaradd);
2953
2954 nlp->varmap_nlpi2nlp[nlp->nvars_solver+c] = i;
2955 nlp->varmap_nlp2nlpi[i] = nlp->nvars_solver+c;
2956 lbs[c] = SCIPvarGetLbLocal(nlp->vars[i]);
2957 ubs[c] = SCIPvarGetUbLocal(nlp->vars[i]);
2958#if ADDNAMESTONLPI
2959 names[c] = SCIPvarGetName(nlp->vars[i]);
2960#endif
2961 ++c;
2962
2963 /* if the new variable has a nonzero objective coefficient, then the objective need to be updated */
2964 if( !SCIPsetIsZero(set, SCIPvarGetObj(nlp->vars[i])) )
2965 nlp->objflushed = FALSE;
2966
2967#ifdef NDEBUG
2968 /* have c vars to add already, there can be no more */
2969 if( c == nlp->nunflushedvaradd )
2970 break;
2971#endif
2972 }
2973 assert(c == nlp->nunflushedvaradd);
2974
2975 nlp->nvars_solver += c;
2976
2977 SCIP_CALL( SCIPnlpiAddVars(set, nlp->solver, nlp->problem, c, lbs, ubs, names) );
2978
2979#if ADDNAMESTONLPI
2981#endif
2984
2985 nlp->nunflushedvaradd = 0;
2986
2987 return SCIP_OKAY;
2988}
2989
2990/** updates the objective in the NLPI problem, if necessary
2991 *
2992 * assumes that there are no unflushed variable additions or deletions (nlpFlushVarDeletions() and nlpFlushVarAdditions() should be called first)
2993 */
2994static
2996 SCIP_NLP* nlp, /**< NLP data */
2997 BMS_BLKMEM* blkmem, /**< block memory */
2998 SCIP_SET* set /**< global SCIP settings */
2999 )
3000{
3001 int* linindices;
3002 SCIP_Real* lincoefs;
3003 SCIP_Real coef;
3004 int i;
3005 int nz;
3006
3007 assert(nlp != NULL);
3008 assert(blkmem != NULL);
3009 assert(set != NULL);
3010 assert(nlp->nunflushedvaradd == 0);
3011 assert(nlp->nunflushedvardel == 0);
3012 assert(!nlp->indiving);
3013
3014 if( nlp->objflushed )
3015 return SCIP_OKAY;
3016
3017 assert(nlp->solver != NULL);
3018 assert(nlp->problem != NULL);
3019
3020 /* assemble coefficients */
3023
3024 nz = 0;
3025 for( i = 0; i < nlp->nvars_solver; ++i )
3026 {
3027 assert(nlp->varmap_nlpi2nlp[i] >= 0); /* there should be no variable deletions pending */
3028
3029 coef = SCIPvarGetObj(nlp->vars[nlp->varmap_nlpi2nlp[i]]);
3030 if( SCIPsetIsZero(set, coef) )
3031 continue;
3032
3033 linindices[nz] = i;
3034 lincoefs[nz] = coef;
3035 ++nz;
3036 }
3037
3039 nz, linindices, lincoefs,
3040 NULL,
3041 0.0) );
3042
3043 SCIPsetFreeBufferArray(set, &lincoefs);
3045
3046 nlp->objflushed = TRUE;
3047
3048 return SCIP_OKAY;
3049}
3050
3051/** solves the NLP (or diving NLP), assuming it has been flushed already */
3052static
3054 SCIP_NLP* nlp, /**< NLP data */
3055 BMS_BLKMEM* blkmem, /**< block memory buffers */
3056 SCIP_SET* set, /**< global SCIP settings */
3057 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3058 SCIP_STAT* stat, /**< problem statistics */
3059 SCIP_PRIMAL* primal, /**< primal data */
3060 SCIP_TREE* tree, /**< branch and bound tree */
3061 SCIP_NLPPARAM* nlpparam /**< NLP solve parameters */
3062 )
3063{
3064 int i;
3065
3066 assert(nlp != NULL);
3067 assert(blkmem != NULL);
3068 assert(set != NULL);
3069 assert(stat != NULL);
3070
3071 if( nlp->solver == NULL )
3072 {
3073 SCIPmessagePrintWarning(messagehdlr, "Attempted to solve NLP, but no solver available.\n");
3074
3077
3078 return SCIP_OKAY;
3079 }
3080
3081 assert(nlp->solver != NULL);
3082 assert(nlp->problem != NULL);
3083
3084 /* set initial guess, if available and warmstart hasn't been enabled
3085 * when using the NLP, passing a dual solution with the initguess is not available at the moment (TODO),
3086 * so a warmstart has to start from the last solution stored in the NLPI
3087 */
3088 if( nlp->haveinitguess && !nlpparam->warmstart )
3089 {
3090 /* @todo should we not set it if we had set it already? (initguessflushed...) */
3091 SCIP_Real* initialguess_solver;
3092 int nlpidx;
3093
3094 assert(nlp->initialguess != NULL);
3095
3097
3098 for( i = 0; i < nlp->nvars_solver; ++i )
3099 {
3100 nlpidx = nlp->varmap_nlpi2nlp[i];
3101 assert(nlpidx >= 0);
3103
3105 }
3107
3109 }
3110
3111 /* let NLP solver do his work */
3113
3114 SCIP_CALL( SCIPnlpiSolve(set, stat, nlp->solver, nlp->problem, nlpparam) );
3115
3117 ++stat->nnlps;
3118
3119 nlp->termstat = SCIPnlpiGetTermstat(set, nlp->solver, nlp->problem);
3120 nlp->solstat = SCIPnlpiGetSolstat(set, nlp->solver, nlp->problem);
3121 switch( nlp->solstat )
3122 {
3127 {
3128 SCIP_Real* primalvals;
3129 SCIP_Real* nlrowdualvals;
3130 SCIP_Real* varlbdualvals;
3131 SCIP_Real* varubdualvals;
3132
3133 primalvals = NULL;
3135 varlbdualvals = NULL;
3136 varubdualvals = NULL;
3137
3138 /* get NLP solution */
3139 SCIP_CALL( SCIPnlpiGetSolution(set, nlp->solver, nlp->problem, &primalvals, &nlrowdualvals, &varlbdualvals, &varubdualvals, NULL) );
3140 assert(primalvals != NULL || nlp->nvars == 0);
3141 assert((varlbdualvals != NULL) == (varubdualvals != NULL)); /* if there are duals for one bound, then there should also be duals for the other bound */
3142
3143 /* store solution primal values in variable and evaluate objective function */
3144 if( nlp->indiving && nlp->divingobj != NULL )
3145 {
3146 for( i = 0; i < nlp->nvars; ++i )
3147 {
3148 SCIP_CALL( SCIPvarSetNLPSol(nlp->vars[i], set, primalvals[nlp->varmap_nlp2nlpi[i]]) ); /*lint !e613 */
3149 }
3150
3151 /* evaluate modified diving objective */
3152 SCIP_CALL( SCIPnlrowGetNLPActivity(nlp->divingobj, blkmem, set, stat, primal, tree, nlp, &nlp->primalsolobjval) );
3153 }
3154 else
3155 {
3156 /* evaluate SCIP objective function */
3157 nlp->primalsolobjval = 0.0;
3158 for( i = 0; i < nlp->nvars; ++i )
3159 {
3160 SCIP_Real solval = primalvals[nlp->varmap_nlp2nlpi[i]]; /*lint !e613 */
3161
3162 /* do a quick assert that variable bounds are satisfied, if feasibility is claimed */
3167
3168 SCIP_CALL( SCIPvarSetNLPSol(nlp->vars[i], set, solval) ); /*lint !e613 */
3169 nlp->primalsolobjval += SCIPvarGetObj(nlp->vars[i]) * solval; /*lint !e613 */
3170 }
3171 }
3172
3173 /* store solution dual values in nlrows and variables */
3174 for( i = 0; i < nlp->nnlrows; ++i )
3175 {
3176 assert(nlp->nlrows[i]->nlpiindex >= 0); /* NLP was flushed before solve, so all nlrows should be in there */
3177
3178 nlp->nlrows[i]->dualsol = nlrowdualvals != NULL ? nlrowdualvals[nlp->nlrows[i]->nlpiindex] : 0.0;
3179
3180 /* SCIPsetDebugMsg(set, "dual of nlrow <%s> = %g\n", nlp->nlrows[i]->name, nlp->nlrows[i]->dualsol); */
3181 }
3182 assert(nlp->varlbdualvals != NULL || nlp->nvars == 0);
3183 assert(nlp->varubdualvals != NULL || nlp->nvars == 0);
3184 if( varlbdualvals != NULL )
3185 {
3186 for( i = 0; i < nlp->nvars; ++i )
3187 {
3188 assert(nlp->varmap_nlp2nlpi[i] >= 0); /* NLP was flushed before solve, so all vars should be in there */
3189
3190 nlp->varlbdualvals[i] = varlbdualvals[nlp->varmap_nlp2nlpi[i]];
3191 nlp->varubdualvals[i] = varubdualvals[nlp->varmap_nlp2nlpi[i]];
3192
3193 /* SCIPsetDebugMsg(set, "duals of var <%s> = %g %g\n", SCIPvarGetName(nlp->vars[i]), nlp->varlbdualvals[i], nlp->varubdualvals[i]); */
3194 }
3195 }
3196 else if( nlp->nvars > 0 )
3197 {
3200 }
3201
3202 break;
3203 }
3204 default:
3206 break;
3207 } /*lint !e788*/
3208
3209 return SCIP_OKAY;
3210}
3211
3212/** assembles list of fractional variables in last NLP solution */
3213static
3215 SCIP_NLP* nlp, /**< NLP data */
3216 BMS_BLKMEM* blkmem, /**< block memory buffers */
3217 SCIP_SET* set, /**< global SCIP settings */
3218 SCIP_STAT* stat /**< problem statistics */
3219 )
3220{
3221 assert(nlp != NULL);
3222 assert(blkmem != NULL);
3223 assert(set != NULL);
3224 assert(stat != NULL);
3225 assert(nlp->validfracvars <= stat->nnlps);
3227
3228 SCIPsetDebugMsg(set, "calculating NLP fractional variables: validfracvars=%" SCIP_LONGINT_FORMAT ", nnlps=%" SCIP_LONGINT_FORMAT "\n", nlp->validfracvars, stat->nnlps);
3229
3231 {
3232 nlp->nfracvars = 0;
3233 nlp->npriofracvars = 0;
3234 nlp->validfracvars = stat->nnlps;
3235
3236 SCIPsetDebugMsg(set, "NLP globally infeasible, unbounded, or worse -> no solution values -> no fractional variables\n");
3237 return SCIP_OKAY;
3238 }
3239
3240 /* check, if the current NLP fractional variables array is invalid */
3241 if( nlp->validfracvars < stat->nnlps )
3242 {
3243 SCIP_VAR* var;
3244 SCIP_Real primsol;
3245 SCIP_Real frac;
3246 int branchpriority;
3247 int insertpos;
3248 int maxpriority;
3249 int i;
3250
3251 SCIPsetDebugMsg(set, " -> recalculating NLP fractional variables\n");
3252
3253 if( nlp->fracvarssize == 0 )
3254 {
3255 assert(nlp->fracvars == NULL);
3256 assert(nlp->fracvarssol == NULL);
3257 assert(nlp->fracvarsfrac == NULL);
3258 nlp->fracvarssize = 5;
3262 }
3263
3265 nlp->nfracvars = 0;
3266 nlp->npriofracvars = 0;
3267 for( i = 0; i < nlp->nvars; ++i )
3268 {
3269 var = nlp->vars[i];
3270 assert(var != NULL);
3271
3274
3275 /* consider only binary and integer variables */
3277 continue;
3278
3279 /* ignore fixed variables (due to numerics, it is possible, that the NLP solution of a fixed integer variable
3280 * (with large fixed value) is fractional in terms of absolute feasibility measure)
3281 */
3283 continue;
3284
3285 /* check, if the LP solution value is fractional */
3287
3288 /* The fractionality should not be smaller than -feastol, however, if the primsol is large enough
3289 * and close to an integer, fixed precision floating point arithmetic might give us values slightly
3290 * smaller than -feastol. Originally, the "frac >= -feastol"-check was within SCIPsetIsFeasFracIntegral(),
3291 * however, we relaxed it to "frac >= -2*feastol" and have the stricter check here for small-enough primsols.
3292 */
3294
3296 continue;
3297
3298 /* ensure enough space in fracvars arrays */
3299 if( nlp->fracvarssize <= nlp->nfracvars )
3300 {
3301 int newsize;
3302
3307 nlp->fracvarssize = newsize;
3308 }
3309 assert(nlp->nfracvars < nlp->fracvarssize);
3310 assert(nlp->fracvars != NULL);
3311 assert(nlp->fracvarssol != NULL);
3312 assert(nlp->fracvarsfrac != NULL);
3313
3314 /* insert candidate in candidate list */
3315 branchpriority = SCIPvarGetBranchPriority(var);
3316 insertpos = nlp->nfracvars;
3317 nlp->nfracvars++;
3318 if( branchpriority > maxpriority )
3319 {
3320 /* candidate has higher priority than the current maximum:
3321 * move it to the front and declare it to be the single best candidate
3322 */
3323 if( insertpos != 0 )
3324 {
3325 nlp->fracvars[insertpos] = nlp->fracvars[0];
3326 nlp->fracvarssol[insertpos] = nlp->fracvarssol[0];
3327 nlp->fracvarsfrac[insertpos] = nlp->fracvarsfrac[0];
3328 insertpos = 0;
3329 }
3330 nlp->npriofracvars = 1;
3331 maxpriority = branchpriority;
3332 }
3333 else if( branchpriority == maxpriority )
3334 {
3335 /* candidate has equal priority as the current maximum:
3336 * move away the first non-maximal priority candidate, move the current candidate to the correct
3337 * slot (binaries first) and increase the number of maximal priority candidates
3338 */
3339 if( insertpos != nlp->npriofracvars )
3340 {
3341 nlp->fracvars[insertpos] = nlp->fracvars[nlp->npriofracvars];
3344 insertpos = nlp->npriofracvars;
3345 }
3346 ++nlp->npriofracvars;
3347 }
3348 nlp->fracvars[insertpos] = var;
3350 nlp->fracvarsfrac[insertpos] = frac;
3351
3352 SCIPsetDebugMsg(set, " -> candidate %d: var=<%s>, sol=%g, frac=%g, prio=%d (max: %d) -> pos %d\n",
3353 nlp->nfracvars, SCIPvarGetName(var), primsol, frac, branchpriority, maxpriority, insertpos);
3354 }
3355
3356 nlp->validfracvars = stat->nnlps;
3357 }
3358 assert(0 <= nlp->npriofracvars);
3359 assert(nlp->npriofracvars <= nlp->nfracvars);
3360
3361 SCIPsetDebugMsg(set, " -> %d fractional variables (%d of maximal priority)\n", nlp->nfracvars, nlp->npriofracvars);
3362
3363 return SCIP_OKAY;
3364}
3365
3366/** event handling for variable events */
3367static
3369{
3371 SCIP_VAR* var;
3372
3373 assert(scip != NULL);
3374 assert(eventhdlr != NULL);
3375 assert(event != NULL);
3376 assert(eventdata != NULL);
3377
3378 assert((SCIP_NLP*)eventdata == scip->nlp);
3379
3382
3384 {
3385 SCIPdebugMessage("-> handling varadd event, variable <%s>\n", SCIPvarGetName(var) );
3387 }
3388 else if( SCIP_EVENTTYPE_VARDELETED & etype )
3389 {
3390 SCIPdebugMessage("-> handling vardel event, variable <%s>\n", SCIPvarGetName(var) );
3391 SCIP_CALL( SCIPnlpDelVar(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, scip->eventqueue, scip->lp, var) );
3392 }
3393 else if( SCIP_EVENTTYPE_VARFIXED & etype )
3394 {
3395 /* variable was fixed, aggregated, or multi-aggregated */
3396 /* TODO is this ever happening? that is, can we have changes in a variable status during solve? */
3397 SCIPdebugMessage("-> handling variable fixation event, variable <%s>\n", SCIPvarGetName(var) );
3398 SCIP_CALL( nlpRemoveFixedVar(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, scip->eventqueue, scip->lp, var) );
3399 }
3401 {
3402 SCIPdebugMessage("-> handling bound changed event %" SCIP_EVENTTYPE_FORMAT ", variable <%s>\n", etype, SCIPvarGetName(var) );
3404 }
3405 else if( SCIP_EVENTTYPE_OBJCHANGED & etype )
3406 {
3407 SCIPdebugMessage("-> handling objchg event, variable <%s>\n", SCIPvarGetName(var) );
3408 SCIP_CALL( nlpUpdateObjCoef(scip->set, scip->nlp, var) );
3409 }
3410 else
3411 {
3412 SCIPerrorMessage("unexpected event %" SCIP_EVENTTYPE_FORMAT " on variable <%s>\n", etype, SCIPvarGetName(var) );
3413 return SCIP_ERROR;
3414 }
3415
3416 return SCIP_OKAY;
3417}
3418
3419
3420/*
3421 * public NLP methods
3422 */
3423
3424/** includes event handler that is used by NLP */
3426 SCIP_SET* set, /**< global SCIP settings */
3427 BMS_BLKMEM* blkmem /**< block memory */
3428 )
3429{
3430 SCIP_EVENTHDLR* eventhdlr;
3431
3432 assert(set != NULL);
3433 assert(blkmem != NULL);
3434 assert(set->stage == SCIP_STAGE_INIT);
3435
3436 /* check whether event handler is already present */
3438 {
3439 SCIPerrorMessage("event handler <" EVENTHDLR_NAME "> already included.\n");
3440 return SCIP_INVALIDDATA;
3441 }
3442
3445 SCIP_CALL( SCIPsetIncludeEventhdlr(set, eventhdlr) );
3446
3447 return SCIP_OKAY;
3448} /*lint !e715*/
3449
3450/** construct a new empty NLP */
3452 SCIP_NLP** nlp, /**< NLP handler, call by reference */
3453 BMS_BLKMEM* blkmem, /**< block memory */
3454 SCIP_SET* set, /**< global SCIP settings */
3455 SCIP_STAT* stat, /**< problem statistics */
3456 const char* name, /**< problem name */
3457 int nvars_estimate /**< an estimate on the number of variables that may be added to the NLP later */
3458 )
3459{
3460 assert(nlp != NULL);
3461 assert(blkmem != NULL);
3462 assert(set != NULL);
3463 assert(stat != NULL);
3464 assert(name != NULL);
3465
3466 SCIP_ALLOC( BMSallocMemory(nlp) );
3467
3468 /* select NLP solver (if any available) and setup problem */
3469 if( set->nnlpis > 0 )
3470 {
3471 assert(set->nlp_solver != NULL);
3472 if( set->nlp_solver[0] == '\0' )
3473 { /* take solver with highest priority */
3474 assert(set->nlpis != NULL);
3475
3476 /* sort the NLPIs if necessary */
3477 if( !set->nlpissorted )
3479
3480 (*nlp)->solver = set->nlpis[0];
3481 }
3482 else
3483 { /* find user specified NLP solver */
3484 (*nlp)->solver = SCIPsetFindNlpi(set, set->nlp_solver);
3485 if( (*nlp)->solver == NULL )
3486 {
3487 SCIPerrorMessage("Selected NLP solver <%s> not available.\n", set->nlp_solver);
3488 return SCIP_PLUGINNOTFOUND;
3489 }
3490 }
3491 assert((*nlp)->solver != NULL);
3492 SCIP_CALL( SCIPnlpiCreateProblem(set, (*nlp)->solver, &(*nlp)->problem, name) );
3493 }
3494 else
3495 {
3496 /* maybe someone wanna use the NLP just to collect nonlinearities, but is not necessarily interesting on solving
3497 * so we allow this and just continue */
3498 (*nlp)->solver = NULL;
3499 (*nlp)->problem = NULL;
3500 }
3501
3502 /* status */
3503 (*nlp)->nunflushedvaradd = 0;
3504 (*nlp)->nunflushedvardel = 0;
3505 (*nlp)->nunflushednlrowadd = 0;
3506 (*nlp)->nunflushednlrowdel = 0;
3507 (*nlp)->indiving = FALSE;
3508
3509 /* variables in problem and NLPI problem */
3510 (*nlp)->nvars = 0;
3511 (*nlp)->sizevars = 0;
3512 (*nlp)->vars = NULL;
3513 SCIP_CALL( SCIPhashmapCreate(&(*nlp)->varhash, blkmem, nvars_estimate) );
3514
3515 (*nlp)->nvars_solver = 0;
3516 (*nlp)->sizevars_solver = 0;
3517 (*nlp)->varmap_nlp2nlpi = NULL;
3518 (*nlp)->varmap_nlpi2nlp = NULL;
3519
3520 /* nonlinear rows in problem and NLPI problem */
3521 (*nlp)->nnlrows = 0;
3522 (*nlp)->sizenlrows = 0;
3523 (*nlp)->nlrows = NULL;
3524
3525 (*nlp)->nnlrows_solver = 0;
3526 (*nlp)->sizenlrows_solver = 0;
3527 (*nlp)->nlrowmap_nlpi2nlp = NULL;
3528
3529 /* objective function */
3530 (*nlp)->objflushed = TRUE;
3531 (*nlp)->divingobj = NULL;
3532
3533 /* initial guess */
3534 (*nlp)->haveinitguess = FALSE;
3535 (*nlp)->initialguess = NULL;
3536
3537 /* solution of NLP */
3538 (*nlp)->primalsolobjval = SCIP_INVALID;
3539 (*nlp)->solstat = SCIP_NLPSOLSTAT_UNKNOWN;
3540 (*nlp)->termstat = SCIP_NLPTERMSTAT_OTHER;
3541 (*nlp)->varlbdualvals = NULL;
3542 (*nlp)->varubdualvals = NULL;
3543
3544 /* event handling: catch variable addition and deletion events */
3545 (*nlp)->eventhdlr = SCIPsetFindEventhdlr(set, EVENTHDLR_NAME);
3546 if( (*nlp)->eventhdlr == NULL )
3547 {
3548 SCIPerrorMessage("NLP eventhandler <" EVENTHDLR_NAME "> not found.\n");
3549 return SCIP_PLUGINNOTFOUND;
3550 }
3551 SCIP_CALL( SCIPeventfilterAdd(set->scip->eventfilter, blkmem, set,
3553 (*nlp)->eventhdlr, (SCIP_EVENTDATA*)(*nlp), &(*nlp)->globalfilterpos) );
3554
3555 /* fractional variables in last NLP solution */
3556 (*nlp)->fracvars = NULL;
3557 (*nlp)->fracvarssol = NULL;
3558 (*nlp)->fracvarsfrac = NULL;
3559 (*nlp)->nfracvars = 0;
3560 (*nlp)->npriofracvars = 0;
3561 (*nlp)->fracvarssize = 0;
3562 (*nlp)->validfracvars = -1;
3563
3564 /* miscellaneous */
3565 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*nlp)->name, name, strlen(name)+1) );
3566
3567 return SCIP_OKAY;
3568}
3569
3570/** frees NLP data object */
3572 SCIP_NLP** nlp, /**< pointer to NLP data object */
3573 BMS_BLKMEM* blkmem, /**< block memory */
3574 SCIP_SET* set, /**< global SCIP settings */
3575 SCIP_STAT* stat, /**< problem statistics */
3576 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3577 SCIP_LP* lp /**< SCIP LP, needed for releasing variables */
3578 )
3579{
3580 assert(nlp != NULL);
3581 assert(*nlp != NULL);
3582 assert(blkmem != NULL);
3583 assert(set != NULL);
3584
3585 /* drop fractional variables */
3586 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->fracvars, (*nlp)->fracvarssize);
3587 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->fracvarssol, (*nlp)->fracvarssize);
3588 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->fracvarsfrac, (*nlp)->fracvarssize);
3589
3590 /* drop global events (variable addition and deletion) */
3591 SCIP_CALL( SCIPeventfilterDel(set->scip->eventfilter, blkmem, set,
3593 (*nlp)->eventhdlr, (SCIP_EVENTDATA*)(*nlp), (*nlp)->globalfilterpos) );
3594
3595 SCIP_CALL( SCIPnlpReset(*nlp, blkmem, set, stat, eventqueue, lp) );
3596 assert((*nlp)->nnlrows == 0);
3597 assert((*nlp)->nnlrows_solver == 0);
3598 assert((*nlp)->nvars == 0);
3599 assert((*nlp)->nvars_solver == 0);
3600 assert((*nlp)->initialguess == NULL);
3601
3602 BMSfreeBlockMemoryArray(blkmem, &(*nlp)->name, strlen((*nlp)->name)+1);
3603
3604 /* free nonlinear rows arrays */
3605 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->nlrowmap_nlpi2nlp, (*nlp)->sizenlrows_solver);
3606 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->nlrows, (*nlp)->sizenlrows);
3607
3608 /* free variables arrays */
3609 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->varmap_nlp2nlpi, (*nlp)->sizevars);
3610 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->varmap_nlpi2nlp, (*nlp)->sizevars_solver);
3611 SCIPhashmapFree(&(*nlp)->varhash);
3612 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->vars, (*nlp)->sizevars);
3613 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->varlbdualvals, (*nlp)->sizevars);
3614 BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->varubdualvals, (*nlp)->sizevars);
3615
3616 /* free NLPI problem */
3617 if( (*nlp)->problem != NULL )
3618 {
3619 SCIP_CALL( SCIPnlpiFreeProblem(set, (*nlp)->solver, &(*nlp)->problem) );
3620 }
3621
3622 /* free NLP data structure */
3623 BMSfreeMemory(nlp);
3624
3625 return SCIP_OKAY;
3626}
3627
3628/** resets the NLP to the empty NLP by removing all variables and rows from NLP,
3629 * releasing all rows, and flushing the changes to the NLP solver
3630 */
3632 SCIP_NLP* nlp, /**< NLP data */
3633 BMS_BLKMEM* blkmem, /**< block memory */
3634 SCIP_SET* set, /**< global SCIP settings */
3635 SCIP_STAT* stat, /**< problem statistics data */
3636 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3637 SCIP_LP* lp /**< SCIP LP, needed for releasing variables */
3638 )
3639{
3640 int i;
3641
3642 assert(nlp != NULL);
3643 assert(blkmem != NULL);
3644 assert(set != NULL);
3645
3646 if( nlp->indiving )
3647 {
3648 SCIP_CALL( SCIPnlpEndDive(nlp, blkmem, set, stat) );
3649 }
3650
3653
3655 nlp->haveinitguess = FALSE;
3656
3657 for(i = nlp->nnlrows - 1; i >= 0; --i)
3658 {
3659 SCIP_CALL( nlpDelNlRowPos(nlp, blkmem, set, stat, i) );
3660 }
3661
3662 for(i = nlp->nvars - 1; i >= 0; --i)
3663 {
3664 SCIP_CALL( nlpDelVarPos(nlp, blkmem, set, stat, eventqueue, lp, i) );
3665 }
3666
3667 SCIP_CALL( SCIPnlpFlush(nlp, blkmem, set, stat) );
3668
3669 return SCIP_OKAY;
3670}
3671
3672/** currently a dummy function that always returns TRUE */
3674 SCIP_NLP* nlp /**< NLP data */
3675 )
3676{
3677 assert(nlp != NULL);
3678 return TRUE;
3679} /*lint !e715*/
3680
3681/** ensures, that variables array of NLP can store at least num entries */
3683 SCIP_NLP* nlp, /**< NLP data */
3684 BMS_BLKMEM* blkmem, /**< block memory */
3685 SCIP_SET* set, /**< global SCIP settings */
3686 int num /**< minimum number of entries to store */
3687 )
3688{
3689 assert(nlp != NULL);
3690 assert(blkmem != NULL);
3691 assert(set != NULL);
3692 assert(nlp->nvars <= nlp->sizevars);
3693
3694 if( num > nlp->sizevars )
3695 {
3696 int newsize;
3697
3703 if( nlp->initialguess != NULL )
3704 {
3706 }
3707
3708 nlp->sizevars = newsize;
3709 }
3710 assert(num <= nlp->sizevars);
3711
3712 return SCIP_OKAY;
3713}
3714
3715/** adds a variable to the NLP and captures the variable */
3717 SCIP_NLP* nlp, /**< NLP data */
3718 BMS_BLKMEM* blkmem, /**< block memory */
3719 SCIP_SET* set, /**< global SCIP settings */
3720 SCIP_VAR* var /**< variable */
3721 )
3722{
3723 assert(nlp != NULL);
3724 assert(blkmem != NULL);
3725 assert(set != NULL);
3726 assert(var != NULL);
3729
3730 if( nlp->indiving )
3731 {
3732 SCIPerrorMessage("cannot add variable during NLP diving\n");
3733 return SCIP_ERROR;
3734 }
3735
3736 SCIP_CALL( nlpAddVars(nlp, blkmem, set, 1, &var) );
3737
3738 return SCIP_OKAY;
3739}
3740
3741/** adds a set of variables to the NLP and captures the variables */
3743 SCIP_NLP* nlp, /**< NLP data */
3744 BMS_BLKMEM* blkmem, /**< block memory */
3745 SCIP_SET* set, /**< global SCIP settings */
3746 int nvars, /**< number of variables to add */
3747 SCIP_VAR** vars /**< variables to add */
3748 )
3749{
3750 assert(nlp != NULL);
3751 assert(blkmem != NULL);
3752 assert(set != NULL);
3753 assert(vars != NULL || nvars == 0);
3754
3755 if( nlp->indiving && nvars > 0)
3756 {
3757 SCIPerrorMessage("cannot add variables during NLP diving\n");
3758 return SCIP_ERROR;
3759 }
3760
3761 SCIP_CALL( nlpAddVars(nlp, blkmem, set, nvars, vars) );
3762
3763 return SCIP_OKAY;
3764}
3765
3766/** deletes a variable from the NLP and releases the variable */
3768 SCIP_NLP* nlp, /**< NLP data */
3769 BMS_BLKMEM* blkmem, /**< block memory */
3770 SCIP_SET* set, /**< global SCIP settings */
3771 SCIP_STAT* stat, /**< problem statistics data */
3772 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3773 SCIP_LP* lp, /**< SCIP LP, needed to release variable */
3774 SCIP_VAR* var /**< variable */
3775 )
3776{
3777 int varpos;
3778
3779 assert(nlp != NULL);
3780 assert(blkmem != NULL);
3781 assert(set != NULL);
3782 assert(var != NULL);
3783
3784 if( !SCIPhashmapExists(nlp->varhash, var) )
3785 {
3786 SCIPerrorMessage("variable <%s> not found in NLP, cannot delete\n", SCIPvarGetName(var));
3787 return SCIP_ERROR;
3788 }
3789
3790 if( nlp->indiving )
3791 {
3792 SCIPerrorMessage("cannot delete variable during NLP diving\n");
3793 return SCIP_ERROR;
3794 }
3795
3796 varpos = SCIPhashmapGetImageInt(nlp->varhash, var);
3797
3798 SCIP_CALL( nlpDelVarPos(nlp, blkmem, set, stat, eventqueue, lp, varpos) );
3799
3800 return SCIP_OKAY;
3801}
3802
3803/** ensures, that nonlinear rows array of NLP can store at least num entries */
3805 SCIP_NLP* nlp, /**< NLP data */
3806 BMS_BLKMEM* blkmem, /**< block memory */
3807 SCIP_SET* set, /**< global SCIP settings */
3808 int num /**< minimum number of entries to store */
3809 )
3810{
3811 assert(nlp != NULL);
3812 assert(blkmem != NULL);
3813 assert(set != NULL);
3814 assert(nlp->nnlrows <= nlp->sizenlrows);
3815
3816 if( num > nlp->sizenlrows )
3817 {
3818 int newsize;
3819
3822
3823 nlp->sizenlrows = newsize;
3824 }
3825 assert(num <= nlp->sizenlrows);
3826
3827 return SCIP_OKAY;
3828}
3829
3830/** adds a nonlinear row to the NLP and captures it
3831 *
3832 * all variables of the row need to be present in the NLP
3833 */
3835 SCIP_NLP* nlp, /**< NLP data */
3836 BMS_BLKMEM* blkmem, /**< block memory */
3837 SCIP_SET* set, /**< global SCIP settings */
3838 SCIP_STAT* stat, /**< problem statistics data */
3839 SCIP_NLROW* nlrow /**< nonlinear row */
3840 )
3841{
3842 assert(nlp != NULL);
3843 assert(nlrow != NULL);
3844
3845 if( nlp->indiving )
3846 {
3847 SCIPerrorMessage("cannot add row during NLP diving\n");
3848 return SCIP_ERROR;
3849 }
3850
3851 SCIP_CALL( nlpAddNlRows(nlp, blkmem, set, stat, 1, &nlrow) );
3852
3853 return SCIP_OKAY;
3854}
3855
3856/** adds nonlinear rows to the NLP and captures them
3857 *
3858 * all variables of the row need to be present in the NLP
3859 */
3861 SCIP_NLP* nlp, /**< NLP data */
3862 BMS_BLKMEM* blkmem, /**< block memory */
3863 SCIP_SET* set, /**< global SCIP settings */
3864 SCIP_STAT* stat, /**< problem statistics data */
3865 int nnlrows, /**< number of rows to add */
3866 SCIP_NLROW** nlrows /**< rows to add */
3867 )
3868{
3869 assert(nlp != NULL);
3870 assert(nlrows != NULL || nnlrows == 0);
3871
3872 if( nnlrows == 0 )
3873 return SCIP_OKAY;
3874
3875 if( nlp->indiving )
3876 {
3877 SCIPerrorMessage("cannot add rows during NLP diving\n");
3878 return SCIP_ERROR;
3879 }
3880
3881 SCIP_CALL( nlpAddNlRows(nlp, blkmem, set, stat, nnlrows, nlrows) );
3882
3883 return SCIP_OKAY;
3884}
3885
3886/** deletes a nonlinear row from the NLP
3887 *
3888 * does nothing if nonlinear row is not in NLP
3889 */
3891 SCIP_NLP* nlp, /**< NLP data */
3892 BMS_BLKMEM* blkmem, /**< block memory */
3893 SCIP_SET* set, /**< global SCIP settings */
3894 SCIP_STAT* stat, /**< problem statistics data */
3895 SCIP_NLROW* nlrow /**< nonlinear row */
3896 )
3897{
3898 assert(nlp != NULL);
3899 assert(blkmem != NULL);
3900 assert(set != NULL);
3901 assert(nlrow != NULL);
3902
3903 /* if row not in NLP, nothing to do */
3904 if( nlrow->nlpindex == -1 )
3905 return SCIP_OKAY;
3906
3907 assert(nlrow->nlpindex >= 0);
3908 assert(nlrow->nlpindex < nlp->nnlrows);
3909
3910 if( nlp->indiving )
3911 {
3912 SCIPerrorMessage("cannot delete row during NLP diving\n");
3913 return SCIP_ERROR;
3914 }
3915
3916 SCIP_CALL( nlpDelNlRowPos(nlp, blkmem, set, stat, nlrow->nlpindex) );
3917
3918 return SCIP_OKAY;
3919}
3920
3921/** applies all cached changes to the NLP solver */
3923 SCIP_NLP* nlp, /**< current NLP data */
3924 BMS_BLKMEM* blkmem, /**< block memory */
3925 SCIP_SET* set, /**< global SCIP settings */
3926 SCIP_STAT* stat /**< problem statistics */
3927 )
3928{
3929 assert(nlp != NULL);
3930 assert(blkmem != NULL);
3931 assert(set != NULL);
3932
3933 if( nlp->indiving )
3934 {
3935 SCIPerrorMessage("cannot flush NLP during NLP diving\n");
3936 return SCIP_ERROR;
3937 }
3938
3939 /* flush removals of nonlinear rows and variables */
3940 SCIP_CALL( nlpFlushNlRowDeletions(nlp, blkmem, set) );
3941 SCIP_CALL( nlpFlushVarDeletions(nlp, blkmem, set) );
3942 assert(nlp->nunflushednlrowdel == 0);
3943 assert(nlp->nunflushedvardel == 0);
3944
3945 /* flush addition of variables, objective, and addition of rows */
3946 SCIP_CALL( nlpFlushVarAdditions(nlp, blkmem, set) );
3947 SCIP_CALL( nlpFlushObjective(nlp, blkmem, set) );
3948 SCIP_CALL( nlpFlushNlRowAdditions(nlp, blkmem, set, stat) );
3949 assert(nlp->nunflushedvaradd == 0);
3950 assert(nlp->objflushed == TRUE);
3951 assert(nlp->nunflushednlrowadd == 0);
3952
3953 assert(nlp->nvars == nlp->nvars_solver);
3954 assert(nlp->nnlrows == nlp->nnlrows_solver);
3955
3956 return SCIP_OKAY;
3957}
3958
3959/** solves the NLP or diving NLP */
3961 SCIP_NLP* nlp, /**< NLP data */
3962 BMS_BLKMEM* blkmem, /**< block memory buffers */
3963 SCIP_SET* set, /**< global SCIP settings */
3964 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3965 SCIP_STAT* stat, /**< problem statistics */
3966 SCIP_PRIMAL* primal, /**< primal data */
3967 SCIP_TREE* tree, /**< branch and bound tree */
3968 SCIP_NLPPARAM* nlpparam /**< NLP solve parameters */
3969 )
3970{
3971 assert(nlp != NULL);
3972 assert(blkmem != NULL);
3973 assert(set != NULL);
3974 assert(stat != NULL);
3975
3976 if( !nlp->indiving )
3977 {
3978 SCIP_CALL( SCIPnlpFlush(nlp, blkmem, set, stat) );
3979 }
3980
3981 SCIP_CALL( nlpSolve(nlp, blkmem, set, messagehdlr, stat, primal, tree, nlpparam) );
3982
3983 return SCIP_OKAY;
3984}
3985
3986/** gets objective value of current NLP */
3988 SCIP_NLP* nlp /**< current NLP data */
3989 )
3990{
3991 assert(nlp != NULL);
3992
3993 return nlp->primalsolobjval;
3994}
3995
3996/** gives current pseudo objective value */
3998 SCIP_NLP* nlp, /**< current NLP data */
3999 BMS_BLKMEM* blkmem, /**< block memory */
4000 SCIP_SET* set, /**< global SCIP settings */
4001 SCIP_STAT* stat, /**< problem statistics data */
4002 SCIP_PROB* prob, /**< SCIP problem */
4003 SCIP_PRIMAL* primal, /**< primal data */
4004 SCIP_TREE* tree, /**< branch and bound tree */
4005 SCIP_LP* lp, /**< SCIP LP */
4006 SCIP_Real* pseudoobjval /**< buffer to store pseudo objective value */
4007 )
4008{
4009 assert(nlp != NULL);
4010 assert(pseudoobjval != NULL);
4011
4012 if( nlp->divingobj != NULL )
4013 {
4014 assert(nlp->indiving);
4015 SCIP_CALL( SCIPnlrowGetPseudoActivity(nlp->divingobj, blkmem, set, stat, prob, primal, tree, lp, pseudoobjval) );
4016 }
4017 else
4018 {
4019 int i;
4020
4021 *pseudoobjval = 0.0;
4022 for( i = 0; i < nlp->nvars; ++i )
4023 *pseudoobjval += SCIPvarGetObj(nlp->vars[i]) * SCIPvarGetBestBoundLocal(nlp->vars[i]);
4024 }
4025
4026 return SCIP_OKAY;
4027}
4028
4029/** gets fractional variables of last NLP solution along with solution values and fractionalities
4030 */
4032 SCIP_NLP* nlp, /**< NLP data structure */
4033 BMS_BLKMEM* blkmem, /**< block memory */
4034 SCIP_SET* set, /**< global SCIP settings */
4035 SCIP_STAT* stat, /**< problem statistics */
4036 SCIP_VAR*** fracvars, /**< pointer to store the array of NLP fractional variables, or NULL */
4037 SCIP_Real** fracvarssol, /**< pointer to store the array of NLP fractional variables solution values, or NULL */
4038 SCIP_Real** fracvarsfrac, /**< pointer to store the array of NLP fractional variables fractionalities, or NULL */
4039 int* nfracvars, /**< pointer to store the number of NLP fractional variables , or NULL */
4040 int* npriofracvars /**< pointer to store the number of NLP fractional variables with maximal branching priority, or NULL */
4041 )
4042{
4043 assert(nlp != NULL);
4044
4045 SCIP_CALL( nlpCalcFracVars(nlp, blkmem, set, stat) );
4046 assert(nlp->fracvars != NULL);
4047 assert(nlp->fracvarssol != NULL);
4048 assert(nlp->fracvarsfrac != NULL);
4049
4050 if( fracvars != NULL )
4051 *fracvars = nlp->fracvars;
4052 if( fracvarssol != NULL )
4053 *fracvarssol = nlp->fracvarssol;
4054 if( fracvarsfrac != NULL )
4055 *fracvarsfrac = nlp->fracvarsfrac;
4056 if( nfracvars != NULL )
4057 *nfracvars = nlp->nfracvars;
4058 if( npriofracvars != NULL )
4059 *npriofracvars = nlp->npriofracvars;
4060
4061 return SCIP_OKAY;
4062}
4063
4064/** removes all redundant nonlinear rows */
4066 SCIP_NLP* nlp, /**< current NLP data */
4067 BMS_BLKMEM* blkmem, /**< block memory buffers */
4068 SCIP_SET* set, /**< global SCIP settings */
4069 SCIP_STAT* stat /**< problem statistics */
4070 )
4071{
4073 SCIP_Bool isredundant;
4074 int i;
4075
4076 assert(nlp != NULL);
4077 assert(blkmem != NULL);
4078 assert(set != NULL);
4079 assert(stat != NULL);
4080
4081 if( nlp->nnlrows == 0 )
4082 return SCIP_OKAY;
4083
4084 if( nlp->indiving )
4085 {
4086 SCIPerrorMessage("cannot remove redundant rows during NLP diving\n");
4087 return SCIP_ERROR;
4088 }
4089
4090 /* removing redundant rows should not change the solution status, so we reset it at the end */
4091 solstatus = nlp->solstat;
4092
4093 for( i = 0; i < nlp->nnlrows; ++i )
4094 {
4095 SCIP_CALL( SCIPnlrowIsRedundant(nlp->nlrows[i], blkmem, set, stat, &isredundant) );
4096 if( isredundant )
4097 {
4098 SCIP_CALL( nlpDelNlRowPos(nlp, blkmem, set, stat, i) );
4099 }
4100 }
4101
4102 nlp->solstat = solstatus;
4103
4104 return SCIP_OKAY;
4105}
4106
4107/** set initial guess (approximate primal solution) for next solve
4108 *
4109 * array initguess must be NULL or have length at least SCIPnlpGetNVars()
4110 */
4112 SCIP_SET* set, /**< global SCIP settings */
4113 SCIP_NLP* nlp, /**< current NLP data */
4114 BMS_BLKMEM* blkmem, /**< block memory buffers */
4115 SCIP_Real* initguess /**< new initial guess, or NULL to clear previous one */
4116 )
4117{
4118 assert(nlp != NULL);
4119 assert(blkmem != NULL);
4120 assert(nlp->solver != NULL);
4121 assert(nlp->problem != NULL);
4122
4123 /* if user wants to let NLP solver choose start point, then invalidate current initial guess both in NLP and in NLPI */
4124 if( initguess == NULL )
4125 {
4126 nlp->haveinitguess = FALSE;
4128 return SCIP_OKAY;
4129 }
4130
4131 if( nlp->initialguess != NULL )
4132 {
4133 BMScopyMemoryArray(nlp->initialguess, initguess, nlp->nvars);
4134 }
4135 else
4136 {
4137 assert( nlp->sizevars >= nlp->nvars );
4139 BMScopyMemoryArray(nlp->initialguess, initguess, nlp->nvars);
4140 }
4141 nlp->haveinitguess = TRUE;
4142
4143 return SCIP_OKAY;
4144}
4145
4146/** writes NLP to a file */
4148 SCIP_NLP* nlp, /**< current NLP data */
4149 BMS_BLKMEM* blkmem, /**< block memory buffers */
4150 SCIP_SET* set, /**< global SCIP settings */
4151 SCIP_STAT* stat, /**< problem statistics */
4152 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
4153 const char* fname /**< file name */
4154 )
4155{
4156 SCIP_RETCODE retcode = SCIP_OKAY;
4157 FILE* file;
4158 int i;
4159
4160 assert(nlp != NULL);
4161
4162 if( fname != NULL )
4163 {
4164 file = fopen(fname, "w");
4165 if( file == NULL )
4166 {
4167 SCIPerrorMessage("could not open file <%s> for writing\n", fname);
4168 return SCIP_FILECREATEERROR;
4169 }
4170 }
4171 else
4172 file = stdout;
4173
4174 SCIPmessageFPrintInfo(messagehdlr, file, "STATISTICS\n");
4175 SCIPmessageFPrintInfo(messagehdlr, file, " NLP name: %s\n", nlp->name);
4176 SCIPmessageFPrintInfo(messagehdlr, file, " Variables: %d\n", nlp->nvars);
4177 SCIPmessageFPrintInfo(messagehdlr, file, " Rows: %d\n", nlp->nnlrows);
4178
4179 SCIPmessageFPrintInfo(messagehdlr, file, "VARIABLES\n");
4180 for( i = 0; i < nlp->nvars; ++i )
4181 {
4182 SCIP_CALL( SCIPvarPrint(nlp->vars[i], set, messagehdlr, file) );
4183 }
4184
4185 SCIPmessageFPrintInfo(messagehdlr, file, "NONLINEAR ROWS\n");
4186 for( i = 0; i < nlp->nnlrows; ++i )
4187 {
4188 SCIPmessageFPrintInfo(messagehdlr, file, " ");
4189 SCIP_CALL_TERMINATE( retcode, SCIPnlrowPrint(nlp->nlrows[i], blkmem, set, stat, messagehdlr, file), TERMINATE );
4190 }
4191
4192 TERMINATE:
4193 if( fname != NULL )
4194 {
4195 fclose(file);
4196 }
4197
4198 return retcode;
4199}
4200
4201/** gets array with variables of the NLP */
4203 SCIP_NLP* nlp /**< current NLP data */
4204 )
4205{
4206 assert(nlp != NULL);
4207
4208 return nlp->vars;
4209}
4210
4211/** gets current number of variables in NLP */
4213 SCIP_NLP* nlp /**< current NLP data */
4214 )
4215{
4216 assert(nlp != NULL);
4217
4218 return nlp->nvars;
4219}
4220
4221/** computes for each variables the number of NLP rows in which the variable appears in a nonlinear var */
4223 SCIP_NLP* nlp, /**< current NLP data */
4224 BMS_BLKMEM* blkmem, /**< block memory buffers */
4225 SCIP_SET* set, /**< global SCIP settings */
4226 SCIP_STAT* stat, /**< problem statistics */
4227 int* nlcount /**< an array of length at least SCIPnlpGetNVars() to store nonlinearity counts of variables */
4228 )
4229{
4230 SCIP_NLROW* nlrow;
4232 SCIP_EXPR* expr;
4233 int varidx;
4234 int c;
4235
4236 assert(nlp != NULL);
4237 assert(nlcount != NULL || nlp->nvars == 0);
4238
4239 BMSclearMemoryArray(nlcount, nlp->nvars);
4240
4241 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
4242
4243 for( c = 0; c < nlp->nnlrows; ++c )
4244 {
4245 nlrow = nlp->nlrows[c];
4246 assert(nlrow != NULL);
4247
4248 if( nlrow->expr == NULL )
4249 continue;
4250
4252 for( expr = nlrow->expr; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
4253 {
4254 if( !SCIPexprIsVar(set, expr) )
4255 continue;
4256
4258
4261 assert(nlcount != NULL);
4262 ++nlcount[varidx];
4263 }
4264 }
4265
4267
4268 return SCIP_OKAY;
4269}
4270
4271
4272/** indicates whether there exists a row that contains a continuous variable in a nonlinear term
4273 *
4274 * @note The method may have to touch every row and nonlinear term to compute its result.
4275 */
4277 SCIP_NLP* nlp, /**< current NLP data */
4278 BMS_BLKMEM* blkmem, /**< block memory buffers */
4279 SCIP_SET* set, /**< global SCIP settings */
4280 SCIP_STAT* stat, /**< problem statistics */
4281 SCIP_Bool* result /**< buffer to store whether continuous variable present in an expression of any row */
4282 )
4283{
4284 SCIP_NLROW* nlrow;
4286 SCIP_EXPR* expr;
4287 int c;
4288
4289 assert(nlp != NULL);
4290
4291 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
4293
4294 *result = FALSE;
4295 for( c = 0; c < nlp->nnlrows && !*result; ++c )
4296 {
4297 nlrow = nlp->nlrows[c];
4298 assert(nlrow != NULL);
4299
4300 if( nlrow->expr == NULL )
4301 continue;
4302
4303 for( expr = SCIPexpriterRestartDFS(it, nlrow->expr); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
4304 {
4306 {
4307 *result = TRUE;
4308 break;
4309 }
4310 }
4311 }
4312
4314
4315 return SCIP_OKAY;
4316}
4317
4318/** gives dual solution values associated with lower bounds of NLP variables */
4320 SCIP_NLP* nlp /**< current NLP data */
4321 )
4322{
4323 assert(nlp != NULL);
4324
4325 return nlp->varlbdualvals;
4326}
4327
4328/** gives dual solution values associated with upper bounds of NLP variables */
4330 SCIP_NLP* nlp /**< current NLP data */
4331 )
4332{
4333 assert(nlp != NULL);
4334
4335 return nlp->varubdualvals;
4336}
4337
4338/** gets array with nonlinear rows of the NLP */
4340 SCIP_NLP* nlp /**< current NLP data */
4341 )
4342{
4343 assert(nlp != NULL);
4344
4345 return nlp->nlrows;
4346}
4347
4348/** gets current number of nonlinear rows in NLP */
4350 SCIP_NLP* nlp /**< current NLP data */
4351 )
4352{
4353 assert(nlp != NULL);
4354
4355 return nlp->nnlrows;
4356}
4357
4358/** gets the NLP solver interface */
4360 SCIP_NLP* nlp /**< current NLP data */
4361 )
4362{
4363 assert(nlp != NULL);
4364
4365 return nlp->solver;
4366}
4367
4368/** gets the NLP problem in the solver interface */
4370 SCIP_NLP* nlp /**< current NLP data */
4371 )
4372{
4373 assert(nlp != NULL);
4374
4375 return nlp->problem;
4376}
4377
4378/** indicates whether NLP is currently in diving mode */
4380 SCIP_NLP* nlp /**< current NLP data */
4381 )
4382{
4383 assert(nlp != NULL);
4384
4385 return nlp->indiving;
4386}
4387
4388/** gets solution status of current NLP */
4390 SCIP_NLP* nlp /**< current NLP data */
4391 )
4392{
4393 assert(nlp != NULL);
4394
4395 return nlp->solstat;
4396}
4397
4398/** gets termination status of last NLP solve */
4400 SCIP_NLP* nlp /**< current NLP data */
4401 )
4402{
4403 assert(nlp != NULL);
4404
4405 return nlp->termstat;
4406}
4407
4408/** gives statistics (number of iterations, solving time, ...) of last NLP solve */
4410 SCIP_SET* set, /**< global SCIP settings */
4411 SCIP_NLP* nlp, /**< pointer to NLP datastructure */
4412 SCIP_NLPSTATISTICS* statistics /**< pointer to store statistics */
4413 )
4414{
4415 assert(nlp != NULL);
4416 assert(nlp->solver != NULL);
4417 assert(nlp->problem != NULL);
4419
4421
4422 return SCIP_OKAY;
4423}
4424
4425/** indicates whether a solution for the current NLP is available
4426 *
4427 * The solution may be optimal, feasible, or infeasible.
4428 * Thus, returns whether the NLP solution status is at most \ref SCIP_NLPSOLSTAT_LOCINFEASIBLE.
4429 */
4431 SCIP_NLP* nlp /**< current NLP data */
4432 )
4433{
4434 assert(nlp != NULL);
4435
4437}
4438
4439/*
4440 * NLP diving methods
4441 */
4442
4443/** signals start of diving */
4445 SCIP_NLP* nlp, /**< current NLP data */
4446 BMS_BLKMEM* blkmem, /**< block memory buffers */
4447 SCIP_SET* set, /**< global SCIP settings */
4448 SCIP_STAT* stat /**< problem statistics */
4449 )
4450{
4451 assert(nlp != NULL);
4452
4453 if( nlp->indiving )
4454 {
4455 SCIPerrorMessage("NLP is already in diving mode\n");
4456 return SCIP_ERROR;
4457 }
4458
4459 if( nlp->solver == NULL )
4460 {
4461 /* In diving mode we do not cache changes but put them directly in the NLPI problem, which does not exist if there is no solver.
4462 * So we forbid diving of no solver is available. */
4463 SCIPerrorMessage("Cannot start diving if no NLP solver is available\n");
4464 return SCIP_ERROR;
4465 }
4466
4467 SCIP_CALL( SCIPnlpFlush(nlp, blkmem, set, stat) );
4468
4469 nlp->indiving = TRUE;
4470
4471 return SCIP_OKAY;
4472}
4473
4474/** resets the bound and objective changes made during diving and disables diving mode */
4476 SCIP_NLP* nlp, /**< current NLP data */
4477 BMS_BLKMEM* blkmem, /**< block memory */
4478 SCIP_SET* set, /**< global SCIP settings */
4479 SCIP_STAT* stat /**< problem statistics data */
4480 )
4481{
4482 int i;
4483 int* varidx;
4484 SCIP_Real* varlb;
4485 SCIP_Real* varub;
4486
4487 assert(nlp != NULL);
4488 assert(set != NULL);
4489 assert(nlp->nvars == nlp->nvars_solver);
4490
4491 if( !nlp->indiving )
4492 {
4493 SCIPerrorMessage("NLP not in diving mode, cannot end dive\n");
4494 return SCIP_ERROR;
4495 }
4496
4497 assert(nlp->solver != NULL);
4498 assert(nlp->problem != NULL);
4499
4500 /* reset variable bounds in NLPI problem to their current values */
4504 for( i = 0; i < nlp->nvars; ++i )
4505 {
4506 varidx[i] = i;
4509 }
4510
4512
4516
4517 /* clear diving objective, if one was used (i.e., if SCIPnlpChgVarObjDive had been called)
4518 * the objective in the NLPI will be reset in the next flush */
4519 if( nlp->divingobj != NULL )
4520 {
4521 SCIP_CALL( SCIPnlrowRelease(&nlp->divingobj, blkmem, set, stat) );
4522 assert(nlp->divingobj == NULL);
4523 assert(nlp->objflushed == FALSE);
4524 }
4525
4526 /* we do not have a valid solution anymore */
4530
4531 nlp->indiving = FALSE;
4532
4533 return SCIP_OKAY;
4534}
4535
4536/** changes coefficient of variable in diving NLP */
4538 SCIP_NLP* nlp, /**< current NLP data */
4539 BMS_BLKMEM* blkmem, /**< block memory */
4540 SCIP_SET* set, /**< global SCIP settings */
4541 SCIP_STAT* stat, /**< problem statistics data */
4542 SCIP_VAR* var, /**< variable which coefficient to change */
4543 SCIP_Real coef /**< new linear coefficient of variable in objective */
4544 )
4545{
4546 int pos;
4547 int objidx;
4548
4549 assert(nlp != NULL);
4550 assert(var != NULL);
4552 assert(nlp->indiving);
4553 assert(nlp->solver != NULL);
4554 assert(nlp->problem != NULL);
4555
4556 /* get position of variable in NLPI problem */
4557 pos = SCIPhashmapGetImageInt(nlp->varhash, var);
4558 pos = nlp->varmap_nlp2nlpi[pos];
4559 assert(pos >= 0);
4560
4561 /* set coefficient in NLPI problem objective */
4562 objidx = -1;
4563 SCIP_CALL( SCIPnlpiChgLinearCoefs(set, nlp->solver, nlp->problem, objidx, 1, &pos, &coef) );
4564
4565 /* create an nlrow that holds the diving objective, if not done yet */
4566 if( nlp->divingobj == NULL )
4567 {
4568 SCIP_Real* coefs;
4569 int i;
4570
4571 SCIP_CALL( SCIPsetAllocBufferArray(set, &coefs, nlp->nvars) );
4572 for( i = 0; i < nlp->nvars; ++i )
4573 coefs[i] = SCIPvarGetObj(nlp->vars[i]);
4574
4575 SCIP_CALL( SCIPnlrowCreate(&nlp->divingobj, blkmem, set, stat, "divingobj",
4576 0.0, nlp->nvars, nlp->vars, coefs, NULL,
4579
4580 SCIPsetFreeBufferArray(set, &coefs);
4581 }
4582 assert(nlp->divingobj != NULL);
4583
4584 /* modify coefficient in diving objective */
4585 SCIP_CALL( SCIPnlrowChgLinearCoef(nlp->divingobj, blkmem, set, stat, nlp, var, coef) );
4586
4587 /* remember that we have to store objective after diving ended */
4588 nlp->objflushed = FALSE;
4589
4590 return SCIP_OKAY;
4591}
4592
4593/** changes bounds of variable in diving NLP */
4595 SCIP_SET* set, /**< global SCIP settings */
4596 SCIP_NLP* nlp, /**< current NLP data */
4597 SCIP_VAR* var, /**< variable which coefficient to change */
4598 SCIP_Real lb, /**< new lower bound of variable */
4599 SCIP_Real ub /**< new upper bound of variable */
4600 )
4601{
4602 int pos;
4603
4604 assert(nlp != NULL);
4605 assert(var != NULL);
4607 assert(nlp->indiving);
4608 assert(nlp->solver != NULL);
4609 assert(nlp->problem != NULL);
4610
4611 /* get position of variable in NLPI problem */
4612 pos = SCIPhashmapGetImageInt(nlp->varhash, var);
4613 pos = nlp->varmap_nlp2nlpi[pos];
4614 assert(pos >= 0);
4615
4616 /* set new bounds in NLPI */
4617 SCIP_CALL( SCIPnlpiChgVarBounds(set, nlp->solver, nlp->problem, 1, &pos, &lb, &ub) );
4618
4619 return SCIP_OKAY;
4620}
4621
4622/** changes bounds of a set of variables in diving NLP */
4624 SCIP_NLP* nlp, /**< current NLP data */
4625 SCIP_SET* set, /**< global SCIP settings */
4626 int nvars, /**< number of variables which bounds to change */
4627 SCIP_VAR** vars, /**< variables which bounds to change */
4628 SCIP_Real* lbs, /**< new lower bounds of variables */
4629 SCIP_Real* ubs /**< new upper bounds of variables */
4630 )
4631{
4632 int i;
4633 int* poss;
4634
4635 assert(nlp != NULL);
4636 assert(vars != NULL || nvars == 0);
4637 assert(nlp->indiving);
4638 assert(lbs != NULL || nvars == 0);
4639 assert(ubs != NULL || nvars == 0);
4640 assert(nlp->solver != NULL);
4641 assert(nlp->problem != NULL);
4642
4643 if( nvars == 0 )
4644 return SCIP_OKAY;
4645
4647
4648 for( i = 0; i < nvars; ++i )
4649 {
4650 assert(SCIPhashmapExists(nlp->varhash, vars[i])); /*lint !e613*/
4651
4652 /* get position of variable in NLPI problem */
4653 poss[i] = SCIPhashmapGetImageInt(nlp->varhash, vars[i]); /*lint !e613*/
4654 poss[i] = nlp->varmap_nlp2nlpi[poss[i]];
4655 assert(poss[i] >= 0);
4656 }
4657
4658 /* set new bounds in NLPI */
4659 SCIP_CALL( SCIPnlpiChgVarBounds(set, nlp->solver, nlp->problem, nvars, poss, lbs, ubs) );
4660
4662
4663 return SCIP_OKAY;
4664}
4665
4666/** returns whether the objective function has been changed during diving */
4668 SCIP_NLP* nlp /**< current NLP data */
4669 )
4670{
4671 return nlp->divingobj != NULL;
4672}
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition clock.c:360
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition clock.c:290
internal methods for clocks and timing issues
#define SCIP_INVALID
Definition def.h:206
#define SCIP_ALLOC(x)
Definition def.h:399
#define SCIP_UNKNOWN
Definition def.h:207
#define TRUE
Definition def.h:95
#define FALSE
Definition def.h:96
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition def.h:409
#define REALABS(x)
Definition def.h:210
#define SCIP_CALL(x)
Definition def.h:388
SCIP_RETCODE SCIPeventhdlrCreate(SCIP_EVENTHDLR **eventhdlr, SCIP_SET *set, const char *name, const char *desc, SCIP_DECL_EVENTCOPY((*eventcopy)), SCIP_DECL_EVENTFREE((*eventfree)), SCIP_DECL_EVENTINIT((*eventinit)), SCIP_DECL_EVENTEXIT((*eventexit)), SCIP_DECL_EVENTINITSOL((*eventinitsol)), SCIP_DECL_EVENTEXITSOL((*eventexitsol)), SCIP_DECL_EVENTDELETE((*eventdelete)), SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition event.c:123
SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition event.c:1979
SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition event.c:1886
internal methods for managing events
SCIP_RETCODE SCIPexprPrint(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
Definition expr.c:2243
SCIP_RETCODE SCIPexprEvalActivity(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr)
Definition expr.c:2927
SCIP_RETCODE SCIPexprCopy(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_SET *targetset, SCIP_STAT *targetstat, BMS_BLKMEM *targetblkmem, SCIP_EXPR *sourceexpr, SCIP_EXPR **targetexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr.c:1855
SCIP_RETCODE SCIPexprSimplify(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_EXPR **simplified, SCIP_Bool *changed, SCIP_Bool *infeasible, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr.c:3166
SCIP_Bool SCIPexprIsVar(SCIP_SET *set, SCIP_EXPR *expr)
Definition expr.c:2183
SCIP_Bool SCIPexprIsValue(SCIP_SET *set, SCIP_EXPR *expr)
Definition expr.c:2195
SCIP_RETCODE SCIPexprRelease(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR **rootexpr)
Definition expr.c:2051
SCIP_RETCODE SCIPexprEval(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition expr.c:2631
private functions to work with algebraic expressions
void SCIPexpriterFree(SCIP_EXPRITER **iterator)
Definition expriter.c:445
SCIP_RETCODE SCIPexpriterCreate(SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRITER **iterator)
Definition expriter.c:426
handler for variable index expressions
SCIP_RETCODE SCIPcreateExprVaridx(SCIP *scip, SCIP_EXPR **expr, int varidx, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3058
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3231
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3024
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3373
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition misc.c:3142
SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3389
SCIP_RETCODE SCIPhashmapSetImageInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition misc.c:3307
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition lp.c:17042
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition event.c:1030
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition event.c:1053
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition expriter.c:968
SCIP_EXPR * SCIPexpriterRestartDFS(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
Definition expriter.c:629
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition expr_value.c:294
SCIP_Real SCIPexprGetEvalValue(SCIP_EXPR *expr)
Definition expr.c:3875
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition expriter.c:857
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition expr_var.c:416
SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
Definition expr.c:3957
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition expriter.c:500
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
SCIP_Bool SCIPintervalIsEntire(SCIP_Real infinity, SCIP_INTERVAL operand)
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
void SCIPintervalMulScalar(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_Real operand2)
SCIP_Real SCIPintervalGetSup(SCIP_INTERVAL interval)
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_RETCODE SCIPnlrowChgRhs(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_Real rhs)
Definition nlp.c:1374
SCIP_RETCODE SCIPnlrowCreate(SCIP_NLROW **nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
Definition nlp.c:842
SCIP_RETCODE SCIPnlrowRelease(SCIP_NLROW **nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition nlp.c:1098
SCIP_RETCODE SCIPnlrowEnsureLinearSize(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition nlp.c:1143
SCIP_RETCODE SCIPnlrowGetNLPFeasibility(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp, SCIP_Real *feasibility)
Definition nlp.c:1491
SCIP_RETCODE SCIPnlrowIsRedundant(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *isredundant)
Definition nlp.c:1720
const char * SCIPnlrowGetName(SCIP_NLROW *nlrow)
Definition nlp.c:1852
SCIP_RETCODE SCIPnlrowChgLinearCoef(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var, SCIP_Real coef)
Definition nlp.c:1249
SCIP_Real SCIPnlrowGetRhs(SCIP_NLROW *nlrow)
Definition nlp.c:1823
SCIP_RETCODE SCIPnlrowGetActivityBounds(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *minactivity, SCIP_Real *maxactivity)
Definition nlp.c:1688
SCIP_RETCODE SCIPnlrowGetSolFeasibility(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Real *feasibility)
Definition nlp.c:1666
void SCIPnlrowSetCurvature(SCIP_NLROW *nlrow, SCIP_EXPRCURV curvature)
Definition nlp.c:1842
SCIP_RETCODE SCIPnlrowAddLinearCoef(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var, SCIP_Real val)
Definition nlp.c:1168
SCIP_RETCODE SCIPnlrowChgLhs(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_Real lhs)
Definition nlp.c:1354
SCIP_Real SCIPnlrowGetLhs(SCIP_NLROW *nlrow)
Definition nlp.c:1813
SCIP_EXPRCURV SCIPnlrowGetCurvature(SCIP_NLROW *nlrow)
Definition nlp.c:1833
SCIP_RETCODE SCIPnlrowChgExpr(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_EXPR *expr)
Definition nlp.c:1287
int SCIPnlrowGetNLPPos(SCIP_NLROW *nlrow)
Definition nlp.c:1862
SCIP_RETCODE SCIPnlrowGetNLPActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp, SCIP_Real *activity)
Definition nlp.c:1461
int SCIPnlrowGetNLinearVars(SCIP_NLROW *nlrow)
Definition nlp.c:1773
SCIP_VAR ** SCIPnlrowGetLinearVars(SCIP_NLROW *nlrow)
Definition nlp.c:1783
SCIP_RETCODE SCIPnlrowSimplify(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition nlp.c:1394
SCIP_RETCODE SCIPnlrowRecalcNLPActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp)
Definition nlp.c:1409
SCIP_RETCODE SCIPnlrowGetSolActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Real *activity)
Definition nlp.c:1617
SCIP_RETCODE SCIPnlrowPrint(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition nlp.c:1039
SCIP_RETCODE SCIPnlrowChgConstant(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_Real constant)
Definition nlp.c:1334
SCIP_Real SCIPnlrowGetDualsol(SCIP_NLROW *nlrow)
Definition nlp.c:1885
SCIP_Real SCIPnlrowGetConstant(SCIP_NLROW *nlrow)
Definition nlp.c:1763
SCIP_EXPR * SCIPnlrowGetExpr(SCIP_NLROW *nlrow)
Definition nlp.c:1803
SCIP_Bool SCIPnlrowIsInNLP(SCIP_NLROW *nlrow)
Definition nlp.c:1872
SCIP_Real * SCIPnlrowGetLinearCoefs(SCIP_NLROW *nlrow)
Definition nlp.c:1793
SCIP_RETCODE SCIPnlrowDelLinearCoef(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var)
Definition nlp.c:1216
SCIP_RETCODE SCIPnlrowCreateCopy(SCIP_NLROW **nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLROW *sourcenlrow)
Definition nlp.c:941
SCIP_RETCODE SCIPnlrowGetPseudoFeasibility(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Real *pseudofeasibility)
Definition nlp.c:1592
SCIP_RETCODE SCIPnlrowCreateFromRow(SCIP_NLROW **nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_ROW *row)
Definition nlp.c:976
SCIP_RETCODE SCIPnlrowRecalcPseudoActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp)
Definition nlp.c:1514
SCIP_RETCODE SCIPnlrowGetPseudoActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Real *pseudoactivity)
Definition nlp.c:1561
void SCIPnlrowCapture(SCIP_NLROW *nlrow)
Definition nlp.c:1086
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition lp.c:17292
int SCIProwGetNNonz(SCIP_ROW *row)
Definition lp.c:17213
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition lp.c:17238
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition lp.c:17302
const char * SCIProwGetName(SCIP_ROW *row)
Definition lp.c:17351
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition lp.c:17258
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition lp.c:17248
SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition var.c:17704
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:17570
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:17360
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:17966
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition var.c:17383
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:17748
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:17406
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:17241
SCIP_Real SCIPvarGetBestBoundLocal(SCIP_VAR *var)
Definition var.c:17986
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition var.c:17680
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition var.c:17668
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:17956
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition var.c:18072
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition var.c:11931
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition var.c:18287
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition var.c:17692
SCIP_Bool SCIPsortedvecFindPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *val, int len, int *pos)
void SCIPsortPtrReal(void **ptrarray, SCIP_Real *realarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
return SCIP_OKAY
int c
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
SCIP_Real primsol
SCIP_Real frac
static SCIP_VAR ** vars
#define NULL
Definition lpi_spx1.cpp:161
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition memory.h:464
#define BMSfreeMemory(ptr)
Definition memory.h:147
#define BMSfreeBlockMemory(mem, ptr)
Definition memory.h:467
#define BMSallocBlockMemory(mem, ptr)
Definition memory.h:453
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition memory.h:470
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition memory.h:456
#define BMScopyMemoryArray(ptr, source, num)
Definition memory.h:136
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition memory.h:469
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition memory.h:460
#define BMSclearMemoryArray(ptr, num)
Definition memory.h:132
struct BMS_BlkMem BMS_BLKMEM
Definition memory.h:439
#define BMSallocMemory(ptr)
Definition memory.h:120
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition message.c:618
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition message.c:427
SCIP_RETCODE SCIPnlpDelVar(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_VAR *var)
Definition nlp.c:3767
SCIP_Real * SCIPnlpGetVarsUbDualsol(SCIP_NLP *nlp)
Definition nlp.c:4329
SCIP_RETCODE SCIPnlpGetStatistics(SCIP_SET *set, SCIP_NLP *nlp, SCIP_NLPSTATISTICS *statistics)
Definition nlp.c:4409
static SCIP_RETCODE nlrowRemoveFixedLinearCoefPos(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, int pos)
Definition nlp.c:627
SCIP_Bool SCIPnlpIsDivingObjChanged(SCIP_NLP *nlp)
Definition nlp.c:4667
static SCIP_RETCODE nlpFlushVarAdditions(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition nlp.c:2906
static SCIP_RETCODE nlrowConstantChanged(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition nlp.c:283
SCIP_RETCODE SCIPnlpEndDive(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition nlp.c:4475
static SCIP_RETCODE nlrowChgLinearCoefPos(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, int pos, SCIP_Real coef)
Definition nlp.c:550
SCIP_NLPI * SCIPnlpGetNLPI(SCIP_NLP *nlp)
Definition nlp.c:4359
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
static SCIP_RETCODE nlpEnsureVarsSolverSize(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition nlp.c:2512
static SCIP_RETCODE nlpCalcFracVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition nlp.c:3214
static void nlrowMoveLinearCoef(SCIP_NLROW *nlrow, int oldpos, int newpos)
Definition nlp.c:369
SCIP_RETCODE SCIPnlpFree(SCIP_NLP **nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition nlp.c:3571
static SCIP_RETCODE nlrowRemoveFixedLinearCoefs(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition nlp.c:729
int SCIPnlpGetNNlRows(SCIP_NLP *nlp)
Definition nlp.c:4349
SCIP_RETCODE SCIPnlpWrite(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_MESSAGEHDLR *messagehdlr, const char *fname)
Definition nlp.c:4147
SCIP_RETCODE SCIPnlpReset(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition nlp.c:3631
SCIP_RETCODE SCIPnlpAddVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int nvars, SCIP_VAR **vars)
Definition nlp.c:3742
static SCIP_RETCODE nlpRemoveFixedVar(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_VAR *var)
Definition nlp.c:2438
SCIP_RETCODE SCIPnlpCreate(SCIP_NLP **nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, int nvars_estimate)
Definition nlp.c:3451
static SCIP_RETCODE nlpFlushNlRowDeletions(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition nlp.c:2568
SCIP_RETCODE SCIPnlpChgVarBoundsDive(SCIP_SET *set, SCIP_NLP *nlp, SCIP_VAR *var, SCIP_Real lb, SCIP_Real ub)
Definition nlp.c:4594
static SCIP_RETCODE nlpMoveVar(SCIP_NLP *nlp, int oldpos, int newpos)
Definition nlp.c:2311
SCIP_RETCODE SCIPnlpInclude(SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition nlp.c:3425
static SCIP_RETCODE nlpFlushObjective(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition nlp.c:2995
SCIP_Bool SCIPnlpHasCurrentNodeNLP(SCIP_NLP *nlp)
Definition nlp.c:3673
SCIP_RETCODE SCIPnlpDelNlRow(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLROW *nlrow)
Definition nlp.c:3890
SCIP_RETCODE SCIPnlpChgVarObjDive(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_Real coef)
Definition nlp.c:4537
SCIP_RETCODE SCIPnlpEnsureNlRowsSize(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition nlp.c:3804
static SCIP_RETCODE nlrowCalcActivityBounds(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition nlp.c:581
static SCIP_RETCODE nlrowRemoveFixedVar(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var)
Definition nlp.c:797
static SCIP_RETCODE nlpEnsureNlRowsSolverSize(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition nlp.c:2540
SCIP_Bool SCIPnlpHasSolution(SCIP_NLP *nlp)
Definition nlp.c:4430
static SCIP_RETCODE nlrowLinearCoefChanged(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_Real coef, SCIP_NLP *nlp)
Definition nlp.c:118
static void nlrowSortLinear(SCIP_NLROW *nlrow)
Definition nlp.c:329
static SCIP_RETCODE nlrowSimplifyExpr(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition nlp.c:755
SCIP_RETCODE SCIPnlpSetInitialGuess(SCIP_SET *set, SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_Real *initguess)
Definition nlp.c:4111
static SCIP_RETCODE nlpDelNlRowPos(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int pos)
Definition nlp.c:2056
SCIP_RETCODE SCIPnlpGetVarsNonlinearity(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int *nlcount)
Definition nlp.c:4222
static SCIP_RETCODE nlpUpdateVarBounds(SCIP_NLP *nlp, SCIP_SET *set, SCIP_VAR *var, SCIP_Bool tightened)
Definition nlp.c:2111
static SCIP_RETCODE nlpFlushVarDeletions(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition nlp.c:2662
static SCIP_RETCODE nlpRowChanged(SCIP_NLP *nlp, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLROW *nlrow)
Definition nlp.c:1905
static int nlrowSearchLinearCoef(SCIP_NLROW *nlrow, SCIP_VAR *var)
Definition nlp.c:347
SCIP_RETCODE SCIPnlpRemoveRedundantNlRows(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition nlp.c:4065
SCIP_RETCODE SCIPnlpAddNlRows(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int nnlrows, SCIP_NLROW **nlrows)
Definition nlp.c:3860
SCIP_RETCODE SCIPnlpGetPseudoObjval(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Real *pseudoobjval)
Definition nlp.c:3997
static SCIP_RETCODE nlrowExprChanged(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition nlp.c:204
static SCIP_RETCODE nlpSolve(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLPPARAM *nlpparam)
Definition nlp.c:3053
static SCIP_RETCODE nlpFlushNlRowAdditions(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition nlp.c:2758
SCIP_RETCODE SCIPnlpChgVarsBoundsDive(SCIP_NLP *nlp, SCIP_SET *set, int nvars, SCIP_VAR **vars, SCIP_Real *lbs, SCIP_Real *ubs)
Definition nlp.c:4623
SCIP_NLPTERMSTAT SCIPnlpGetTermstat(SCIP_NLP *nlp)
Definition nlp.c:4399
static SCIP_RETCODE nlpSetupNlpiIndices(SCIP_NLP *nlp, SCIP_SET *set, SCIP_NLROW *nlrow, int **linidxs)
Definition nlp.c:2470
static SCIP_RETCODE nlrowSideChanged(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition nlp.c:245
SCIP_RETCODE SCIPnlpAddNlRow(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLROW *nlrow)
Definition nlp.c:3834
static SCIP_RETCODE nlrowAddLinearCoef(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var, SCIP_Real coef)
Definition nlp.c:392
SCIP_RETCODE SCIPnlpEnsureVarsSize(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition nlp.c:3682
#define EVENTHDLR_DESC
Definition nlp.c:71
SCIP_VAR ** SCIPnlpGetVars(SCIP_NLP *nlp)
Definition nlp.c:4202
SCIP_RETCODE SCIPnlpFlush(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition nlp.c:3922
SCIP_NLPIPROBLEM * SCIPnlpGetNLPIProblem(SCIP_NLP *nlp)
Definition nlp.c:4369
int SCIPnlpGetNVars(SCIP_NLP *nlp)
Definition nlp.c:4212
static SCIP_RETCODE nlpAddVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int nvars, SCIP_VAR **vars)
Definition nlp.c:2232
SCIP_RETCODE SCIPnlpGetFracVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR ***fracvars, SCIP_Real **fracvarssol, SCIP_Real **fracvarsfrac, int *nfracvars, int *npriofracvars)
Definition nlp.c:4031
static SCIP_RETCODE nlpDelVarPos(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition nlp.c:2344
static void nlpMoveNlrow(SCIP_NLP *nlp, int oldpos, int newpos)
Definition nlp.c:2028
SCIP_RETCODE SCIPnlpStartDive(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition nlp.c:4444
SCIP_Real * SCIPnlpGetVarsLbDualsol(SCIP_NLP *nlp)
Definition nlp.c:4319
SCIP_RETCODE SCIPnlpSolve(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLPPARAM *nlpparam)
Definition nlp.c:3960
#define EVENTHDLR_NAME
Definition nlp.c:70
SCIP_Real SCIPnlpGetObjval(SCIP_NLP *nlp)
Definition nlp.c:3987
static SCIP_RETCODE nlrowDelLinearCoefPos(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, int pos)
Definition nlp.c:521
static SCIP_RETCODE nlpAddNlRows(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int nnlrows, SCIP_NLROW **nlrows)
Definition nlp.c:1941
SCIP_NLROW ** SCIPnlpGetNlRows(SCIP_NLP *nlp)
Definition nlp.c:4339
SCIP_RETCODE SCIPnlpHasContinuousNonlinearity(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *result)
Definition nlp.c:4276
static SCIP_RETCODE nlpUpdateObjCoef(SCIP_SET *set, SCIP_NLP *nlp, SCIP_VAR *var)
Definition nlp.c:2170
SCIP_Bool SCIPnlpIsDiving(SCIP_NLP *nlp)
Definition nlp.c:4379
SCIP_NLPSOLSTAT SCIPnlpGetSolstat(SCIP_NLP *nlp)
Definition nlp.c:4389
SCIP_RETCODE SCIPnlpAddVar(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_VAR *var)
Definition nlp.c:3716
internal methods for NLP management
SCIP_RETCODE SCIPnlpiSetInitialGuess(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_Real *primalvalues, SCIP_Real *consdualvalues, SCIP_Real *varlbdualvalues, SCIP_Real *varubdualvalues)
Definition nlpi.c:528
SCIP_RETCODE SCIPnlpiChgVarBounds(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, const int nvars, const int *indices, const SCIP_Real *lbs, const SCIP_Real *ubs)
Definition nlpi.c:376
SCIP_RETCODE SCIPnlpiSetObjective(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nlins, const int *lininds, const SCIP_Real *linvals, SCIP_EXPR *expr, const SCIP_Real constant)
Definition nlpi.c:352
SCIP_RETCODE SCIPnlpiGetStatistics(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_NLPSTATISTICS *statistics)
Definition nlpi.c:675
SCIP_NLPSOLSTAT SCIPnlpiGetSolstat(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
Definition nlpi.c:621
SCIP_RETCODE SCIPnlpiFreeProblem(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM **problem)
Definition nlpi.c:266
SCIP_RETCODE SCIPnlpiDelVarSet(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int *dstats, int dstatssize)
Definition nlpi.c:422
SCIP_RETCODE SCIPnlpiAddConstraints(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nconss, const SCIP_Real *lhss, const SCIP_Real *rhss, const int *nlininds, int *const *lininds, SCIP_Real *const *linvals, SCIP_EXPR **exprs, const char **names)
Definition nlpi.c:325
SCIP_RETCODE SCIPnlpiSolve(SCIP_SET *set, SCIP_STAT *stat, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_NLPPARAM *param)
Definition nlpi.c:551
SCIP_RETCODE SCIPnlpiDelConsSet(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int *dstats, int dstatssize)
Definition nlpi.c:443
SCIP_RETCODE SCIPnlpiAddVars(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
Definition nlpi.c:302
SCIP_RETCODE SCIPnlpiGetSolution(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_Real **primalvalues, SCIP_Real **consdualvalues, SCIP_Real **varlbdualvalues, SCIP_Real **varubdualvalues, SCIP_Real *objval)
Definition nlpi.c:653
SCIP_RETCODE SCIPnlpiChgExpr(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int idxcons, SCIP_EXPR *expr)
Definition nlpi.c:487
SCIP_RETCODE SCIPnlpiChgConsSides(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nconss, const int *indices, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition nlpi.c:399
SCIP_NLPTERMSTAT SCIPnlpiGetTermstat(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
Definition nlpi.c:636
SCIP_RETCODE SCIPnlpiCreateProblem(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM **problem, const char *name)
Definition nlpi.c:244
SCIP_RETCODE SCIPnlpiChgLinearCoefs(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int idx, int nvals, const int *varidxs, const SCIP_Real *vals)
Definition nlpi.c:464
internal methods for NLP solver interfaces
internal methods for collecting primal CIP solutions and primal informations
public methods for managing events
public functions to work with algebraic expressions
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebugMessage
Definition pub_message.h:96
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for NLP management
public methods for problem variables
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6227
SCIP_Bool SCIPsetIsFeasFracIntegral(SCIP_SET *set, SCIP_Real val)
Definition set.c:6685
SCIP_Real SCIPsetFeastol(SCIP_SET *set)
Definition set.c:6040
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6597
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6575
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6155
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6553
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition set.c:5998
SCIP_RETCODE SCIPsetIncludeEventhdlr(SCIP_SET *set, SCIP_EVENTHDLR *eventhdlr)
Definition set.c:4677
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition set.c:6133
void SCIPsetSortNlpis(SCIP_SET *set)
Definition set.c:5133
SCIP_NLPI * SCIPsetFindNlpi(SCIP_SET *set, const char *name)
Definition set.c:5113
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:6245
SCIP_Real SCIPsetFeasFrac(SCIP_SET *set, SCIP_Real val)
Definition set.c:6731
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6619
SCIP_EVENTHDLR * SCIPsetFindEventhdlr(SCIP_SET *set, const char *name)
Definition set.c:4700
SCIP_Bool SCIPsetIsRelLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:7054
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition set.c:5712
internal methods for global SCIP settings
#define SCIPsetFreeBufferArray(set, ptr)
Definition set.h:1741
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition set.h:1734
#define SCIPsetDebugMsg
Definition set.h:1770
SCIP_RETCODE SCIPsolCreateNLPSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp, SCIP_HEUR *heur)
Definition sol.c:631
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition sol.c:801
SCIP_RETCODE SCIPsolCreatePseudoSol(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:678
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition sol.c:1372
internal methods for storing primal CIP solutions
SCIP_EXPR * expr
Definition struct_nlp.h:81
int linvarssize
Definition struct_nlp.h:75
SCIP_Longint validactivitybdsdomchg
Definition struct_nlp.h:92
int nlpiindex
Definition struct_nlp.h:94
SCIP_EXPRCURV curvature
Definition struct_nlp.h:96
SCIP_Real minactivity
Definition struct_nlp.h:90
char * name
Definition struct_nlp.h:84
SCIP_Real lhs
Definition struct_nlp.h:67
SCIP_Longint validactivitynlp
Definition struct_nlp.h:87
double * lincoefs
Definition struct_nlp.h:77
SCIP_Real activity
Definition struct_nlp.h:86
SCIP_Real maxactivity
Definition struct_nlp.h:91
SCIP_Real pseudoactivity
Definition struct_nlp.h:88
SCIP_Real dualsol
Definition struct_nlp.h:95
SCIP_Real rhs
Definition struct_nlp.h:68
SCIP_Real constant
Definition struct_nlp.h:71
SCIP_VAR ** linvars
Definition struct_nlp.h:76
SCIP_Longint validpsactivitydomchg
Definition struct_nlp.h:89
SCIP_Bool linvarssorted
Definition struct_nlp.h:78
SCIP_Real primalsolobjval
Definition struct_nlp.h:142
int sizevars_solver
Definition struct_nlp.h:120
SCIP_NLROW * divingobj
Definition struct_nlp.h:135
SCIP_Bool objflushed
Definition struct_nlp.h:134
SCIP_Longint validfracvars
Definition struct_nlp.h:159
int sizenlrows_solver
Definition struct_nlp.h:130
SCIP_VAR ** fracvars
Definition struct_nlp.h:153
SCIP_Bool haveinitguess
Definition struct_nlp.h:138
int sizevars
Definition struct_nlp.h:115
SCIP_EVENTHDLR * eventhdlr
Definition struct_nlp.h:149
int * nlrowmap_nlpi2nlp
Definition struct_nlp.h:131
int nnlrows
Definition struct_nlp.h:125
int fracvarssize
Definition struct_nlp.h:158
char * name
Definition struct_nlp.h:162
int nunflushednlrowdel
Definition struct_nlp.h:110
int nunflushednlrowadd
Definition struct_nlp.h:109
int npriofracvars
Definition struct_nlp.h:157
int sizenlrows
Definition struct_nlp.h:126
SCIP_NLPSOLSTAT solstat
Definition struct_nlp.h:143
SCIP_Real * fracvarsfrac
Definition struct_nlp.h:155
int nvars_solver
Definition struct_nlp.h:119
SCIP_HASHMAP * varhash
Definition struct_nlp.h:117
SCIP_NLPI * solver
Definition struct_nlp.h:103
int nunflushedvaradd
Definition struct_nlp.h:107
int nnlrows_solver
Definition struct_nlp.h:129
SCIP_NLPTERMSTAT termstat
Definition struct_nlp.h:144
SCIP_NLROW ** nlrows
Definition struct_nlp.h:127
SCIP_VAR ** vars
Definition struct_nlp.h:116
int * varmap_nlp2nlpi
Definition struct_nlp.h:121
SCIP_NLPIPROBLEM * problem
Definition struct_nlp.h:104
SCIP_Real * varubdualvals
Definition struct_nlp.h:146
int nfracvars
Definition struct_nlp.h:156
SCIP_Bool indiving
Definition struct_nlp.h:111
int * varmap_nlpi2nlp
Definition struct_nlp.h:122
SCIP_Real * varlbdualvals
Definition struct_nlp.h:145
int nunflushedvardel
Definition struct_nlp.h:108
SCIP_Real * initialguess
Definition struct_nlp.h:139
SCIP_Real * fracvarssol
Definition struct_nlp.h:154
SCIP_Longint nnlps
SCIP_Longint domchgcount
SCIP_CLOCK * nlpsoltime
datastructures for NLP management
SCIP main data structure.
datastructures for global SCIP settings
datastructures for problem statistics
#define MAX(x, y)
Definition tclique_def.h:92
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition type_event.h:125
struct SCIP_EventData SCIP_EVENTDATA
Definition type_event.h:173
#define SCIP_EVENTTYPE_OBJCHANGED
Definition type_event.h:74
#define SCIP_EVENTTYPE_VARFIXED
Definition type_event.h:72
#define SCIP_EVENTTYPE_VARDELETED
Definition type_event.h:71
#define SCIP_DECL_EVENTEXEC(x)
Definition type_event.h:253
#define SCIP_EVENTTYPE_FORMAT
Definition type_event.h:152
#define SCIP_EVENTTYPE_VARADDED
Definition type_event.h:70
uint64_t SCIP_EVENTTYPE
Definition type_event.h:151
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition type_event.h:123
SCIP_EXPRCURV
Definition type_expr.h:58
@ SCIP_EXPRCURV_LINEAR
Definition type_expr.h:62
@ SCIP_EXPRITER_DFS
Definition type_expr.h:700
#define SCIP_DECL_EXPR_MAPEXPR(x)
Definition type_expr.h:179
enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
Definition type_nlpi.h:168
@ SCIP_NLPTERMSTAT_OTHER
Definition type_nlpi.h:182
@ SCIP_NLPSOLSTAT_UNBOUNDED
Definition type_nlpi.h:165
@ SCIP_NLPSOLSTAT_GLOBINFEASIBLE
Definition type_nlpi.h:164
@ SCIP_NLPSOLSTAT_LOCINFEASIBLE
Definition type_nlpi.h:163
@ SCIP_NLPSOLSTAT_FEASIBLE
Definition type_nlpi.h:162
@ SCIP_NLPSOLSTAT_LOCOPT
Definition type_nlpi.h:161
@ SCIP_NLPSOLSTAT_GLOBOPT
Definition type_nlpi.h:160
@ SCIP_NLPSOLSTAT_UNKNOWN
Definition type_nlpi.h:166
enum SCIP_NlpTermStat SCIP_NLPTERMSTAT
Definition type_nlpi.h:194
@ SCIP_FILECREATEERROR
@ SCIP_INVALIDDATA
@ SCIP_PLUGINNOTFOUND
@ SCIP_ERROR
enum SCIP_Retcode SCIP_RETCODE
@ SCIP_STAGE_INIT
Definition type_set.h:44
@ SCIP_VARTYPE_INTEGER
Definition type_var.h:63
@ SCIP_VARTYPE_CONTINUOUS
Definition type_var.h:71
@ SCIP_VARTYPE_BINARY
Definition type_var.h:62
@ SCIP_VARSTATUS_MULTAGGR
Definition type_var.h:54
SCIP_RETCODE SCIPvarRelease(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition var.c:2872
SCIP_RETCODE SCIPvarDropEvent(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition var.c:18407
SCIP_RETCODE SCIPvarSetNLPSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real solval)
Definition var.c:13995
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition var.c:3006
void SCIPvarCapture(SCIP_VAR *var)
Definition var.c:2847
SCIP_RETCODE SCIPvarCatchEvent(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition var.c:18380
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition var.c:12636
internal methods for problem variables