Scippy

SCIP

Solving Constraint Integer Programs

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