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