SCIP Doxygen Documentation
Loading...
Searching...
No Matches
reader_zpl.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-2026 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 reader_zpl.c
26 * @ingroup DEFPLUGINS_READER
27 * @brief ZIMPL model file reader
28 * @author Tobias Achterberg
29 * @author Timo Berthold
30 */
31
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33
34#include "scip/reader_zpl.h"
35
36#ifdef SCIP_WITH_ZIMPL
37
38#include <unistd.h>
39#include <stdbool.h>
40#ifdef _MSC_VER
41#include <direct.h>
42#define getcwd _getcwd
43#endif
44
46#include "scip/cons_indicator.h"
47#include "scip/cons_linear.h"
48#include "scip/cons_sos1.h"
49#include "scip/cons_sos2.h"
50#include "scip/pub_misc.h"
51#include "scip/pub_nlp.h"
52#include "scip/pub_reader.h"
53#include "scip/pub_var.h"
54#include "scip/scip_cons.h"
55#include "scip/scip_exact.h"
56#include "scip/scip_general.h"
57#include "scip/scip_mem.h"
58#include "scip/scip_message.h"
59#include "scip/scip_numerics.h"
60#include "scip/scip_param.h"
61#include "scip/scip_prob.h"
62#include "scip/scip_reader.h"
63#include "scip/scip_sol.h"
64#include "scip/scip_var.h"
65#include "scip/cons_nonlinear.h"
66#include "scip/struct_misc.h"
67#include "scip/expr_pow.h"
68#include "scip/expr_log.h"
69#include "scip/expr_exp.h"
70#include "scip/expr_abs.h"
71#include "scip/expr_sum.h"
72#include "scip/expr_trig.h"
73#include "scip/expr_product.h"
74#include "scip/pub_expr.h"
75#include "scip/type_reader.h"
76
77#ifdef __cplusplus
78extern "C" {
79#endif
80
81/* @Note: Due to dependencies we need the following order. */
82/* include the ZIMPL headers necessary to define the LP and MINLP construction interface */
83#ifdef SCIP_WITH_GMP
84#include <gmp.h>
85#endif
86#include "zimpl/attribute.h"
87#include "zimpl/ratlptypes.h"
88#include "zimpl/lint.h"
89#include "zimpl/mme.h"
90
91#include "zimpl/numb.h"
92#include "zimpl/bound.h"
93#include "zimpl/mono.h"
94#include "zimpl/term.h"
95
96#include "zimpl/xlpglue.h"
97#include "zimpl/zimpllib.h"
98#include "scip/rational.h"
99#include "scip/rationalgmp.h"
100
101#ifdef __cplusplus
102}
103#endif
104
105/* disable warning that our callbacks, like xlp_addvar, may return NULL if there was an error earlier,
106 * even though they were declared __attribute__((__nonnull__))
107 */
108#if defined(__clang__)
109#pragma clang diagnostic ignored "-Wnonnull"
110#endif
111
112#define READER_NAME "zplreader"
113#define READER_DESC "file reader for ZIMPL model files"
114#define READER_EXTENSION "zpl"
115
116/*
117 * LP construction interface of ZIMPL
118 */
119
120/* we only support ZIMPL with a version higher than 3.4.1 */
121#if (ZIMPL_VERSION >= 341)
122
123/* ZIMPL does not support user data in callbacks - we have to use static variables */
124struct
125SCIP_ReaderData
126{
127 SCIP* scip; /**< scip data structure */
128 SCIP_SOL* sol; /**< primal solution candidate */
129 SCIP_Bool valid; /**< is the primal solution candidate valid */
130 SCIP_Bool branchpriowarning; /**< store if the waring regarding fractional value for the branching
131 * priority was already posted */
132 SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
133 SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
134 SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
135 SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
136 SCIP_Bool readerror; /**< was a reading error be discovered */
137 SCIP_RETCODE retcode; /**< store a none SCIP_OKAY return code if an error occurred */
138};
139
140#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_BOOST)
141/** convert between scips_rational and zimpl's numb type */
142static
143SCIP_RETCODE RcreateNumb(
144 BMS_BLKMEM* mem,
145 SCIP_RATIONAL** rational,
146 const Numb* numb
147 )
148{
149 mpq_t temp;
150
151 mpq_init(temp);
152 numb_get_mpq(numb, temp);
153
154 SCIPdebug(gmp_printf("the rational is: %Qd\n",temp));
155
156 SCIP_CALL( SCIPrationalCreateBlockGMP(mem, rational, temp) );
157 mpq_clear(temp);
158
159 return SCIP_OKAY;
160}
161#else
162/** convert between scips_rational and zimpl's numb type */
163static
164SCIP_RETCODE RcreateNumb(
165 BMS_BLKMEM* mem,
166 SCIP_RATIONAL** rational,
167 const Numb* numb
168 )
169{
170 SCIP_CALL( SCIPrationalCreateBlock(mem, rational) );
171 SCIPrationalSetReal(*rational, numb_todbl(numb));
172 return SCIP_OKAY;
173}
174#endif
175
176/** abort the reading with an errormessage; this type of constraint is not supported
177 * in exact solving
178 */
179static
180SCIP_RETCODE abortReadIfExact(
181 SCIP* scip, /**< scip data structure */
182 SCIP_Bool* created, /**< store if a cons was created or NULL */
183 const char* errmsg /**< Error Message */
184 )
185{
186 if( SCIPisExact(scip) )
187 {
188 SCIPerrorMessage("%s\n",errmsg);
189 if( created != NULL )
190 (*created) = FALSE;
191 return SCIP_ERROR;
192 }
193 else
194 return SCIP_OKAY;
195}
196
197/** create problem */
198static
199SCIP_RETCODE createProb(
200 SCIP* scip, /**< SCIP data structure */
201 SCIP_READERDATA* readerdata, /**< reader data */
202 const char* name /**< name of the problem */
203 )
204{
205 SCIP_Bool usestartsol;
206
207 /* create problem */
209
210 /* check if are interested in the primal solution candidate */
211 SCIP_CALL( SCIPgetBoolParam(scip, "reading/zplreader/usestartsol", &usestartsol) );
212
213 if( usestartsol )
214 {
215 /* create primal solution */
216 if( SCIPisExact(scip) )
217 {
218 SCIP_CALL( SCIPcreateSolExact(scip, &readerdata->sol, NULL) );
219 }
220 else
221 {
222 SCIP_CALL( SCIPcreateSol(scip, &readerdata->sol, NULL) );
223 }
224 readerdata->valid = TRUE;
225 }
226
227 return SCIP_OKAY;
228}
229
230/** Allocate storage for the mathematical program instance generated by ZIMPL. xlp_alloc() is the first xlpglue routine
231 * that will be called by ZIMPL. The user_data pointer may hold an arbitray value.
232 */
233Lps* xlp_alloc(
234 const char* name, /**< name of the problem */
235 bool need_startval, /**< does ZIMPL provides a primal solution candidate */
236 void* user_data /**< user data which was previously passed to ZIMPL */
237 )
238{ /*lint --e{715}*/
239 SCIP* scip;
240 SCIP_READERDATA* readerdata;
241
242 readerdata = (SCIP_READERDATA*)user_data;
243 assert(readerdata != NULL);
244 assert(readerdata->retcode == SCIP_OKAY);
245 assert(!readerdata->readerror);
246
247 scip = readerdata->scip;
248 assert(scip != NULL);
249
250 readerdata->retcode = createProb(scip, readerdata, name);
251
252 /* return the reader data pointer to receive it all other ZIMPL call backs */
253 return (Lps*) readerdata;
254}
255
256/** free storage for mathematical program. xlp_free() is the last xlpglue routine that will be called by Zimpl */
257void xlp_free(
258 Lps* lp /**< pointer to reader data */
259 )
260{ /*lint --e{715}*/
261 /* nothing to be done here */
262}
263
264/** does there already exists a constraint with the given name? */
265bool xlp_conname_exists(
266 const Lps* lp, /**< pointer to reader data */
267 const char* conname /**< constraint name to check */
268 )
269{
270 SCIP_READERDATA* readerdata;
271
272 readerdata = (SCIP_READERDATA*)lp;
273 assert(readerdata != NULL);
274
275 /* check if constraint with the given name already exists */
276 return (SCIPfindCons(readerdata->scip, conname) != NULL);
277}
278
279/** create a SCIP expression from a ZIMPL term
280 *
281 * Returns *expr == NULL if could not create expression due to unsupported ZIMPL functions.
282 */
283static
284SCIP_RETCODE createExpr(
285 SCIP* scip, /**< SCIP data structure */
286 SCIP_READERDATA* readerdata, /**< reader data */
287 SCIP_EXPR** expr, /**< buffer to store expression */
288 const Term* term /**< term to convert to expression */
289 )
290{
291 assert(scip != NULL);
292 assert(readerdata != NULL);
293 assert(expr != NULL);
294 assert(term != NULL);
295
296 *expr = NULL;
297
298 if( term_get_degree(term) == 2 )
299 {
300 int nlinvars;
301 int nquadterms;
302 SCIP_VAR** linvars;
303 SCIP_VAR** quadvar1;
304 SCIP_VAR** quadvar2;
305 SCIP_Real* lincoefs;
306 SCIP_Real* quadcoefs;
307 Mono* monom;
308 int i;
309
310 nlinvars = 0;
311 nquadterms = 0;
312
313 SCIP_CALL( SCIPallocBufferArray(scip, &linvars, term_get_elements(term)) );
314 SCIP_CALL( SCIPallocBufferArray(scip, &quadvar1, term_get_elements(term)) );
315 SCIP_CALL( SCIPallocBufferArray(scip, &quadvar2, term_get_elements(term)) );
316 SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, term_get_elements(term)) );
317 SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, term_get_elements(term)) );
318
319 for( i = 0; i < term_get_elements(term); ++i )
320 {
321 monom = term_get_element(term, i);
322 assert(!numb_equal(mono_get_coeff(monom), numb_zero()));
323 assert(mono_get_degree(monom) <= 2);
324 assert(mono_get_degree(monom) > 0);
325 if (mono_get_degree(monom) == 1)
326 {
327 linvars [nlinvars] = (SCIP_VAR*)mono_get_var(monom, 0);
328 lincoefs[nlinvars] = numb_todbl(mono_get_coeff(monom));
329 ++nlinvars;
330 }
331 else
332 {
333 assert(mono_get_degree(monom) == 2);
334 quadvar1 [nquadterms] = (SCIP_VAR*)mono_get_var(monom, 0);
335 quadvar2 [nquadterms] = (SCIP_VAR*)mono_get_var(monom, 1);
336 quadcoefs[nquadterms] = numb_todbl(mono_get_coeff(monom));
337 ++nquadterms;
338 }
339 }
340
341 SCIP_CALL( SCIPcreateExprQuadratic(scip, expr, nlinvars, linvars, lincoefs, nquadterms, quadvar1, quadvar2, quadcoefs, NULL, NULL) );
342
343 SCIPfreeBufferArray(scip, &linvars);
344 SCIPfreeBufferArray(scip, &quadvar1);
345 SCIPfreeBufferArray(scip, &quadvar2);
346 SCIPfreeBufferArray(scip, &lincoefs);
347 SCIPfreeBufferArray(scip, &quadcoefs);
348 }
349 else
350 {
351 SCIP_VAR** polyvars;
352 SCIP_Real* polyexps;
353 SCIP_HASHMAP* varexpmap;
354 SCIP_EXPR** monomials;
355 int nmonomials;
356 int monomialssize;
357 SCIP_Real* coefs;
358 Mono* monomial;
359 SCIP_EXPR* monomialexpr;
360 SCIP_Bool created;
361 int varpos;
362 int i;
363 int j;
364
365 polyvars = NULL;
366 polyexps = NULL;
367
368 monomials = NULL;
369 nmonomials = 0;
370 monomialssize = 0;
371 coefs = NULL;
372 created = TRUE;
373
375
376 for( i = 0; i < term_get_elements(term); ++i )
377 {
378 monomial = term_get_element(term, i);
379 assert(monomial != NULL);
380 assert(!numb_equal(mono_get_coeff(monomial), numb_zero()));
381 assert(mono_get_degree(monomial) > 0);
382
383 /* allocate space in the monomials array */
384 if( monomialssize == 0 )
385 {
386 monomialssize = SCIPcalcMemGrowSize(scip, 1);
387 SCIP_CALL( SCIPallocBufferArray(scip, &monomials, monomialssize) );
388 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, monomialssize) );
389 }
390 else if( monomialssize < nmonomials + 1 )
391 {
392 monomialssize = SCIPcalcMemGrowSize(scip, nmonomials+1);
393 SCIP_CALL( SCIPreallocBufferArray(scip, &monomials, monomialssize) );
394 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, monomialssize) );
395 }
396 assert(monomials != NULL);
397 assert(coefs != NULL);
398
399 /* create SCIP monomial expression */
400 for( j = 0; j < mono_get_degree(monomial); ++j )
401 {
402 SCIP_Real exponent;
403
404 exponent = SCIPhashmapGetImageReal(varexpmap, (void*)mono_get_var(monomial, j));
405 exponent = exponent == SCIP_INVALID ? 1.0 : exponent + 1.0;
406
407 SCIP_CALL( SCIPhashmapSetImageReal(varexpmap, (void*)mono_get_var(monomial, j), exponent) );
408 }
409
412
413 varpos = 0;
414
415 for( j = 0; j < SCIPhashmapGetNEntries(varexpmap); ++j )
416 {
417 SCIP_HASHMAPENTRY* entry;
418
419 entry = SCIPhashmapGetEntry(varexpmap, j);
420 if( entry == NULL )
421 continue;
422
423 polyvars[varpos] = (SCIP_VAR*) SCIPhashmapEntryGetOrigin(entry);
424 polyexps[varpos] = SCIPhashmapEntryGetImageReal(entry);
425 ++varpos;
426 }
427 assert(varpos == SCIPhashmapGetNElements(varexpmap));
428 SCIPhashmapRemoveAll(varexpmap);
429
430 SCIP_CALL( SCIPcreateExprMonomial(scip, &monomialexpr, varpos, polyvars, polyexps, NULL, NULL) );
431
432 SCIPfreeBufferArrayNull(scip, &polyexps);
433 SCIPfreeBufferArrayNull(scip, &polyvars);
434
435 /* add monomial to array, possibly with an extra function around it */
436 if( mono_get_function(monomial) == MFUN_NONE )
437 {
438 monomials[nmonomials] = monomialexpr;
439 coefs[nmonomials] = numb_todbl(mono_get_coeff(monomial));
440 }
441 else
442 {
443 SCIP_EXPR* cosexpr;
444 SCIP_EXPR* prodchildren[2];
445
446 coefs[nmonomials] = 1.0;
447
448 /* nonlinear monomial with an extra function around it */
449 switch( mono_get_function(monomial) )
450 {
451 case MFUN_SQRT:
452 SCIP_CALL( SCIPcreateExprPow(scip, &monomials[nmonomials], monomialexpr, 0.5, NULL, NULL) );
453 break;
454 case MFUN_LOG:
455 /* log10(x) = ln(x) / ln(10.0) */
456 coefs[nmonomials] = 1.0 / log(10.0);
457 SCIP_CALL( SCIPcreateExprLog(scip, &monomials[nmonomials], monomialexpr, NULL, NULL) );
458 break;
459 case MFUN_EXP:
460 SCIP_CALL( SCIPcreateExprExp(scip, &monomials[nmonomials], monomialexpr, NULL, NULL) );
461 break;
462 case MFUN_LN:
463 SCIP_CALL( SCIPcreateExprLog(scip, &monomials[nmonomials], monomialexpr, NULL, NULL) );
464 break;
465 case MFUN_SIN:
466 SCIP_CALL( SCIPcreateExprSin(scip, &monomials[nmonomials], monomialexpr, NULL, NULL) );
467 break;
468 case MFUN_COS:
469 SCIP_CALL( SCIPcreateExprCos(scip, &monomials[nmonomials], monomialexpr, NULL, NULL) );
470 break;
471 case MFUN_TAN:
472 SCIP_CALL( SCIPcreateExprSin(scip, &prodchildren[0], monomialexpr, NULL, NULL) );
473 SCIP_CALL( SCIPcreateExprCos(scip, &cosexpr, monomialexpr, NULL, NULL) );
474 SCIP_CALL( SCIPcreateExprPow(scip, &prodchildren[1], cosexpr, -1.0, NULL, NULL) );
475 SCIP_CALL( SCIPcreateExprProduct(scip, &monomials[nmonomials], 2, prodchildren, 1.0, NULL, NULL) );
476
477 SCIP_CALL( SCIPreleaseExpr(scip, &prodchildren[1]) );
478 SCIP_CALL( SCIPreleaseExpr(scip, &cosexpr) );
479 SCIP_CALL( SCIPreleaseExpr(scip, &prodchildren[0]) );
480
481 break;
482 case MFUN_ABS:
483 SCIP_CALL( SCIPcreateExprAbs(scip, &monomials[nmonomials], monomialexpr, NULL, NULL) );
484 break;
485 case MFUN_POW:
486 SCIP_CALL( SCIPcreateExprPow(scip, &monomials[nmonomials], monomialexpr,
487 numb_todbl(mono_get_coeff(monomial)), NULL, NULL) );
488 break;
489 case MFUN_SGNPOW:
490 SCIP_CALL( SCIPcreateExprSignpower(scip, &monomials[nmonomials], monomialexpr,
491 numb_todbl(mono_get_coeff(monomial)), NULL, NULL) );
492 break;
493 case MFUN_NONE:
494 case MFUN_TRUE:
495 case MFUN_FALSE:
496 SCIPerrorMessage("ZIMPL function %d invalid here.\n", mono_get_function(monomial));
497 created = FALSE;
498 break;
499 default:
500 SCIPerrorMessage("ZIMPL function %d not supported\n", mono_get_function(monomial));
501 created = FALSE;
502 break;
503 } /*lint !e788*/
504
505 SCIP_CALL( SCIPreleaseExpr(scip, &monomialexpr) );
506 }
507
508 ++nmonomials;
509
510 if( !created )
511 break;
512 }
513
514 if( created )
515 {
516 SCIP_CALL( SCIPcreateExprSum(scip, expr, nmonomials, monomials, coefs, 0.0, NULL, NULL) );
517 }
518
519 /* free memory */
520 for( j = nmonomials - 1; j >= 0; --j )
521 {
522 if( monomials[j] != NULL )
523 {
524 SCIP_CALL( SCIPreleaseExpr(scip, &monomials[j]) );
525 }
526 }
527
529 SCIPfreeBufferArrayNull(scip, &monomials);
530 SCIPhashmapFree(&varexpmap);
531 }
532
533 return SCIP_OKAY;
534}
535
536/** method creates a constraint and is called directly from ZIMPL
537 *
538 * @note this method is used by ZIMPL beginning from version 3.00
539 */
540static
541SCIP_RETCODE addConsTerm(
542 SCIP* scip, /**< SCIP data structure */
543 SCIP_READERDATA* readerdata, /**< reader data */
544 const char* name, /**< constraint name */
545 ConType type, /**< constraint type (LHS, RHS, EQUAL, RANGE, etc) */
546 const Numb* lhs, /**< left hand side */
547 const Numb* rhs, /**< right hand side */
548 unsigned int flags, /**< special constraint flags, see ratlptypes.h */
549 const Term* term, /**< term to use */
550 SCIP_Bool* created /**< pointer to store if a constraint was created */
551 )
552{
553 SCIP_CONS* cons;
554 SCIP_RATIONAL* ratlhs = NULL;
555 SCIP_RATIONAL* ratrhs = NULL;
556 SCIP_Real sciplhs;
557 SCIP_Real sciprhs;
558 SCIP_Bool initial;
560 SCIP_Bool enforce;
561 SCIP_Bool check;
563 SCIP_Bool local;
564 SCIP_Bool modifiable;
565 SCIP_Bool usercut;
566 SCIP_Bool lazycut;
567 int i;
568
569 if( SCIPisExact(scip) )
570 {
571 /* get exact lhs and rhs */
572 switch( type )
573 {
574 case CON_FREE:
577 break;
578 case CON_LHS:
579 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &ratlhs, lhs) );
581 break;
582 case CON_RHS:
583 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &ratrhs, rhs) );
585 break;
586 case CON_RANGE:
587 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &ratlhs, lhs) );
588 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &ratrhs, rhs) );
589 break;
590 case CON_EQUAL:
591 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &ratlhs, lhs) );
592 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &ratrhs, rhs) );
593 assert(SCIPrationalIsEQ(ratrhs, ratlhs));
594 break;
595 default:
596 SCIPwarningMessage(scip, "invalid constraint type <%d> in ZIMPL callback xlp_addcon()\n", type);
597 readerdata->readerror = TRUE;
598 break;
599 }
600 }
601 switch( type )
602 {
603 case CON_FREE:
604 sciplhs = -SCIPinfinity(scip);
605 sciprhs = SCIPinfinity(scip);
606 break;
607 case CON_LHS:
608 sciplhs = (SCIP_Real)numb_todbl(lhs);
609 sciprhs = SCIPinfinity(scip);
610 break;
611 case CON_RHS:
612 sciplhs = -SCIPinfinity(scip);
613 sciprhs = (SCIP_Real)numb_todbl(rhs);
614 break;
615 case CON_RANGE:
616 sciplhs = (SCIP_Real)numb_todbl(lhs);
617 sciprhs = (SCIP_Real)numb_todbl(rhs);
618 break;
619 case CON_EQUAL:
620 sciplhs = (SCIP_Real)numb_todbl(lhs);
621 sciprhs = (SCIP_Real)numb_todbl(rhs);
622 assert(sciplhs == sciprhs); /*lint !e777*/
623 break;
624 default:
625 SCIPwarningMessage(scip, "invalid constraint type <%d> in ZIMPL callback xlp_addcon()\n", type);
626 sciplhs = (SCIP_Real)numb_todbl(lhs);
627 sciprhs = (SCIP_Real)numb_todbl(rhs);
628 readerdata->readerror = TRUE;
629 break;
630 }
631
632 cons = NULL;
633
634 /* default values */
635 initial = readerdata->initialconss;
636 separate = TRUE;
637 propagate = TRUE;
638 enforce = TRUE;
639 check = TRUE;
640 local = FALSE;
641 modifiable = FALSE;
642
643 usercut = (flags & LP_FLAG_CON_SEPAR) != 0;
644 lazycut = (flags & LP_FLAG_CON_CHECK) != 0;
645
646 /* evaluate constraint flags */
647 if( usercut && lazycut )
648 {
649 initial = FALSE;
650 separate = TRUE;
651 check = TRUE;
652 }
653 else if( usercut )
654 {
655 initial = FALSE;
656 separate = TRUE;
657 check = FALSE;
658 }
659 else if( lazycut )
660 {
661 initial = FALSE;
662 separate = FALSE;
663 check = TRUE;
664 }
665
666 if( term_is_linear(term) )
667 {
668 /* if the constraint gives an indicator constraint */
669 if ( flags & LP_FLAG_CON_INDIC )
670 {
671 bool lhsIndCons = FALSE; /* generate lhs form for indicator constraints */
672 bool rhsIndCons = FALSE; /* generate rhs form for indicator constraints */
673
674 SCIP_CALL( abortReadIfExact(scip, created,
675 "xpl_addcon_term: exact version for indicator constraints not supported\n") );
676
677 /* currently indicator constraints can only handle "<=" constraints */
678 switch( type )
679 {
680 case CON_LHS:
681 lhsIndCons = TRUE;
682 break;
683 case CON_RHS:
684 rhsIndCons = TRUE;
685 break;
686 case CON_RANGE:
687 case CON_EQUAL:
688 lhsIndCons = TRUE;
689 rhsIndCons = TRUE;
690 break;
691 case CON_FREE:
692 /*lint -fallthrough*/
693 default:
694 SCIPerrorMessage("invalid constraint type <%d> in ZIMPL callback xlp_addcon()\n", type);
695 readerdata->readerror = TRUE;
696 break;
697 }
698
699 /* insert lhs form of indicator */
700 if ( lhsIndCons )
701 {
702 SCIP_CALL( SCIPcreateConsIndicator(scip, &cons, name, NULL, 0, NULL, NULL, -sciplhs,
703 initial, separate, enforce, check, propagate, local, readerdata->dynamicconss, readerdata->dynamicrows, FALSE) );
704 SCIP_CALL( SCIPaddCons(scip, cons) );
705
706 for( i = 0; i < term_get_elements(term); i++ )
707 {
708 SCIP_VAR* scipvar;
709 SCIP_Real scipval;
710 const Mono* mono = term_get_element(term, i);
711 MFun mfun;
712
713 scipvar = (SCIP_VAR*)mono_get_var(mono, 0);
714
715 /* check whether variable is the binary variable */
716 mfun = mono_get_function(mono);
717 if (mfun == MFUN_TRUE || mfun == MFUN_FALSE)
718 {
719 SCIP_CALL( SCIPsetBinaryVarIndicator(scip, cons, scipvar) );
720 }
721 else
722 {
723 assert(!numb_equal(mono_get_coeff(mono), numb_zero()));
724 assert(mono_is_linear(mono));
725
726 scipval = -numb_todbl(mono_get_coeff(mono));
727 SCIP_CALL( SCIPaddVarIndicator(scip, cons, scipvar, scipval) );
728 }
729 }
730
731 (*created) = TRUE;
732 }
733
734 /* insert rhs form of indicator */
735 if ( rhsIndCons )
736 {
737 SCIP_CALL( SCIPcreateConsIndicator(scip, &cons, name, NULL, 0, NULL, NULL, sciprhs,
738 initial, separate, enforce, check, propagate, local, readerdata->dynamicconss, readerdata->dynamicrows, FALSE) );
739 SCIP_CALL( SCIPaddCons(scip, cons) );
740
741 for( i = 0; i < term_get_elements(term); i++ )
742 {
743 SCIP_VAR* scipvar;
744 SCIP_Real scipval;
745 const Mono* mono = term_get_element(term, i);
746 MFun mfun;
747
748 scipvar = (SCIP_VAR*)mono_get_var(mono, 0);
749
750 /* check whether variable is the binary variable */
751 mfun = mono_get_function(mono);
752 if (mfun == MFUN_TRUE || mfun == MFUN_FALSE)
753 {
754 SCIP_CALL( SCIPsetBinaryVarIndicator(scip, cons, scipvar) );
755 }
756 else
757 {
758 assert(!numb_equal(mono_get_coeff(mono), numb_zero()));
759 assert(mono_is_linear(mono));
760
761 scipval = numb_todbl(mono_get_coeff(mono));
762 SCIP_CALL( SCIPaddVarIndicator(scip, cons, scipvar, scipval) );
763 }
764 }
765
766 (*created) = TRUE;
767 }
768 }
769 else
770 {
771 if( SCIPisExact(scip) )
772 {
773 SCIP_VAR* scipvar;
774 SCIP_RATIONAL* scipvalrat;
775
776 /* due to technical reasons, we do not add singleton constraints but immediately transform them to variable bounds */
777 /** @todo rework this into presolving of cons_exactlinear */
778 if( term_get_elements(term) == 1 )
779 {
780 SCIP_RATIONAL* quotient;
781 SCIP_Bool isupper;
782 SCIP_Bool consneeded;
783
784 consneeded = FALSE;
785
786 assert(!numb_equal(mono_get_coeff(term_get_element(term, 0)), numb_zero()));
787 assert(mono_is_linear(term_get_element(term, 0)));
788
789 scipvar = (SCIP_VAR*)mono_get_var(term_get_element(term, 0), 0);
790 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &scipvalrat, mono_get_coeff(term_get_element(term, 0))) );
792
793 if( !SCIPrationalIsInfinity(ratrhs) )
794 {
795 isupper = SCIPrationalIsPositive(scipvalrat);
796 SCIPrationalDiv(quotient, ratrhs, scipvalrat);
797
798 if( isupper && SCIPrationalIsLT(quotient, SCIPvarGetUbGlobalExact(scipvar)) )
799 {
800 if( SCIPrationalIsGE(quotient, SCIPvarGetLbGlobalExact(scipvar)) )
801 {
802 SCIP_CALL( SCIPchgVarUbGlobalExact(scip, scipvar, quotient) );
803 }
804 else
805 consneeded = TRUE;
806 }
807 else if( !isupper && SCIPrationalIsGT(quotient, SCIPvarGetLbGlobalExact(scipvar)) )
808 {
809 if( SCIPrationalIsLE(quotient, SCIPvarGetUbGlobalExact(scipvar)) )
810 {
811 SCIP_CALL( SCIPchgVarLbGlobalExact(scip, scipvar, quotient) );
812 }
813 else
814 consneeded = TRUE;
815 }
816 }
817 if( !SCIPrationalIsNegInfinity(ratlhs) )
818 {
819 isupper = !SCIPrationalIsPositive(scipvalrat);
820 SCIPrationalDiv(quotient, ratlhs, scipvalrat);
821
822 if( isupper && SCIPrationalIsLT(quotient, SCIPvarGetUbGlobalExact(scipvar)) )
823 {
824 if( SCIPrationalIsGE(quotient, SCIPvarGetLbGlobalExact(scipvar)) )
825 {
826 SCIP_CALL( SCIPchgVarUbGlobalExact(scip, scipvar, quotient) );
827 }
828 else
829 consneeded = TRUE;
830 }
831 else if( !isupper && SCIPrationalIsGT(quotient, SCIPvarGetLbGlobalExact(scipvar)) )
832 {
833 if( SCIPrationalIsLE(quotient, SCIPvarGetUbGlobalExact(scipvar)) )
834 {
835 SCIP_CALL( SCIPchgVarLbGlobalExact(scip, scipvar, quotient) );
836 }
837 else
838 consneeded = TRUE;
839 }
840 }
841
842 if( consneeded )
843 {
844 SCIP_CALL( SCIPcreateConsExactLinear(scip, &cons, name, 0, NULL, NULL, ratlhs, ratrhs,
845 initial, separate, enforce, check, propagate, local, modifiable, readerdata->dynamicconss, readerdata->dynamicrows, FALSE) );
846 SCIP_CALL( SCIPaddCons(scip, cons) );
847 SCIP_CALL( SCIPaddCoefExactLinear(scip, cons, scipvar, scipvalrat) );
848 }
849
852 }
853 else
854 {
855 SCIP_CALL( SCIPcreateConsExactLinear(scip, &cons, name, 0, NULL, NULL, ratlhs, ratrhs,
856 initial, separate, enforce, check, propagate, local, modifiable, readerdata->dynamicconss, readerdata->dynamicrows, FALSE) );
857 SCIP_CALL( SCIPaddCons(scip, cons) );
858
859 for( i = 0; i < term_get_elements(term); i++ )
860 {
861 assert(!numb_equal(mono_get_coeff(term_get_element(term, i)), numb_zero()));
862 assert(mono_is_linear(term_get_element(term, i)));
863
864 scipvar = (SCIP_VAR*)mono_get_var(term_get_element(term, i), 0);
865 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &scipvalrat, mono_get_coeff(term_get_element(term, i))) );
866
867 SCIP_CALL( SCIPaddCoefExactLinear(scip, cons, scipvar, scipvalrat) );
869 }
870 }
871 }
872 else
873 {
874 SCIP_CALL( SCIPcreateConsLinear(scip, &cons, name, 0, NULL, NULL, sciplhs, sciprhs,
875 initial, separate, enforce, check, propagate, local, modifiable, readerdata->dynamicconss, readerdata->dynamicrows, FALSE) );
876 SCIP_CALL( SCIPaddCons(scip, cons) );
877
878 for( i = 0; i < term_get_elements(term); i++ )
879 {
880 SCIP_VAR* scipvar;
881 SCIP_Real scipval;
882
883 assert(!numb_equal(mono_get_coeff(term_get_element(term, i)), numb_zero()));
884 assert(mono_is_linear(term_get_element(term, i)));
885
886 scipvar = (SCIP_VAR*)mono_get_var(term_get_element(term, i), 0);
887 scipval = numb_todbl(mono_get_coeff(term_get_element(term, i)));
888
889 SCIP_CALL( SCIPaddCoefLinear(scip, cons, scipvar, scipval) );
890 }
891 }
892 (*created) = TRUE;
893 }
894 }
895 else
896 {
897 SCIP_EXPR* expr;
898
899 SCIP_CALL( abortReadIfExact(scip, created,
900 "xpl_addcon_term: exact version for degree == 2 not supported\n") );
901
902 /* convert term into expression */
903 SCIP_CALL( createExpr(scip, readerdata, &expr, term) );
904
905 if( expr == NULL )
906 {
907 /* ZIMPL term could not be represented as SCIP expression */
908 (*created) = FALSE;
909 }
910 else
911 {
912 /* create constraint with expression */
913 SCIP_CALL( SCIPcreateConsNonlinear(scip, &cons, name, expr, sciplhs, sciprhs,
914 initial, separate, enforce, check, propagate, local, modifiable, readerdata->dynamicconss, readerdata->dynamicrows) );
915 SCIP_CALL( SCIPaddCons(scip, cons) );
916
917 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
918
919 (*created) = TRUE;
920 }
921 }
922
923 if( cons != NULL )
924 {
925 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
926 }
927
928 if( SCIPisExact(scip) )
929 {
932 }
933
934 return SCIP_OKAY;
935}
936
937/** method adds objective term and is called directly from ZIMPL
938 *
939 * @note this method is used by ZIMPL beginning from version 3.4.1
940 */
941static
942SCIP_RETCODE addObjTerm(
943 SCIP* scip, /**< SCIP data structure */
944 SCIP_READERDATA* readerdata, /**< reader data */
945 const Term* term /**< term to use */
946 )
947{
948 if( term_is_linear(term) )
949 {
950 int i;
951 for( i = 0; i < term_get_elements(term); i++ )
952 {
953 SCIP_VAR* scipvar;
954 SCIP_Real scipval;
955
956 assert(!numb_equal(mono_get_coeff(term_get_element(term, i)), numb_zero()));
957 assert(mono_is_linear(term_get_element(term, i)));
958
959 scipvar = (SCIP_VAR*)mono_get_var(term_get_element(term, i), 0);
960 if( SCIPisExact(scip) )
961 {
962 SCIP_RATIONAL* scipvalrat;
963 char str[SCIP_MAXSTRLEN];
964
965 RcreateNumb(SCIPblkmem(scip), &scipvalrat, mono_get_coeff(term_get_element(term, i)));
966 SCIPrationalAdd(scipvalrat, scipvalrat, SCIPvarGetObjExact(scipvar));
967
968 SCIPdebugMessage("zimpl reader: change obj<%g> of var: add<%g> as approx", SCIPvarGetObj(scipvar),
969 SCIPrationalGetReal(scipvalrat) );
970 SCIPdebug(SCIPrationalToString(scipvalrat, str));
971 SCIPdebugMessage(" (<%s> as exact) \n", str);
972
973 readerdata->retcode = SCIPchgVarObjExact(scip, scipvar, scipvalrat);
974 SCIPchgVarObj(scip, scipvar, SCIPrationalGetReal(scipvalrat));
975
977 }
978 else
979 {
980 SCIP_CALL( abortReadIfExact(scip, &(readerdata->readerror),
981 "xlp_addobj_termr: exact version not supported.\n") );
982
983 scipval = numb_todbl(mono_get_coeff(term_get_element(term, i)));
984
985 SCIP_CALL( SCIPaddVarObj(scip, scipvar, scipval) );
986 }
987 }
988 }
989 else
990 {
991 /* create variable objvar, add 1*objvar to objective, and add constraint term - objvar = 0 */
992 SCIP_EXPR* expr;
993 SCIP_CONS* cons;
994 SCIP_VAR* objvar;
995
996 SCIP_CALL( createExpr(scip, readerdata, &expr, term) );
997
998 if( expr == NULL )
999 {
1000 SCIPerrorMessage("Could not convert ZIMPL objective term into SCIP expression due to unsupported ZIMPL function.\n");
1001 return SCIP_READERROR;
1002 }
1003
1004 SCIP_CALL( SCIPcreateConsNonlinear(scip, &cons, "obj", expr,
1007 readerdata->initialconss, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, readerdata->dynamicconss, FALSE) );
1008
1010 SCIP_CALL( SCIPaddLinearVarNonlinear(scip, cons, objvar, -1.0) );
1011
1012 SCIP_CALL( SCIPaddVar(scip, objvar) );
1013 SCIP_CALL( SCIPaddCons(scip, cons) );
1014
1015 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
1016 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1017 SCIP_CALL( SCIPreleaseVar(scip, &objvar) );
1018 }
1019
1020 if( SCIPisExact(scip) )
1021 {
1022 SCIP_RATIONAL* scipvalrat;
1023
1024 RcreateNumb(SCIPblkmem(scip), &scipvalrat, term_get_constant(term));
1026 SCIPrationalFreeBlock(SCIPblkmem(scip), &scipvalrat);
1027 }
1028 else
1029 {
1030 SCIP_CALL( SCIPaddOrigObjoffset(scip, (SCIP_Real)numb_todbl(term_get_constant(term))) );
1031 }
1032
1033 return SCIP_OKAY;
1034}
1035
1036/** method creates a constraint and is called directly from ZIMPL
1037 *
1038 * @note this method is used by ZIMPL beginning from version 3.00
1039 */
1040bool xlp_addcon_term(
1041 Lps* lp, /**< pointer to reader data */
1042 const char* name, /**< constraint name */
1043 ConType type, /**< constraint type (LHS, RHS, EQUAL, RANGE, etc) */
1044 const Numb* lhs, /**< left hand side */
1045 const Numb* rhs, /**< right hand side */
1046 unsigned int flags, /**< special constraint flags, see ratlptypes.h */
1047 const Term* term /**< term to use */
1048 )
1049{
1050 SCIP* scip;
1051 SCIP_READERDATA* readerdata;
1052 SCIP_Bool created = FALSE;
1053
1054 readerdata = (SCIP_READERDATA*)lp;
1055 assert(readerdata != NULL);
1056
1057 scip = readerdata->scip;
1058 assert(scip != NULL);
1059
1060 if( readerdata->retcode != SCIP_OKAY || readerdata->readerror )
1061 return TRUE;
1062
1063 readerdata->retcode = addConsTerm(scip, readerdata, name, type, lhs, rhs, flags, term, &created);
1064
1065 return !created;
1066}
1067
1068/** adde variable */
1069static
1070SCIP_RETCODE addVar(
1071 SCIP* scip, /**< SCIP data structure */
1072 SCIP_READERDATA* readerdata, /**< reader data */
1073 const char* name, /**< variable name */
1074 VarClass usevarclass, /**< variable type */
1075 const Bound* lower, /**< lower bound */
1076 const Bound* upper, /**< upper bound */
1077 const Numb* priority, /**< branching priority */
1078 const Numb* startval, /**< start value for the variable within in the start solution */
1079 Var** zplvar /**< pointer to store the created variable */
1080 )
1081{
1082 SCIP_VAR* var;
1083 SCIP_Real lb;
1084 SCIP_Real ub;
1085 SCIP_RATIONAL* lbrat = NULL;
1086 SCIP_RATIONAL* ubrat = NULL;
1087 SCIP_VARTYPE vartype;
1088 SCIP_IMPLINTTYPE varimpltype;
1089 SCIP_Bool initial;
1090 SCIP_Bool removable;
1091 int branchpriority;
1092
1093 if( SCIPisExact(scip) )
1094 {
1095 /* get exact lower bounds for exactlinear constraint handler and safe FP-values for FP-problem */
1096 switch( bound_get_type(lower) )
1097 {
1098 case BOUND_VALUE:
1099 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &lbrat, bound_get_value(lower)) );
1101 break;
1102 case BOUND_INFTY:
1104 lb = SCIPinfinity(scip);
1105 break;
1106 case BOUND_MINUS_INFTY:
1108 lb = -SCIPinfinity(scip);
1109 break;
1110 case BOUND_ERROR:
1111 default:
1112 SCIPerrorMessage("invalid lower bound type <%d> in ZIMPL reader\n", bound_get_type(lower));
1114 lb = 0.0;
1115 break;
1116 }
1117
1118 /* get exact upper bounds for exactlinear constraint handler and safe FP-values for FP-problem */
1119 switch( bound_get_type(upper) )
1120 {
1121 case BOUND_VALUE:
1122 SCIP_CALL( RcreateNumb(SCIPblkmem(scip), &ubrat, bound_get_value(upper)) );
1124 break;
1125 case BOUND_INFTY:
1127 ub = SCIPinfinity(scip);
1128 break;
1129 case BOUND_MINUS_INFTY:
1131 ub = -SCIPinfinity(scip);
1132 break;
1133 case BOUND_ERROR:
1134 default:
1135 SCIPerrorMessage("invalid upper bound type <%d> in ZIMPL reader\n", bound_get_type(upper));
1137 ub = 0.0;
1138 break;
1139 }
1140 }
1141 else
1142 {
1143 switch( bound_get_type(lower) )
1144 {
1145 case BOUND_VALUE:
1146 lb = (SCIP_Real)numb_todbl(bound_get_value(lower));
1147 break;
1148 case BOUND_INFTY:
1149 lb = SCIPinfinity(scip);
1150 break;
1151 case BOUND_MINUS_INFTY:
1152 lb = -SCIPinfinity(scip);
1153 break;
1154 case BOUND_ERROR:
1155 default:
1156 SCIPerrorMessage("invalid lower bound type <%d> in ZIMPL reader\n", bound_get_type(lower));
1157 lb = 0.0;
1158 break;
1159 }
1160
1161 switch( bound_get_type(upper) )
1162 {
1163 case BOUND_VALUE:
1164 ub = (SCIP_Real)numb_todbl(bound_get_value(upper));
1165 break;
1166 case BOUND_INFTY:
1167 ub = SCIPinfinity(scip);
1168 break;
1169 case BOUND_MINUS_INFTY:
1170 ub = -SCIPinfinity(scip);
1171 break;
1172 case BOUND_ERROR:
1173 default:
1174 SCIPerrorMessage("invalid upper bound type <%d> in ZIMPL reader\n", bound_get_type(upper));
1175 ub = 0.0;
1176 break;
1177 }
1178 }
1179
1180 switch( usevarclass )
1181 {
1182 case VAR_INT:
1183 vartype = SCIP_VARTYPE_INTEGER;
1184 varimpltype = SCIP_IMPLINTTYPE_NONE;
1185 break;
1186 case VAR_IMP:
1187 vartype = SCIP_VARTYPE_CONTINUOUS;
1188 varimpltype = SCIP_IMPLINTTYPE_WEAK;
1189 break;
1190 case VAR_CON:
1191 vartype = SCIP_VARTYPE_CONTINUOUS;
1192 varimpltype = SCIP_IMPLINTTYPE_NONE;
1193 break;
1194 default:
1195 SCIPwarningMessage(scip, "invalid variable class <%d> in ZIMPL callback xlp_addvar()\n", usevarclass);
1196 vartype = SCIP_VARTYPE_CONTINUOUS;
1197 readerdata->readerror = TRUE;
1198 break;
1199 }
1200 initial = !(readerdata->dynamiccols);
1201 removable = readerdata->dynamiccols;
1202
1203 /* create variable */
1204 SCIPdebugMessage("zimpl reader: added new variable");
1205 SCIP_CALL( SCIPcreateVarImpl(scip, &var, name, lb, ub, 0.0, vartype, varimpltype, initial, removable,
1206 NULL, NULL, NULL, NULL, NULL) );
1207
1208 if( SCIPisExact(scip) )
1209 {
1210 SCIP_CALL( SCIPaddVarExactData(scip, var, lbrat, ubrat, NULL) );
1211#ifdef SCIP_MORE_DEBUG
1213 SCIPrationalToString(lbrat, strlb);
1214 SCIPrationalToString(ubrat, strub);
1215 SCIPdebugMessage("exact bounds are [%s,%s]\n", strlb, strub);
1216#endif
1219 }
1220
1221 /* add variable to the problem; we are releasing the variable later */
1223
1224 if( !numb_equal(priority, numb_unknown()) )
1225 {
1226 if( numb_is_int(priority) )
1227 branchpriority = numb_toint(priority);
1228 else
1229 {
1230 if( !readerdata->branchpriowarning )
1231 {
1233 "ZIMPL reader: fractional branching priorities in input - rounding down to integer values\n");
1234 readerdata->branchpriowarning = TRUE;
1235 }
1236 branchpriority = (int)numb_todbl(priority);
1237 }
1238
1239 /* change the branching priority of the variable */
1240 SCIP_CALL( SCIPchgVarBranchPriority(scip, var, branchpriority) );
1241 }
1242
1243 /* check if we are willing to except a primal solution candidate */
1244 if( readerdata->valid )
1245 {
1246 /* if the number is unknown we have no valid primal solution candidate */
1247 if( numb_equal(startval, numb_unknown()) )
1248 {
1249 SCIPdebugMsg(scip, "primal solution candidate contains an unknown value for variable <%s>(%g)\n",
1250 SCIPvarGetName(var), (SCIP_Real)numb_todbl(startval));
1251 readerdata->valid = FALSE;
1252 }
1253 else
1254 {
1255 assert(readerdata->sol != NULL);
1256 SCIPdebugMsg(scip, "change solution solution <%p>: <%s> = <%g>\n",
1257 (void*)readerdata->sol, SCIPvarGetName(var), (SCIP_Real)numb_todbl(startval));
1258
1259 /* set value within the primal solution candidate */
1260 if( SCIPsolIsExact(readerdata->sol) )
1261 {
1262 SCIP_RATIONAL* solrat;
1263
1264 RcreateNumb(SCIPblkmem(scip), &solrat, startval);
1265 SCIP_CALL( SCIPsetSolValExact(scip, readerdata->sol, var, solrat) );
1267 }
1268 else
1269 {
1270 SCIP_CALL( SCIPsetSolVal(scip, readerdata->sol, var, (SCIP_Real)numb_todbl(startval)) );
1271 }
1272 }
1273 }
1274
1275 /* copy the variable pointer before we release the variable */
1276 (*zplvar) = (Var*)var;
1277
1278 /* release variable */
1280
1281 return SCIP_OKAY;
1282}
1283
1284/** method adds a variable; is called directly by ZIMPL */
1285Var* xlp_addvar(
1286 Lps* lp, /**< pointer to reader data */
1287 const char* name, /**< variable name */
1288 VarClass usevarclass, /**< variable type */
1289 const Bound* lower, /**< lower bound */
1290 const Bound* upper, /**< upper bound */
1291 const Numb* priority, /**< branching priority */
1292 const Numb* startval /**< start value for the variable within in the start solution */
1293 )
1294{ /*lint --e{715}*/
1295 SCIP* scip;
1296 SCIP_READERDATA* readerdata;
1297 Var* zplvar;
1298
1299 readerdata = (SCIP_READERDATA*)lp;
1300 assert(readerdata != NULL);
1301
1302 scip = readerdata->scip;
1303 assert(scip != NULL);
1304
1305 zplvar = NULL;
1306
1307 if( readerdata->retcode != SCIP_OKAY || readerdata->readerror )
1308 return NULL;
1309
1310 readerdata->retcode = addVar(scip, readerdata, name, usevarclass, lower, upper, priority, startval, &zplvar);
1311
1312 return zplvar;
1313}
1314
1315/** add a SOS constraint. Add a given a Zimpl term as an SOS constraint to the mathematical program */
1316static
1317SCIP_RETCODE addSOS(
1318 SCIP* scip, /**< SCIP data structure */
1319 SCIP_READERDATA* readerdata, /**< reader data */
1320 const char* name, /**< constraint name */
1321 SosType type, /**< SOS type */
1322 const Term* term /**< terms indicating sos */
1323 )
1324{
1325 SCIP_CONS* cons;
1327 SCIP_Bool enforce;
1328 SCIP_Bool check;
1330 SCIP_Bool local;
1331 int i;
1332
1333 SCIP_CALL( abortReadIfExact(scip, &(readerdata->readerror),
1334 "xlp_addsos_termr: exact version not supported.\n") );
1335
1336 switch( type )
1337 {
1338 case SOS_TYPE1:
1339 separate = TRUE;
1340 enforce = TRUE;
1341 check = enforce;
1342 propagate = TRUE;
1343 local = FALSE;
1344
1345 SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL,
1346 readerdata->initialconss, separate, enforce, check, propagate, local, readerdata->dynamicconss, readerdata->dynamicrows, FALSE) );
1347 SCIP_CALL( SCIPaddCons(scip, cons) );
1348
1349 for( i = 0; i < term_get_elements(term); i++ )
1350 {
1351 SCIP_VAR* var;
1352 SCIP_Real weight;
1353
1354 assert( mono_is_linear(term_get_element(term, i)) );
1355
1356 var = (SCIP_VAR*) mono_get_var(term_get_element(term, i), 0);
1357 weight = numb_todbl(mono_get_coeff(term_get_element(term, i)));
1358
1359 SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, weight) );
1360 }
1361 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1362 break;
1363 case SOS_TYPE2:
1364 separate = TRUE;
1365 enforce = TRUE;
1366 check = enforce;
1367 propagate = TRUE;
1368 local = FALSE;
1369
1370 SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL,
1371 readerdata->initialconss, separate, enforce, check, propagate, local, readerdata->dynamicconss, readerdata->dynamicrows, FALSE) );
1372 SCIP_CALL( SCIPaddCons(scip, cons) );
1373 for( i = 0; i < term_get_elements(term); i++ )
1374 {
1375 SCIP_VAR* var;
1376 SCIP_Real weight;
1377
1378 assert( mono_is_linear(term_get_element(term, i)) );
1379
1380 var = (SCIP_VAR*) mono_get_var(term_get_element(term, i), 0);
1381 weight = numb_todbl(mono_get_coeff(term_get_element(term, i)));
1382
1383 SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, weight) );
1384 }
1385 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1386 break;
1387 case SOS_ERR:
1388 /*lint -fallthrough*/
1389 default:
1390 SCIPerrorMessage("invalid SOS type <%d> in ZIMPL callback xlp_addsos_term()\n", type);
1391 readerdata->readerror = TRUE;
1392 break;
1393 }
1394
1395 return SCIP_OKAY;
1396}
1397
1398/** add a SOS constraint. Add a given a Zimpl term as an SOS constraint to the mathematical program */
1399int xlp_addsos_term(
1400 Lps* lp, /**< pointer to reader data */
1401 const char* name, /**< constraint name */
1402 SosType type, /**< SOS type */
1403 const Numb* priority, /**< priority */
1404 const Term* term /**< terms indicating sos */
1405 )
1406{
1407 /*lint --e{715}*/
1408 SCIP* scip;
1409 SCIP_READERDATA* readerdata;
1410
1411 readerdata = (SCIP_READERDATA*)lp;
1412 assert(readerdata != NULL);
1413
1414 scip = readerdata->scip;
1415 assert(scip != NULL);
1416
1417 if( readerdata->retcode != SCIP_OKAY || readerdata->readerror )
1418 return TRUE;
1419
1420 readerdata->retcode = addSOS(scip, readerdata, name, type, term);
1421
1422 return 0;
1423}
1424
1425/** returns the variable name */
1426const char* xlp_getvarname(
1427 const Lps* lp, /**< pointer to reader data */
1428 const Var* var /**< variable */
1429 )
1430{
1431#ifndef NDEBUG
1432 SCIP* scip;
1433 SCIP_READERDATA* readerdata;
1434
1435 readerdata = (SCIP_READERDATA*)lp;
1436 assert(readerdata != NULL);
1437
1438 scip = readerdata->scip;
1439 assert(scip != NULL);
1440#endif
1441
1442 return SCIPvarGetName((SCIP_VAR*)var);
1443}
1444
1445/** return variable type */
1446VarClass xlp_getclass(
1447 const Lps* lp, /**< pointer to reader data */
1448 const Var* var /**< variable */
1449 )
1450{
1451 SCIP_READERDATA* readerdata = (SCIP_READERDATA*)lp;
1452 SCIP_VAR* scipvar = (SCIP_VAR*)var;
1453 int implintlevel;
1454
1455 /* adjust border between int and imp based on the implied integral level */
1456 assert(readerdata != NULL);
1457 SCIPgetIntParam(readerdata->scip, "write/implintlevel", &implintlevel);
1458 assert(implintlevel >= -2);
1459 assert(implintlevel <= 2);
1460
1461 switch( SCIPvarGetType(scipvar) )
1462 {
1465 return (int)SCIPvarGetImplType(scipvar) <= 2 + implintlevel ? VAR_INT : VAR_IMP;
1467 if( SCIPvarIsImpliedIntegral(scipvar) )
1468 return (int)SCIPvarGetImplType(scipvar) > 2 - implintlevel ? VAR_INT : VAR_IMP;
1469 break;
1470 default:
1471 SCIPerrorMessage("invalid SCIP variable type <%d> in ZIMPL callback xlp_getclass()\n", SCIPvarGetType(scipvar));
1472 readerdata->readerror = TRUE;
1473 break;
1474 }
1475
1476 return VAR_CON;
1477}
1478
1479/** returns lower bound */
1480Bound* xlp_getlower(
1481 const Lps* lp, /**< pointer to reader data */
1482 const Var* var /**< variable */
1483 )
1484{
1485 SCIP* scip;
1486 SCIP_READERDATA* readerdata;
1487 SCIP_VAR* scipvar;
1488 SCIP_Real lb;
1489 char s[SCIP_MAXSTRLEN];
1490 BoundType boundtype;
1491 Numb* numb;
1492 Bound* bound;
1493
1494 readerdata = (SCIP_READERDATA*)lp;
1495 assert(readerdata != NULL);
1496
1497 scip = readerdata->scip;
1498 assert(scip != NULL);
1499
1500 if( SCIP_ERROR == abortReadIfExact(scip, NULL, "xlp_getlower: exact version not supported.\n") )
1501 {
1502 readerdata->readerror = TRUE;
1503 return NULL;
1504 }
1505
1506 scipvar = (SCIP_VAR*)var;
1507 assert(scipvar != NULL);
1508
1509 /* collect lower bound */
1510 lb = SCIPvarGetLbGlobal(scipvar);
1511 numb = NULL;
1512
1513 /* check if lower bound is infinity */
1514 if( SCIPisInfinity(scip, -lb) )
1515 boundtype = BOUND_MINUS_INFTY;
1516 else if( SCIPisInfinity(scip, lb) )
1517 boundtype = BOUND_INFTY;
1518 else
1519 {
1520 boundtype = BOUND_VALUE;
1521
1522 /* create double form string */
1523 (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "%.20f", lb);
1524 numb = numb_new_ascii(s);
1525 }
1526
1527 /* create bound */
1528 bound = bound_new(boundtype, numb);
1529
1530 if( numb != NULL )
1531 numb_free(numb);
1532
1533 return bound;
1534}
1535
1536/** returns upper bound */
1537Bound* xlp_getupper(
1538 const Lps* lp, /**< pointer to reader data */
1539 const Var* var /**< variable */
1540 )
1541{
1542 SCIP* scip;
1543 SCIP_READERDATA* readerdata;
1544 SCIP_VAR* scipvar;
1545 SCIP_Real ub;
1546 char s[SCIP_MAXSTRLEN];
1547 BoundType boundtype;
1548 Numb* numb;
1549 Bound* bound;
1550
1551 readerdata = (SCIP_READERDATA*)lp;
1552 assert(readerdata != NULL);
1553
1554 scip = readerdata->scip;
1555 assert(scip != NULL);
1556
1557 if( SCIP_ERROR == abortReadIfExact(scip, NULL, "xlp_getupper: exact version not supported.\n") )
1558 {
1559 readerdata->readerror = TRUE;
1560 return NULL;
1561 }
1562
1563 scipvar = (SCIP_VAR*)var;
1564 assert(scipvar != NULL);
1565
1566 /* collect upper bound */
1567 ub = SCIPvarGetUbGlobal(scipvar);
1568 numb = NULL;
1569
1570 /* check if upper bound is infinity */
1571 if( SCIPisInfinity(scip, -ub) )
1572 boundtype = BOUND_MINUS_INFTY;
1573 else if( SCIPisInfinity(scip, ub) )
1574 boundtype = BOUND_INFTY;
1575 else
1576 {
1577 boundtype = BOUND_VALUE;
1578 (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "%.20f", ub);
1579 numb = numb_new_ascii(s);
1580 }
1581
1582 /* create ZIMPL bound */
1583 bound = bound_new(boundtype, numb);
1584
1585 if (numb != NULL)
1586 numb_free(numb);
1587
1588 return bound;
1589}
1590
1591/** Set the name and direction of the objective function, i.e. minimization or maximization
1592 * Coefficents of the objective function will be set to all zero.
1593 */
1594bool xlp_setobj(
1595 Lps* lp, /**< pointer to reader data */
1596 const char* name, /**< name of the objective function */
1597 bool minimize /**< True if the problem should be minimized, False if it should be maximized */
1598 )
1599{
1600 SCIP* scip;
1601 SCIP_READERDATA* readerdata;
1602 SCIP_OBJSENSE objsense;
1603
1604 readerdata = (SCIP_READERDATA*)lp;
1605 assert(readerdata != NULL);
1606
1607 scip = readerdata->scip;
1608 assert(scip != NULL);
1609
1610 if( readerdata->retcode != SCIP_OKAY || readerdata->readerror )
1611 return FALSE;
1612
1613 objsense = (minimize ? SCIP_OBJSENSE_MINIMIZE : SCIP_OBJSENSE_MAXIMIZE);
1614 readerdata->retcode = SCIPsetObjsense(scip, objsense);
1615
1616 return FALSE;
1617}
1618
1619/** adds objective function */
1620void xlp_addtoobj(
1621 Lps* lp, /**< pointer to reader data */
1622 const Term* term /**< objective term */
1623 )
1624{
1625 SCIP* scip;
1626 SCIP_READERDATA* readerdata;
1627
1628 readerdata = (SCIP_READERDATA*)lp;
1629 assert(readerdata != NULL);
1630
1631 scip = readerdata->scip;
1632 assert(scip != NULL);
1633
1634 if( readerdata->retcode != SCIP_OKAY || readerdata->readerror )
1635 return;
1636
1637 readerdata->retcode = addObjTerm(scip, readerdata, term);
1638}
1639
1640/*
1641 * Callback methods of reader
1642 */
1643
1644/** copy method for reader plugins (called when SCIP copies plugins) */
1645static
1646SCIP_DECL_READERCOPY(readerCopyZpl)
1647{ /*lint --e{715}*/
1648 assert(scip != NULL);
1649 assert(reader != NULL);
1650
1652
1653 /* call inclusion method of reader */
1655
1656 return SCIP_OKAY;
1657}
1658
1659
1660/** problem reading method of reader */
1661static
1662SCIP_DECL_READERREAD(readerReadZpl)
1663{ /*lint --e{715}*/
1664 SCIP_READERDATA* readerdata;
1665 SCIP_RETCODE retcode;
1666 char oldpath[SCIP_MAXSTRLEN];
1667 char buffer[SCIP_MAXSTRLEN];
1668 char compextension[SCIP_MAXSTRLEN];
1669 char namewithoutpath[SCIP_MAXSTRLEN];
1670 char* path;
1671 char* name;
1672 char* extension;
1673 char* compression;
1674 char* paramstr;
1675
1676 SCIP_Bool changedir;
1677 int i;
1678
1679 SCIP_CALL( SCIPgetBoolParam(scip, "reading/zplreader/changedir", &changedir) );
1680
1681 path = NULL;
1682 oldpath[0] = '\0';
1683 if( changedir )
1684 {
1685 /* change to the directory of the ZIMPL file, s.t. paths of data files read by the ZIMPL model are relative to
1686 * the location of the ZIMPL file
1687 */
1688 (void)SCIPstrncpy(buffer, filename, SCIP_MAXSTRLEN);
1689 SCIPsplitFilename(buffer, &path, &name, &extension, &compression);
1690 if( compression != NULL )
1691 (void) SCIPsnprintf(compextension, SCIP_MAXSTRLEN, ".%s", compression);
1692 else
1693 *compextension = '\0';
1694 (void) SCIPsnprintf(namewithoutpath, SCIP_MAXSTRLEN, "%s.%s%s", name, extension, compextension);
1695 if( (char*)getcwd(oldpath, SCIP_MAXSTRLEN) == NULL )
1696 {
1697 SCIPerrorMessage("error getting the current path\n");
1698 return SCIP_READERROR;
1699 }
1700 if( path != NULL )
1701 {
1702 if( chdir(path) != 0 )
1703 {
1704 SCIPerrorMessage("error changing to directory <%s>\n", path);
1705 return SCIP_NOFILE;
1706 }
1707 }
1708 filename = namewithoutpath;
1709 }
1710
1711 /* get current path for output */
1713 {
1714 char currentpath[SCIP_MAXSTRLEN];
1715 if( (char*)getcwd(currentpath, SCIP_MAXSTRLEN) == NULL )
1716 {
1717 SCIPerrorMessage("error getting the current path\n");
1718 return SCIP_READERROR;
1719 }
1720 /* an extra blank line should be printed separately since the buffer message handler only handle up to one line
1721 * correctly */
1723 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "base directory for ZIMPL parsing: <%s>\n", currentpath);
1724 /* an extra blank line should be printed separately since the buffer message handler only handle up to one line
1725 * correctly */
1727 }
1728
1729 /* allocate storage */
1730 SCIP_CALL( SCIPallocBuffer(scip, &readerdata) );
1731
1732 readerdata->scip = scip;
1733 readerdata->sol = NULL;
1734 readerdata->valid = FALSE;
1735 readerdata->branchpriowarning = FALSE;
1736 readerdata->readerror = FALSE;
1737 readerdata->retcode = SCIP_OKAY;
1738 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &(readerdata->initialconss)) );
1739 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &(readerdata->dynamicconss)) );
1740 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &(readerdata->dynamiccols)) );
1741 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &(readerdata->dynamicrows)) );
1742
1743 /* get the parameter string */
1744 SCIP_CALL( SCIPgetStringParam(scip, "reading/zplreader/parameters", &paramstr) );
1745 if( strcmp(paramstr, "-") == 0 )
1746 {
1747 /* call ZIMPL parser without arguments */
1748 if( !zpl_read(filename, FALSE, (void*)readerdata) )
1749 readerdata->readerror = TRUE;
1750 else
1751 {
1752 /* evaluate retcode */
1753 if ( readerdata->retcode != SCIP_OKAY )
1754 {
1755 SCIPfreeBuffer(scip, &readerdata);
1756 return readerdata->retcode;
1757 }
1758 }
1759 }
1760 else
1761 {
1762 char dummy[2] = "x";
1763 char** argv;
1764 int argc;
1765 int p;
1766 int len;
1767
1768 len = (int) strlen(paramstr);
1769 SCIP_CALL( SCIPallocBufferArray(scip, &argv, len+1) );
1770 argv[0] = dummy; /* argument 0 is irrelevant */
1771 argc = 1;
1772 p = 0;
1773 while( p < len )
1774 {
1775 int arglen;
1776
1777 /* process next argument */
1778 SCIP_CALL( SCIPallocBufferArray(scip, &argv[argc], len+1) ); /*lint !e866*/
1779 arglen = 0;
1780
1781 /* skip spaces */
1782 while( p < len && paramstr[p] == ' ' )
1783 p++;
1784
1785 /* process characters */
1786 while( p < len && paramstr[p] != ' ' )
1787 {
1788 switch( paramstr[p] )
1789 {
1790 case '"':
1791 p++;
1792 /* read characters as they are until the next " */
1793 while( p < len && paramstr[p] != '"' )
1794 {
1795 argv[argc][arglen] = paramstr[p];
1796 arglen++;
1797 p++;
1798 }
1799 p++; /* skip final " */
1800 break;
1801 case '\\':
1802 /* read next character as it is */
1803 p++;
1804 argv[argc][arglen] = paramstr[p];
1805 arglen++;
1806 p++;
1807 break;
1808 default:
1809 argv[argc][arglen] = paramstr[p];
1810 arglen++;
1811 p++;
1812 break;
1813 }
1814 }
1815 argv[argc][arglen] = '\0';
1816
1817 /* check for empty argument */
1818 if( arglen == 0 )
1819 {
1820 SCIPfreeBufferArray(scip, &argv[argc]);
1821 }
1822 else
1823 argc++;
1824 }
1825
1826 /* append file name as last argument */
1827 SCIP_CALL( SCIPduplicateBufferArray(scip, &argv[argc], filename, (int) strlen(filename)+1) ); /*lint !e866*/
1828 argc++;
1829
1830 /* display parsed arguments */
1832 {
1833 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "ZIMPL arguments:\n");
1834 for( i = 1; i < argc; ++i )
1835 {
1836 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "%d: <%s>\n", i, argv[i]);
1837 }
1838 }
1839
1840 /* call ZIMPL parser with arguments */
1841 if( !zpl_read_with_args(argv, argc, FALSE, (void*)readerdata) )
1842 readerdata->readerror = TRUE;
1843
1844 /* free argument memory */
1845 for( i = argc - 1; i >= 1; --i )
1846 {
1847 SCIPfreeBufferArray(scip, &argv[i]);
1848 }
1849 SCIPfreeBufferArray(scip, &argv);
1850
1851 if ( readerdata->retcode != SCIP_OKAY )
1852 {
1853 SCIPfreeBuffer(scip, &readerdata);
1854 return readerdata->retcode;
1855 }
1856 }
1857
1858 if( changedir )
1859 {
1860 /* change directory back to old path */
1861 if( path != NULL )
1862 {
1863 if( chdir(oldpath) != 0 )
1864 {
1865 SCIPwarningMessage(scip, "error changing back to directory <%s>\n", oldpath);
1866 }
1867 }
1868 }
1869
1870 if( readerdata->valid )
1871 {
1872 SCIP_Bool stored;
1873
1874 assert(readerdata->sol != NULL);
1875
1876 stored = FALSE;
1877
1878 /* add primal solution to solution candidate storage, frees the solution afterwards */
1879 SCIP_CALL( SCIPaddSolFree(scip, &readerdata->sol, &stored) );
1880
1881 if( stored )
1882 {
1883 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "ZIMPL starting solution candidate accepted\n");
1884 }
1885 }
1886
1888
1889 /* evaluate if a reading error occurred */
1890 if( readerdata->readerror )
1891 retcode = SCIP_READERROR;
1892 else
1893 retcode = SCIP_OKAY;
1894
1895 /* free primal solution candidate */
1896 if( readerdata->sol != NULL )
1897 {
1898 SCIP_CALL( SCIPfreeSol(scip, &readerdata->sol) );
1899 }
1900
1901 /* free reader data */
1902 SCIPfreeBuffer(scip, &readerdata);
1903
1904 return retcode;
1905}
1906
1907
1908#endif
1909#endif
1910
1911
1912/*
1913 * reader specific interface methods
1914 */
1915
1916/** includes the zpl file reader in SCIP */ /*lint --e{715}*/
1918 SCIP* scip /**< SCIP data structure */
1919 )
1920{ /*lint --e{715}*/
1921#ifdef SCIP_WITH_ZIMPL
1922#if (ZIMPL_VERSION >= 341)
1923 SCIP_READERDATA* readerdata;
1924 SCIP_READER* reader;
1925 char extcodename[SCIP_MAXSTRLEN];
1926
1927 assert(scip != NULL);
1928
1929 /* create zpl reader data */
1930 readerdata = NULL;
1931 reader = NULL;
1932 /* include zpl reader */
1934 assert(reader != NULL);
1935
1936 /* reader is safe to use in exact solving mode */
1937 SCIPreaderMarkExact(reader);
1938
1939 /* set non fundamental callbacks via setter functions */
1940 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyZpl) );
1941 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadZpl) );
1942
1943 /* add zpl reader parameters */
1945 "reading/zplreader/changedir", "should the current directory be changed to that of the ZIMPL file before parsing?",
1946 NULL, FALSE, TRUE, NULL, NULL) );
1948 "reading/zplreader/usestartsol", "should ZIMPL starting solutions be forwarded to SCIP?",
1949 NULL, FALSE, TRUE, NULL, NULL) );
1951 "reading/zplreader/parameters", "additional parameter string passed to the ZIMPL parser (or - for no additional parameters)",
1952 NULL, FALSE, "-", NULL, NULL) );
1953
1954 (void) SCIPsnprintf(extcodename, SCIP_MAXSTRLEN, "ZIMPL %d.%d.%d", ZIMPL_VERSION/100, (ZIMPL_VERSION%100)/10, ZIMPL_VERSION%10); /*lint !e778*/
1955 SCIP_CALL( SCIPincludeExternalCodeInformation(scip, extcodename, "Zuse Institute Mathematical Programming Language developed by T. Koch (zimpl.zib.de)") );
1956#else
1957 assert(scip != NULL);
1958
1959 SCIPwarningMessage(scip, "SCIP does only support ZIMPL 3.4.1 and higher. Please update your ZIMPL version %d.%d.%d\n",
1960 ZIMPL_VERSION/100, (ZIMPL_VERSION%100)/10, ZIMPL_VERSION%10);
1961#endif
1962#endif
1963
1964 return SCIP_OKAY;
1965}
static long bound
Constraint handler for linear constraints in their most general form, .
constraint handler for indicator constraints
Constraint handler for linear constraints in their most general form, .
constraint handler for nonlinear constraints specified by algebraic expressions
constraint handler for SOS type 1 constraints
constraint handler for SOS type 2 constraints
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_INVALID
Definition def.h:187
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_CALL(x)
Definition def.h:364
absolute expression handler
exponential expression handler
logarithm expression handler
power and signed power expression handlers
product expression handler
sum expression handler
handler for sin expressions
SCIP_RETCODE SCIPaddLinearVarNonlinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real coef)
SCIP_RETCODE SCIPcreateConsExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPaddCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
SCIP_RETCODE SCIPcreateConsNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable)
SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition cons_sos2.c:2597
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPsetBinaryVarIndicator(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *binvar)
SCIP_RETCODE SCIPaddVarIndicator(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition cons_sos2.c:2706
SCIP_RETCODE SCIPcreateExprProduct(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real coefficient, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
SCIP_RETCODE SCIPcreateExprSin(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr_trig.c:1431
SCIP_RETCODE SCIPcreateExprCos(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr_trig.c:1451
SCIP_RETCODE SCIPcreateExprAbs(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr_abs.c:528
SCIP_RETCODE SCIPcreateExprSignpower(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_Real exponent, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr_pow.c:3210
SCIP_RETCODE SCIPcreateExprLog(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr_log.c:630
SCIP_RETCODE SCIPcreateExprExp(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr_exp.c:511
SCIP_RETCODE SCIPcreateExprSum(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefficients, SCIP_Real constant, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr_sum.c:1117
SCIP_RETCODE SCIPcreateExprPow(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_Real exponent, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition expr_pow.c:3186
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition misc.c:11073
SCIP_RETCODE SCIPincludeReaderZpl(SCIP *scip)
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition scip_prob.c:1907
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3274
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition scip_prob.c:1417
SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
Definition scip_prob.c:1486
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition scip_prob.c:1400
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
Definition scip_prob.c:119
SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
Definition scip_prob.c:3525
SCIP_RETCODE SCIPaddOrigObjoffsetExact(SCIP *scip, SCIP_RATIONAL *addval)
Definition scip_prob.c:1465
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3095
SCIP_Real SCIPhashmapGetImageReal(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3344
SCIP_RETCODE SCIPhashmapSetImageReal(SCIP_HASHMAP *hashmap, void *origin, SCIP_Real image)
Definition misc.c:3434
int SCIPhashmapGetNElements(SCIP_HASHMAP *hashmap)
Definition misc.c:3576
int SCIPhashmapGetNEntries(SCIP_HASHMAP *hashmap)
Definition misc.c:3584
SCIP_HASHMAPENTRY * SCIPhashmapGetEntry(SCIP_HASHMAP *hashmap, int entryidx)
Definition misc.c:3592
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3061
void * SCIPhashmapEntryGetOrigin(SCIP_HASHMAPENTRY *entry)
Definition misc.c:3603
SCIP_RETCODE SCIPhashmapRemoveAll(SCIP_HASHMAP *hashmap)
Definition misc.c:3676
SCIP_Real SCIPhashmapEntryGetImageReal(SCIP_HASHMAPENTRY *entry)
Definition misc.c:3633
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
SCIP_VERBLEVEL SCIPgetVerbLevel(SCIP *scip)
#define SCIPdebugMsg
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition scip_param.c:250
SCIP_RETCODE SCIPaddStringParam(SCIP *scip, const char *name, const char *desc, char **valueptr, SCIP_Bool isadvanced, const char *defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:194
SCIP_RETCODE SCIPgetStringParam(SCIP *scip, const char *name, char **value)
Definition scip_param.c:345
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:57
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition scip_param.c:269
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
SCIP_Bool SCIPisExact(SCIP *scip)
Definition scip_exact.c:193
SCIP_RETCODE SCIPcreateExprQuadratic(SCIP *scip, SCIP_EXPR **expr, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition scip_expr.c:1059
SCIP_RETCODE SCIPcreateExprMonomial(SCIP *scip, SCIP_EXPR **expr, int nfactors, SCIP_VAR **vars, SCIP_Real *exponents, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition scip_expr.c:1167
SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
Definition scip_expr.c:1443
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
#define SCIPfreeBuffer(scip, ptr)
Definition scip_mem.h:134
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
BMS_BUFMEM * SCIPbuffer(SCIP *scip)
Definition scip_mem.c:72
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition scip_mem.h:128
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition scip_mem.h:132
#define SCIPallocBuffer(scip, ptr)
Definition scip_mem.h:122
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition scip_mem.h:137
SCIP_RETCODE SCIPrationalCreateBlock(BMS_BLKMEM *blkmem, SCIP_RATIONAL **rational)
Definition rational.cpp:109
void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition rational.cpp:936
SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
SCIP_RETCODE SCIPrationalCreateString(BMS_BLKMEM *mem, SCIP_RATIONAL **rational, const char *desc)
Definition rational.cpp:797
void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
Definition rational.cpp:462
int SCIPrationalToString(SCIP_RATIONAL *rational, char *str, int strlen)
void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition rational.cpp:604
SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:474
SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:124
SCIP_Bool SCIPrationalIsGE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
SCIP_Bool SCIPrationalIsLE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader,)
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader,)
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition reader.c:700
void SCIPreaderMarkExact(SCIP_READER *reader)
Definition reader.c:690
SCIP_RETCODE SCIPaddSolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool *stored)
Definition scip_sol.c:3914
SCIP_RETCODE SCIPsetSolValExact(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_RATIONAL *val)
Definition scip_sol.c:1614
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition scip_sol.c:1569
SCIP_RETCODE SCIPcreateSolExact(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition scip_sol.c:564
SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
Definition sol.c:4165
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
Definition var.c:23530
SCIP_RETCODE SCIPaddVarExactData(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_RATIONAL *obj)
Definition scip_var.c:299
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23485
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
SCIP_RETCODE SCIPchgVarLbGlobalExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
Definition scip_var.c:5492
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition scip_var.c:9917
SCIP_RETCODE SCIPchgVarUbGlobalExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
Definition scip_var.c:5467
SCIP_RETCODE SCIPcreateVarImpl(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_IMPLINTTYPE impltype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition scip_var.c:225
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition scip_var.c:1887
SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
Definition var.c:24162
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
SCIP_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
Definition var.c:23495
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition scip_var.c:12465
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition scip_var.c:184
SCIP_RETCODE SCIPchgVarObjExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newobj)
Definition scip_var.c:5420
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition scip_var.c:5372
SCIP_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
Definition var.c:23942
SCIP_RATIONAL * SCIPvarGetUbGlobalExact(SCIP_VAR *var)
Definition var.c:24184
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition scip_var.c:5519
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
int SCIPstrncpy(char *t, const char *s, int size)
Definition misc.c:10897
return SCIP_OKAY
SCIPfreeSol(scip, &heurdata->sol))
SCIPcreateSol(scip, &heurdata->sol, heur))
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_VAR * var
static SCIP_Bool propagate
struct BMS_BlkMem BMS_BLKMEM
Definition memory.h:437
public functions to work with algebraic expressions
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
#define SCIPdebugMessage
Definition pub_message.h:96
public data structures and miscellaneous methods
public methods for NLP management
public methods for input file readers
public methods for problem variables
wrapper for rational number arithmetic
wrapper for rational number arithmetic that interacts with GMP
#define READER_DESC
Definition reader_bnd.c:62
#define READER_EXTENSION
Definition reader_bnd.c:63
#define READER_NAME
Definition reader_bnd.c:61
ZIMPL model file reader.
public methods for constraint handler plugins and constraints
public methods for exact solving
general public methods
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for reader plugins
public methods for solutions
public methods for SCIP variables
static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
Main separation function.
miscellaneous datastructures
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
struct SCIP_Expr SCIP_EXPR
Definition type_expr.h:55
@ SCIP_VERBLEVEL_MINIMAL
@ SCIP_VERBLEVEL_NORMAL
@ SCIP_VERBLEVEL_FULL
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
struct SCIP_HashMapEntry SCIP_HASHMAPENTRY
Definition type_misc.h:100
@ SCIP_OBJSENSE_MAXIMIZE
Definition type_prob.h:47
@ SCIP_OBJSENSE_MINIMIZE
Definition type_prob.h:48
enum SCIP_Objsense SCIP_OBJSENSE
Definition type_prob.h:50
struct SCIP_Rational SCIP_RATIONAL
@ SCIP_R_ROUND_UPWARDS
@ SCIP_R_ROUND_DOWNWARDS
type definitions for input file readers
struct SCIP_ReaderData SCIP_READERDATA
Definition type_reader.h:54
struct SCIP_Reader SCIP_READER
Definition type_reader.h:53
#define SCIP_DECL_READERREAD(x)
Definition type_reader.h:88
#define SCIP_DECL_READERCOPY(x)
Definition type_reader.h:63
@ SCIP_SUCCESS
Definition type_result.h:58
@ SCIP_NOFILE
@ SCIP_READERROR
@ SCIP_INVALIDCALL
@ SCIP_ERROR
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
enum SCIP_ImplintType SCIP_IMPLINTTYPE
Definition type_var.h:117
@ SCIP_IMPLINTTYPE_NONE
Definition type_var.h:90
@ SCIP_IMPLINTTYPE_WEAK
Definition type_var.h:91
@ SCIP_VARTYPE_INTEGER
Definition type_var.h:65
@ SCIP_VARTYPE_CONTINUOUS
Definition type_var.h:71
@ SCIP_VARTYPE_BINARY
Definition type_var.h:64
enum SCIP_Vartype SCIP_VARTYPE
Definition type_var.h:73