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