Scippy

SCIP

Solving Constraint Integer Programs

reader_gms.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 reader_gms.c
26 * @ingroup DEFPLUGINS_READER
27 * @brief GAMS file writer
28 * @author Ambros Gleixner
29 * @author Stefan Vigerske
30 *
31 * @todo Check for words reserved for GAMS.
32 */
33
34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
37#include "scip/cons_nonlinear.h"
38#include "scip/cons_indicator.h"
39#include "scip/cons_knapsack.h"
40#include "scip/cons_linear.h"
41#include "scip/cons_logicor.h"
42#include "scip/cons_setppc.h"
43#include "scip/cons_sos1.h"
44#include "scip/cons_sos2.h"
45#include "scip/cons_varbound.h"
46#include "scip/pub_cons.h"
47#include "scip/pub_message.h"
48#include "scip/pub_misc.h"
49#include "scip/pub_reader.h"
50#include "scip/pub_var.h"
51#include "scip/reader_gms.h"
52#include "scip/scip_cons.h"
53#include "scip/scip_general.h"
54#include "scip/scip_mem.h"
55#include "scip/scip_message.h"
56#include "scip/scip_numerics.h"
57#include "scip/scip_param.h"
58#include "scip/scip_reader.h"
59#include "scip/scip_var.h"
60#include "scip/expr_abs.h"
61#include <string.h>
62
63
64#define READER_NAME "gmsreader"
65#define READER_DESC "file writer for (MI)(N)LPs in GAMS file format"
66#define READER_EXTENSION "gms"
67
68
69#define GMS_MAX_LINELEN 256
70#define GMS_MAX_PRINTLEN 256 /**< the maximum length of any line is 255 + '\\0' = 256*/
71#define GMS_MAX_NAMELEN 64 /**< the maximum length for any name is 63 + '\\0' = 64 */
72#define GMS_PRINTLEN 100
73#define GMS_DEFAULT_BIGM 1e+6
74#define GMS_DEFAULT_INDICATORREFORM 's'
75#define GMS_DEFAULT_SIGNPOWER FALSE
76
77/*
78 * Local methods (for writing)
79 */
80
81static const char badchars[] = "#*+/-@$[](){}";
82
83/** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
84static
86 SCIP* scip, /**< SCIP data structure */
87 SCIP_VAR*** vars, /**< pointer to vars array to get active variables for */
88 SCIP_Real** scalars, /**< pointer to scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
89 int* nvars, /**< pointer to number of variables and values in vars and vals array */
90 int* varssize, /**< pointer to length of vars and scalars array */
91 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
92 SCIP_Bool transformed /**< transformed constraint? */
93 )
94{
95 int requiredsize;
96 int v;
97
98 assert( scip != NULL );
99 assert( vars != NULL );
100 assert( *vars != NULL );
101 assert( scalars != NULL );
102 assert( *scalars != NULL );
103 assert( nvars != NULL );
104 assert( varssize != NULL );
105 assert( *varssize >= *nvars );
106 assert( constant != NULL );
107
108 if( transformed )
109 {
110 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *varssize, constant, &requiredsize, TRUE) );
111
112 if( requiredsize > *varssize )
113 {
114 *varssize = SCIPcalcMemGrowSize(scip, requiredsize);
115 SCIP_CALL( SCIPreallocBufferArray(scip, vars, *varssize) );
117
118 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *varssize, constant, &requiredsize, TRUE) );
119 assert(requiredsize <= *varssize);
120 }
121 }
122 else
123 {
124 for( v = 0; v < *nvars; ++v )
125 {
126 SCIP_CALL( SCIPvarGetOrigvarSum(&(*vars)[v], &(*scalars)[v], constant) );
127 }
128 }
129
130 return SCIP_OKAY;
131}
132
133/** clears the given line buffer */
134static
136 char* linebuffer, /**< line */
137 int* linecnt /**< number of characters in line */
138 )
139{
140 assert( linebuffer != NULL );
141 assert( linecnt != NULL );
142
143 (*linecnt) = 0;
144 linebuffer[0] = '\0';
145}
146
147/** ends the given line with '\\0' and prints it to the given file stream, with a newline at the end */
148static
150 SCIP* scip, /**< SCIP data structure */
151 FILE* file, /**< output file (or NULL for standard output) */
152 char* linebuffer, /**< line */
153 int* linecnt /**< number of characters in line */
154 )
155{
156 assert( scip != NULL );
157 assert( linebuffer != NULL );
158 assert( linecnt != NULL );
159 assert( 0 <= *linecnt && *linecnt < GMS_MAX_LINELEN );
160
161 if( (*linecnt) > 0 )
162 {
163 linebuffer[(*linecnt)] = '\0';
164 SCIPinfoMessage(scip, file, "%s\n", linebuffer);
165 clearLine(linebuffer, linecnt);
166 }
167}
168
169/** ends the given line with '\\0' and prints it to the given file stream, without a newline at the end */
170static
172 SCIP* scip, /**< SCIP data structure */
173 FILE* file, /**< output file (or NULL for standard output) */
174 char* linebuffer, /**< line */
175 int* linecnt /**< number of characters in line */
176 )
177{
178 assert( scip != NULL );
179 assert( linebuffer != NULL );
180 assert( linecnt != NULL );
181 assert( 0 <= *linecnt && *linecnt < GMS_MAX_LINELEN );
182
183 if( (*linecnt) > 0 )
184 {
185 linebuffer[(*linecnt)] = '\0';
186 SCIPinfoMessage(scip, file, "%s", linebuffer);
187 clearLine(linebuffer, linecnt);
188 }
189}
190
191/** appends extension to line and prints it to the give file stream if the
192 * line exceeded the length given in the define GMS_PRINTLEN */
193static
195 SCIP* scip, /**< SCIP data structure */
196 FILE* file, /**< output file (or NULL for standard output) */
197 char* linebuffer, /**< line */
198 int* linecnt, /**< number of characters in line */
199 const char* extension /**< string to extend the line */
200 )
201{
202 size_t len;
203 assert( scip != NULL );
204 assert( linebuffer != NULL );
205 assert( linecnt != NULL );
206 assert( extension != NULL );
207 assert( strlen(linebuffer) + strlen(extension) < GMS_MAX_PRINTLEN );
208
209 /* NOTE: avoid
210 * sprintf(linebuffer, "%s%s", linebuffer, extension);
211 * because of overlapping memory areas in memcpy used in sprintf.
212 */
213 len = strlen(linebuffer);
214 (void) strncat(linebuffer, extension, GMS_MAX_PRINTLEN - len);
215
216 (*linecnt) += (int) strlen(extension);
217
218 SCIPdebugMsg(scip, "linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)len);
219
220 if( (*linecnt) > GMS_PRINTLEN )
221 endLine(scip, file, linebuffer, linecnt);
222}
223
224/** checks string for occurences of bad symbols and replace those by '_' */
225static
227 char* name /**< string to adjust */
228 )
229{
230 const char* badchar;
231
232 assert( name != NULL );
233
234 for( badchar = badchars; *badchar; ++badchar )
235 {
236 char* c = strchr(name, *badchar);
237
238 while( c != NULL )
239 {
240 assert( *c == *badchar );
241
242 *c = '_';
243 c = strchr(c, *badchar);
244 }
245 }
246}
247
248/* print first len-1 characters of name to string s and replace '#', '*', '+', '/', and '-' by '_' if necessary */
249static
251 SCIP* scip, /**< SCIP data structure */
252 char* t, /**< target string */
253 int len, /**< length of t */
254 const char* name /**< source string or format string */
255 )
256{
257 SCIP_Bool replaceforbiddenchars;
258
259 assert( t != NULL );
260 assert( len > 0 );
261
262 SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
263
264 (void) SCIPsnprintf(t, len, "%s", name);
265
266 if( replaceforbiddenchars )
267 conformName(t);
268
269 return SCIP_OKAY;
270}
271
272
273/* retransform to active variables and print in GAMS format to file stream with surrounding bracket, pre- and suffix */
274static
276 SCIP* scip, /**< SCIP data structure */
277 FILE* file, /**< output file (or NULL for standard output) */
278 char* linebuffer, /**< line */
279 int* linecnt, /**< number of characters in line */
280 const char* prefix, /**< prefix (maybe NULL) */
281 const char* suffix, /**< suffix (maybe NULL) */
282 int nvars, /**< number of variables */
283 SCIP_VAR** vars, /**< array of variables */
284 SCIP_Real* vals, /**< array of values (or NULL if all ones) */
285 SCIP_Bool transformed /**< transformed constraint? */
286 )
287{
288 int v;
289 int closingbracket;
290
291 SCIP_VAR* var;
292 char varname[GMS_MAX_NAMELEN];
293 char buffer[GMS_MAX_PRINTLEN];
294 char ext[GMS_MAX_PRINTLEN];
295
296 SCIP_VAR** activevars = NULL;
297 SCIP_Real* activevals = NULL;
298 int nactivevars;
299 int activevarssize;
300 SCIP_Real activeconstant = 0.0;
301
302 assert( scip != NULL );
303 assert( vars != NULL || nvars == 0 );
304
305 if( *linecnt == 0 )
306 /* we start a new line; therefore we tab this line */
307 appendLine(scip, file, linebuffer, linecnt, " ");
308
309 if( nvars == 0 )
310 {
311 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix != NULL ? prefix : "", suffix != NULL ? suffix : "");
312
313 appendLine(scip, file, linebuffer, linecnt, buffer);
314 }
315 else
316 {
317 nactivevars = nvars;
318
319 /* duplicate variable and value array */
320 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars) );
321 if( vals != NULL )
322 {
323 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars) );
324 }
325 else
326 {
327 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
328
329 for( v = 0; v < nactivevars; ++v )
330 activevals[v] = 1.0;
331 }
332 activevarssize = nactivevars;
333
334 /* retransform given variables to active variables */
335 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activevarssize, &activeconstant, transformed) );
336
337 assert( nactivevars == 0 || activevals != NULL );
338
339 if( nactivevars == 0 && SCIPisZero(scip, activeconstant) )
340 {
341 if( *linecnt == 0 )
342 /* we start a new line; therefore we tab this line */
343 appendLine(scip, file, linebuffer, linecnt, " ");
344
345 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix != NULL ? prefix : "", suffix != NULL ? suffix : "");
346
347 appendLine(scip, file, linebuffer, linecnt, buffer);
348 }
349 else
350 {
351 /* buffer prefix */
352 (void) SCIPsnprintf(ext, GMS_MAX_PRINTLEN, "%s(", prefix != NULL ? prefix : "");
353
354 /* find position of closing bracket */
355 closingbracket = nactivevars;
356 if( SCIPisZero(scip, activeconstant) )
357 {
358 do
359 --closingbracket;
360 while( SCIPisZero(scip, activevals[closingbracket]) && closingbracket > 0 );
361 }
362
363 /* print active variables */
364 for( v = 0; v < nactivevars; ++v )
365 {
366 var = activevars[v];
367 assert( var != NULL );
368
369 if( !SCIPisZero(scip, activevals[v]) )
370 {
371 if( *linecnt == 0 )
372 /* we start a new line; therefore we tab this line */
373 appendLine(scip, file, linebuffer, linecnt, " ");
374
376
377 if( SCIPisEQ(scip, activevals[v], 1.0) )
378 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%s%s%s%s", ext, strchr(ext, '(') == NULL ? "+" : "",
379 varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
380 else if( SCIPisEQ(scip, activevals[v], -1.0) )
381 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s-%s%s%s", ext,
382 varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
383 else if( strchr(ext, '(') != NULL )
384 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%.15g*%s%s%s", ext,
385 activevals[v], varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
386 else
387 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%+.15g*%s%s%s", ext,
388 activevals[v], varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
389
390 appendLine(scip, file, linebuffer, linecnt, buffer);
391
392 (void) SCIPsnprintf(ext, GMS_MAX_PRINTLEN, (*linecnt == 0) ? "" : " ");
393 }
394 }
395
396 /* print active constant */
397 if( !SCIPisZero(scip, activeconstant) )
398 {
399 if( *linecnt == 0 )
400 /* we start a new line; therefore we tab this line */
401 appendLine(scip, file, linebuffer, linecnt, " ");
402
403 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%+.15g)%s", ext, activeconstant, suffix ? suffix : "");
404
405 appendLine(scip, file, linebuffer, linecnt, buffer);
406 }
407 /* nothing has been printed, yet */
408 else if( strchr(ext, '(') != NULL )
409 {
410 if( *linecnt == 0 )
411 /* we start a new line; therefore we tab this line */
412 appendLine(scip, file, linebuffer, linecnt, " ");
413
414 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix ? prefix : "", suffix ? suffix : "");
415
416 appendLine(scip, file, linebuffer, linecnt, buffer);
417 }
418 }
419
420 /* free buffer arrays */
421 SCIPfreeBufferArray(scip, &activevars);
422 SCIPfreeBufferArray(scip, &activevals);
423 }
424
425 return SCIP_OKAY;
426}
427
428
429/* print linear row in GAMS format to file stream (without retransformation to active variables) */
430static
432 SCIP* scip, /**< SCIP data structure */
433 FILE* file, /**< output file (or NULL for standard output) */
434 const char* rowname, /**< row name */
435 const char* rownameextension, /**< row name extension */
436 const char* type, /**< row type ("=e=", "=l=", or "=g=") */
437 int nvars, /**< number of variables */
438 SCIP_VAR** vars, /**< array of variables */
439 SCIP_Real* vals, /**< array of values */
440 SCIP_Real rhs /**< right hand side */
441 )
442{
443 int v;
444 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
445 int linecnt;
446
447 SCIP_VAR* var;
448 char varname[GMS_MAX_NAMELEN];
449 char consname[GMS_MAX_NAMELEN + 3]; /* four extra characters for ' ..' */
450 char buffer[GMS_MAX_PRINTLEN];
451
452 assert( scip != NULL );
453 assert( strcmp(type, "=e=") == 0 || strcmp(type, "=l=") == 0 || strcmp(type, "=g=") == 0);
454 assert( nvars == 0 || (vars != NULL && vals != NULL) );
455
456 clearLine(linebuffer, &linecnt);
457
458 /* start each line with a space */
459 appendLine(scip, file, linebuffer, &linecnt, " ");
460
461 /* print row name */
462 if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
463 {
464 (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s%s ..", rowname, rownameextension);
465 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
466 appendLine(scip, file, linebuffer, &linecnt, consname);
467 }
468
469 /* print coefficients */
470 if( nvars == 0 )
471 {
472 /* we start a new line; therefore we tab this line */
473 if( linecnt == 0 )
474 appendLine(scip, file, linebuffer, &linecnt, " ");
475
476 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " 0");
477
478 appendLine(scip, file, linebuffer, &linecnt, buffer);
479 }
480
481 for( v = 0; v < nvars; ++v )
482 {
483 assert(vars != NULL); /* for lint */
484 assert(vals != NULL);
485
486 var = vars[v];
487 assert( var != NULL );
488
489 /* we start a new line; therefore we tab this line */
490 if( linecnt == 0 )
491 appendLine(scip, file, linebuffer, &linecnt, " ");
492
494 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %+.15g*%s", vals[v], varname);
495
496 appendLine(scip, file, linebuffer, &linecnt, buffer);
497 }
498
499 /* print right hand side */
500 if( SCIPisZero(scip, rhs) )
501 rhs = 0.0;
502
503 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s %.15g;", type, rhs);
504
505 /* we start a new line; therefore we tab this line */
506 if( linecnt == 0 )
507 appendLine(scip, file, linebuffer, &linecnt, " ");
508 appendLine(scip, file, linebuffer, &linecnt, buffer);
509
510 endLine(scip, file, linebuffer, &linecnt);
511
512 return SCIP_OKAY;
513}
514
515
516/** prints given linear constraint information in GAMS format to file stream */
517static
519 SCIP* scip, /**< SCIP data structure */
520 FILE* file, /**< output file (or NULL for standard output) */
521 const char* rowname, /**< name of the row */
522 int nvars, /**< number of variables */
523 SCIP_VAR** vars, /**< array of variables */
524 SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
525 SCIP_Real lhs, /**< left hand side */
526 SCIP_Real rhs, /**< right hand side */
527 SCIP_Bool transformed /**< transformed constraint? */
528 )
529{
530 int v;
531 SCIP_VAR** activevars = NULL;
532 SCIP_Real* activevals = NULL;
533 int nactivevars;
534 SCIP_Real activeconstant = 0.0;
535 int activevarssize;
536
537 assert( scip != NULL );
538 assert( rowname != NULL );
539
540 /* The GAMS format does not forbid that the variable array is empty */
541 assert( nvars == 0 || vars != NULL );
542
543 assert( lhs <= rhs );
544
545 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
546 return SCIP_OKAY;
547
548 nactivevars = nvars;
549 if( nvars > 0 )
550 {
551 /* duplicate variable and value array */
552 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars) );
553 if( vals != NULL )
554 {
555 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars) );
556 }
557 else
558 {
559 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
560
561 for( v = 0; v < nactivevars; ++v )
562 activevals[v] = 1.0;
563 }
564 activevarssize = nactivevars;
565
566 /* retransform given variables to active variables */
567 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activevarssize, &activeconstant, transformed) );
568 }
569
570 /* print row(s) in GAMS format */
571 if( SCIPisEQ(scip, lhs, rhs) )
572 {
573 assert( !SCIPisInfinity(scip, rhs) );
574
575 /* print equality constraint */
576 SCIP_CALL( printLinearRow(scip, file, rowname, "", "=e=",
577 nactivevars, activevars, activevals, rhs - activeconstant) );
578 }
579 else
580 {
581 if( !SCIPisInfinity(scip, -lhs) )
582 {
583 /* print inequality ">=" */
584 SCIP_CALL( printLinearRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", "=g=",
585 nactivevars, activevars, activevals, lhs - activeconstant) );
586 }
587 if( !SCIPisInfinity(scip, rhs) )
588 {
589 /* print inequality "<=" */
590 SCIP_CALL( printLinearRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "=l=",
591 nactivevars, activevars, activevals, rhs - activeconstant) );
592 }
593 }
594
595 if( nvars > 0 )
596 {
597 /* free buffer arrays */
598 SCIPfreeBufferArray(scip, &activevars);
599 SCIPfreeBufferArray(scip, &activevals);
600 }
601
602 return SCIP_OKAY;
603}
604
605
606/* print indicator constraint in some GAMS format to file stream (performing retransformation to active variables)
607 * The constraints are of the following form:
608 * \f[
609 * z = 1 -> s = 0
610 * \f]
611 * */
612static
614 SCIP* scip, /**< SCIP data structure */
615 FILE* file, /**< output file (or NULL for standard output) */
616 const char* rowname, /**< row name */
617 SCIP_VAR* z, /**< indicating variable (binary) */
618 SCIP_VAR* s, /**< slack variable */
619 SCIP_Bool* sossetdeclr, /**< buffer to store whether we declared the SOS set for indicator reform */
620 SCIP_Bool transformed /**< transformed constraint? */
621 )
622{
623 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
624 int linecnt;
625 SCIP_Real coef;
626 char indicatorform;
627
628 char consname[GMS_MAX_NAMELEN + 30];
629 char buffer[GMS_MAX_PRINTLEN];
630
631 assert( scip != NULL );
632 assert( strlen(rowname) > 0 );
633 assert( z != NULL );
634 assert( s != NULL );
635 assert( SCIPvarIsBinary(z) );
636 assert( sossetdeclr != NULL );
637
638 clearLine(linebuffer, &linecnt);
639
640 /* start each line with a space */
641 appendLine(scip, file, linebuffer, &linecnt, " ");
642
643 SCIP_CALL( SCIPgetCharParam(scip, "reading/gmsreader/indicatorreform", &indicatorform) );
644
645 switch( indicatorform )
646 {
647 case 'b':
648 {
649 /* print row name */
650 (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s ..", rowname);
651 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
652
653 appendLine(scip, file, linebuffer, &linecnt, consname);
654
655 /* write as s <= upperbound(s)*(1-z) or s <= upperbound(s) * negation(z) */
656 coef = 1.0;
657 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, NULL, " =l= ", 1, &s, &coef, transformed) );
658
659 coef = SCIPvarGetUbGlobal(s);
660 if( SCIPisInfinity(scip, coef) )
661 {
662 SCIP_CALL( SCIPgetRealParam(scip, "reading/gmsreader/bigmdefault", &coef) );
663
664 SCIPwarningMessage(scip, "do not have upper bound on slack variable <%s> in indicator constraint <%s>, will use M = %g.\n",
665 SCIPvarGetName(s), rowname, coef);
666 }
667
668 if( SCIPvarIsNegated(z) )
669 {
671 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "", ";", 1, &z, &coef, transformed) );
672 }
673 else
674 {
675 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g + ", coef);
676
677 coef = -coef;
678 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, buffer, ";", 1, &z, &coef, transformed) );
679 }
680
681 break;
682 }
683
684 case 's':
685 {
686 /* write as
687 * sos1 Variable name_sos(sosset);
688 * name_soseq(sosset).. name_sos(sosset) =e= s$(sameas(sosset,'slack') + z$(sameas(sosset,'bin'));
689 */
690 coef = 1.0;
691 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, rowname) );
692
693 /* declare set for SOS1 declarations from reformulation of indicator, if needed */
694 if( !*sossetdeclr )
695 {
696 SCIPinfoMessage(scip, file, " Set sosset / slack, bin /;\n");
697 *sossetdeclr = TRUE;
698 }
699
700 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "sos1 Variable %s_sos(sosset);", consname);
701 appendLine(scip, file, linebuffer, &linecnt, buffer);
702 endLine(scip, file, linebuffer, &linecnt);
703
704 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s(sosset).. %s_sos(sosset) =e= ", consname, consname);
705 appendLine(scip, file, linebuffer, &linecnt, buffer);
706 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, NULL, "$sameas(sosset,'slack')", 1, &s, &coef, transformed) );
707 if( SCIPvarIsNegated(z) )
708 {
710 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, " + (1-(", "))$sameas(sosset,'bin');", 1, &z, &coef, transformed) );
711 }
712 else
713 {
714 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, " + ", "$sameas(sosset,'bin');", 1, &z, &coef, transformed) );
715 }
716 endLine(scip, file, linebuffer, &linecnt);
717
718 break;
719 }
720
721 default:
722 SCIPerrorMessage("wrong value '%c' for parameter reading/gmsreader/indicatorreform\n", indicatorform);
723 return SCIP_ERROR;
724 }
725
726 endLine(scip, file, linebuffer, &linecnt);
727
728 return SCIP_OKAY;
729}
730
731/* print SOS constraint in some GAMS format to file stream (performing retransformation to active variables)
732 *
733 * write as
734 * Set name_sosset /1*nvars/;
735 * SOS1/2 Variable name_sosvar(name_sosset); name_sosvar.lo(name_sosset) = -inf;
736 * Equation name_sosequ(e1_sosset);
737 * name_sosequ(name_sosset).. name_sosvar(e1_sosset) =e=
738 * vars[0]$sameas(name_sosset, '1') + vars[1]$sameas(name_sosset, '2') + ... + vars[nvars-1]$sameas(name_sosset, nvars);
739 */
740static
742 SCIP* scip, /**< SCIP data structure */
743 FILE* file, /**< output file (or NULL for standard output) */
744 const char* rowname, /**< row name */
745 int nvars, /**< number of variables in SOS */
746 SCIP_VAR** vars, /**< variables in SOS */
747 int sostype, /**< type of SOS: 1 or 2 */
748 SCIP_Bool transformed /**< transformed constraint? */
749 )
750{
751 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
752 int linecnt;
753 SCIP_Real coef;
754 int v;
755
756 char consname[GMS_MAX_NAMELEN + 30];
757 char buffer[GMS_MAX_PRINTLEN];
758
759 assert( scip != NULL );
760 assert( strlen(rowname) > 0 );
761 assert( vars != NULL || nvars == 0 );
762 assert( sostype == 1 || sostype == 2 );
763
764 clearLine(linebuffer, &linecnt);
765
766 /* start each line with a space */
767 appendLine(scip, file, linebuffer, &linecnt, " ");
768
769 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, rowname) );
770
771 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "Set %s_sosset /1*%d/;", consname, nvars);
772 appendLine(scip, file, linebuffer, &linecnt, buffer);
773 endLine(scip, file, linebuffer, &linecnt);
774
775 /* explicitly set lower bound of SOS variables to -inf, as GAMS default is 0.0 */
776 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " SOS%d Variable %s_sosvar(%s_sosset); %s_sosvar.lo(%s_sosset) = -inf;", sostype, consname, consname, consname, consname);
777 appendLine(scip, file, linebuffer, &linecnt, buffer);
778 endLine(scip, file, linebuffer, &linecnt);
779
780 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s(%s_sosset).. %s_sosvar(%s_sosset) =e= ", consname, consname, consname, consname);
781 appendLine(scip, file, linebuffer, &linecnt, buffer);
782 endLine(scip, file, linebuffer, &linecnt);
783
784 coef = 1.0;
785 for( v = 0; v < nvars; ++v )
786 {
787 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "$sameas(%s_sosset,'%d')", consname, v+1);
788 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, v > 0 ? " + " : NULL, buffer, 1, &vars[v], &coef, transformed) ); /*lint !e613*/
789 }
790 appendLine(scip, file, linebuffer, &linecnt, ";");
791 endLine(scip, file, linebuffer, &linecnt);
792
793 return SCIP_OKAY;
794}
795
796/** prints expression in GAMS format to file stream */
797static
799 SCIP* scip, /**< SCIP data structure */
800 FILE* file, /**< output file (or NULL for standard output) */
801 char* linebuffer, /**< line buffer of length GMS_MAX_PRINTLEN */
802 int* linecnt, /**< number of characters in line so far */
803 SCIP_Bool* nsmooth, /**< buffer to store whether we printed a nonsmooth function */
804 SCIP_Bool* nqcons, /**< buffer to update whether we are still quadratic */
805 SCIP_Bool transformed, /**< expression belongs to transformed constraint? */
806 SCIP_EXPR* expr /**< expression to print */
807 )
808{
809 SCIP_EXPRITER* it;
811 int currentchild;
812 unsigned int parentprecedence;
813 long int fpos;
814 SCIP_VAR** activevars = NULL;
815 SCIP_Real* activecoefs = NULL;
816 int nactivevars;
817 int activevarssize;
818 SCIP_Real activeconstant = 0.0;
819 char varname[GMS_MAX_NAMELEN];
820 unsigned int sumprecedence;
821
822 assert(scip != NULL);
823 assert(linebuffer != NULL);
824 assert(linecnt != NULL);
825 assert(nsmooth != NULL);
826 assert(nqcons != NULL);
827 assert(expr != NULL);
828
829 if( file == NULL )
830 file = stdout;
831
832 appendLine(scip, file, linebuffer, linecnt, " ");
833
834 /* store file position at begin of current line */
835 fpos = ftell(file) - *linecnt;
836
837 /* print out current buffer, as we print the expression directly to file */
838 endLineNoNewline(scip, file, linebuffer, linecnt);
839
840 activevarssize = 5;
841 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, activevarssize) );
842 SCIP_CALL( SCIPallocBufferArray(scip, &activecoefs, activevarssize) );
843
847
849
850 while( !SCIPexpriterIsEnd(it) )
851 {
852 stage = SCIPexpriterGetStageDFS(it);
853
855 currentchild = SCIPexpriterGetChildIdxDFS(it);
856 else
857 currentchild = -1;
858
859 if( SCIPexpriterGetParentDFS(it) != NULL )
861 else
862 parentprecedence = 0;
863
864 /* print a newline, if we have printed at least GMS_PRINTLEN chars since the last newline */
865 if( ftell(file) > fpos + GMS_PRINTLEN )
866 {
867 SCIPinfoMessage(scip, file, "\n ");
868 /* store file position at begin of current line again; the -5 is for the whitespace we printed already */
869 fpos = ftell(file) - 5;
870 }
871
872 if( SCIPisExprVar(scip, expr) )
873 {
874 /* special handler for variables:
875 * - map to active variables
876 * - pass variable name through printConformName
877 */
878 if( stage == SCIP_EXPRITER_ENTEREXPR )
879 {
880 activevars[0] = SCIPgetVarExprVar(expr);
881 activecoefs[0] = 1.0;
882 nactivevars = 1;
883
884 SCIP_CALL( getActiveVariables(scip, &activevars, &activecoefs, &nactivevars, &activevarssize, &activeconstant, transformed) );
885
886 if( nactivevars == 1 && activecoefs[0] == 1.0 && activeconstant == 0.0 )
887 {
888 SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(activevars[0])) );
889 SCIPinfoMessage(scip, file, "%s", varname);
890 }
891 else
892 {
893 SCIP_Bool needsign = FALSE;
894 int i;
895
896 /* do as in print of expr_sum: an opening parenthesis may be required */
897 if( sumprecedence <= parentprecedence )
898 SCIPinfoMessage(scip, file, "(");
899
900 if( activeconstant != 0.0 )
901 {
902 SCIPinfoMessage(scip, file, "%.15g", activeconstant);
903 needsign = TRUE;
904 }
905 for( i = 0; i < nactivevars; ++i )
906 {
907 if( REALABS(activecoefs[i]) != 1.0 )
908 {
909 SCIPinfoMessage(scip, file, needsign ? "%+.15g*" : "%.15g*", activecoefs[i]);
910 }
911 else if( activecoefs[i] == 1.0 && needsign )
912 {
913 SCIPinfoMessage(scip, file, "+");
914 }
915 else if( activecoefs[i] == -1.0 )
916 {
917 SCIPinfoMessage(scip, file, "-");
918 }
919
920 SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(activevars[0])) );
921 SCIPinfoMessage(scip, file, "%s", varname);
922
923 needsign = TRUE;
924
925 /* check whether it is time for a linebreak */
926 if( ftell(file) > fpos + GMS_PRINTLEN )
927 {
928 SCIPinfoMessage(scip, file, "\n ");
929 fpos = ftell(file) - 5;
930 }
931 }
932
933 if( sumprecedence <= parentprecedence )
934 SCIPinfoMessage(scip, file, ")");
935 }
936 }
937 }
938 else if( SCIPisExprPower(scip, expr) )
939 {
940 /* special handler for power */
941 SCIP_Real exponent = SCIPgetExponentExprPow(expr);
942
943 if( exponent == 2.0 )
944 {
945 /* write squares as "sqr(child)" */
946 if( stage == SCIP_EXPRITER_ENTEREXPR )
947 SCIPinfoMessage(scip, file, "sqr(");
948 else if( stage == SCIP_EXPRITER_LEAVEEXPR )
949 SCIPinfoMessage(scip, file, ")");
950 }
951 else if( EPSISINT(exponent, 0.0) ) /*lint !e835*/
952 {
953 /* write integer powers as "power(child, exponent)" */
954 if( stage == SCIP_EXPRITER_ENTEREXPR )
955 SCIPinfoMessage(scip, file, "power(");
956 else if( stage == SCIP_EXPRITER_LEAVEEXPR )
957 SCIPinfoMessage(scip, file, ",%g)", exponent);
958 /* if power but not square, then we are no longer quadratic */
959 *nqcons = FALSE;
960 }
961 else if( exponent == 0.5 )
962 {
963 /* write square roots as "sqrt(child)" */
964 if( stage == SCIP_EXPRITER_ENTEREXPR )
965 SCIPinfoMessage(scip, file, "sqrt(");
966 else if( stage == SCIP_EXPRITER_LEAVEEXPR )
967 SCIPinfoMessage(scip, file, ")");
968 *nqcons = FALSE;
969 }
970 else
971 {
972 /* write any other power as "(child)**exponent" */
973 if( stage == SCIP_EXPRITER_ENTEREXPR )
974 SCIPinfoMessage(scip, file, "(");
975 else if( stage == SCIP_EXPRITER_LEAVEEXPR )
976 SCIPinfoMessage(scip, file, exponent >= 0.0 ? ")**%.15g" : ")**(%.15g)", exponent);
977 *nqcons = FALSE;
978 }
979 }
980 else
981 {
982 /* for any other expression, use the print callback of the exprhdlr */
983 SCIP_CALL( SCIPcallExprPrint(scip, expr, stage, currentchild, parentprecedence, file) );
984
985 if( !*nsmooth )
986 {
987 /* check for expression types that require changing modeltype from NLP to DNLP: currently only abs */
988 if( SCIPisExprAbs(scip, expr) )
989 {
990 *nsmooth = TRUE;
991 *nqcons = FALSE;
992 }
993 }
994
995 /* if still quadratic, then check whether expression type is one that cannot occur in quadratics
996 * allowed are sum, product, value, var, and power; the latter two were handled above
997 */
998 if( *nqcons && !SCIPisExprSum(scip, expr) && !SCIPisExprProduct(scip, expr) && !SCIPisExprValue(scip, expr) )
999 *nqcons = FALSE;
1000 }
1001
1002 expr = SCIPexpriterGetNext(it);
1003 }
1004
1005 SCIPfreeExpriter(&it);
1006
1007 SCIPfreeBufferArray(scip, &activecoefs);
1008 SCIPfreeBufferArray(scip, &activevars);
1009
1010 return SCIP_OKAY;
1011}
1012
1013/** print nonlinear row in GAMS format to file stream */
1014static
1016 SCIP* scip, /**< SCIP data structure */
1017 FILE* file, /**< output file (or NULL for standard output) */
1018 const char* rowname, /**< row name */
1019 const char* rownameextension, /**< row name extension */
1020 const char* type, /**< row type ("=e=", "=l=", or "=g=") */
1021 SCIP_EXPR* expr, /**< expression */
1022 SCIP_Real rhs, /**< right hand side */
1023 SCIP_Bool transformed, /**< transformed constraint? */
1024 SCIP_Bool* nsmooth, /**< buffer to store whether we printed a nonsmooth function */
1025 SCIP_Bool* nqcons /**< buffer to update whether we are still quadratic */
1026 )
1027{
1028 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
1029 int linecnt;
1030 char consname[GMS_MAX_NAMELEN + 3];
1031 char buffer[GMS_MAX_PRINTLEN];
1032
1033 assert( scip != NULL );
1034 assert( strlen(rowname) > 0 || strlen(rownameextension) > 0 );
1035 assert( strcmp(type, "=e=") == 0 || strcmp(type, "=l=") == 0 || strcmp(type, "=g=") == 0 );
1036
1037 clearLine(linebuffer, &linecnt);
1038
1039 /* start each line with a space */
1040 appendLine(scip, file, linebuffer, &linecnt, " ");
1041
1042 /* print row name */
1043 (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s%s ..", rowname, rownameextension);
1044 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
1045 appendLine(scip, file, linebuffer, &linecnt, consname);
1046
1047 SCIP_CALL( printExpr(scip, file, linebuffer, &linecnt, nsmooth, nqcons, transformed, expr) );
1048
1049 /* print right hand side */
1050 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s %.15g;", type, rhs);
1051 appendLine(scip, file, linebuffer, &linecnt, buffer);
1052
1053 endLine(scip, file, linebuffer, &linecnt);
1054
1055 return SCIP_OKAY;
1056}
1057
1058/** print nonlinear row in GAMS format to file stream (performing retransformation to active linear variables) */
1059static
1061 SCIP* scip, /**< SCIP data structure */
1062 FILE* file, /**< output file (or NULL for standard output) */
1063 const char* rowname, /**< row name */
1064 SCIP_EXPR* expr, /**< expression */
1065 SCIP_Real lhs, /**< left hand side */
1066 SCIP_Real rhs, /**< right hand side */
1067 SCIP_Bool transformed, /**< transformed constraint? */
1068 SCIP_Bool* nsmooth, /**< buffer to store whether we printed a nonsmooth function */
1069 SCIP_Bool* nqcons /**< buffer to update whether we are still quadratic */
1070 )
1071{
1072 assert( scip != NULL );
1073 assert( strlen(rowname) > 0 );
1074
1075 /* print row(s) in GAMS format */
1076 if( SCIPisEQ(scip, lhs, rhs) )
1077 {
1078 assert( !SCIPisInfinity(scip, rhs) );
1079
1080 /* print equality constraint */
1081 SCIP_CALL( printNonlinearRow(scip, file, rowname, "", "=e=", expr, rhs, transformed, nsmooth, nqcons) );
1082 }
1083 else
1084 {
1085 if( !SCIPisInfinity(scip, -lhs) )
1086 {
1087 /* print inequality ">=" */
1088 SCIP_CALL( printNonlinearRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", "=g=", expr, lhs, transformed, nsmooth, nqcons) );
1089 }
1090 if( !SCIPisInfinity(scip, rhs) )
1091 {
1092 /* print inequality "<=" */
1093 SCIP_CALL( printNonlinearRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "=l=", expr, rhs, transformed, nsmooth, nqcons) );
1094 }
1095 }
1096
1097 if( *nqcons )
1098 {
1099 /* if we are still at most quadratic, check whether that is still the case when considering current constraint */
1100 SCIP_CALL( SCIPcheckExprQuadratic(scip, expr, nqcons) );
1101 if( *nqcons )
1102 *nqcons = SCIPexprAreQuadraticExprsVariables(expr);
1103 }
1104
1105 return SCIP_OKAY;
1106}
1107
1108/** method check if the variable names are not longer than GMS_MAX_NAMELEN */
1109static
1111 SCIP* scip, /**< SCIP data structure */
1112 SCIP_VAR** vars, /**< array of variables */
1113 int nvars /**< number of variables */
1114 )
1115{
1116 int v;
1117 SCIP_VAR* var;
1118 SCIP_Bool replaceforbiddenchars;
1119 const char* badchar;
1120
1121 assert( scip != NULL );
1122 assert( vars != NULL );
1123
1124 SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
1125
1126 /* check if the variable names contain any of the bad symbols */
1127 for( badchar = badchars; *badchar; ++badchar )
1128 {
1129 for( v = 0; v < nvars; ++v )
1130 {
1131 var = vars[v];
1132 assert( var != NULL );
1133
1134 if( strchr(SCIPvarGetName(var), *badchar) != NULL )
1135 {
1136 if( replaceforbiddenchars )
1137 {
1138 SCIPinfoMessage(scip, NULL, "there is a variable name with symbol '%c', not allowed in GAMS format; all '%c' replaced by '_' (consider using 'write genproblem'/'write gentransproblem').\n", *badchar, *badchar);
1139 }
1140 else
1141 {
1142 SCIPwarningMessage(scip, "there is a variable name with symbol '%c', not allowed in GAMS format; use 'write genproblem'/'write gentransproblem', or set 'reading/gmsreader/replaceforbiddenchars' to TRUE and risk duplicate variable names.\n", *badchar);
1143 }
1144
1145 break;
1146 }
1147 }
1148 }
1149
1150 /* check if the variable names are too long */
1151 for( v = 0; v < nvars; ++v )
1152 {
1153 var = vars[v];
1154 assert( var != NULL );
1155
1156 if( strlen(SCIPvarGetName(var)) > GMS_MAX_NAMELEN )
1157 {
1158 SCIPwarningMessage(scip, "there is a variable name which has to be cut down to %d characters; GAMS model might be corrupted.\n",
1159 GMS_MAX_NAMELEN - 1);
1160 break;
1161 }
1162 }
1163
1164 return SCIP_OKAY;
1165}
1166
1167/** method check if the constraint names are not longer than GMS_MAX_NAMELEN */
1168static
1170 SCIP* scip, /**< SCIP data structure */
1171 SCIP_CONS** conss, /**< array of constraints */
1172 int nconss, /**< number of constraints */
1173 SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
1174 )
1175{
1176 int c;
1177 SCIP_CONS* cons;
1178 SCIP_CONSHDLR* conshdlr;
1179 const char* conshdlrname;
1180 SCIP_Bool replaceforbiddenchars;
1181 const char* badchar;
1182
1183 assert( scip != NULL );
1184 assert( conss != NULL );
1185
1186 SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
1187
1188 /* check if the constraint names contain any of the bad symbols */
1189 for( badchar = badchars; *badchar; ++badchar )
1190 {
1191 for( c = 0; c < nconss; ++c )
1192 {
1193 cons = conss[c];
1194 assert( cons != NULL );
1195
1196 if( strchr(SCIPconsGetName(cons), *badchar) != NULL )
1197 {
1198 if( replaceforbiddenchars )
1199 {
1200 SCIPinfoMessage(scip, NULL, "there is a constraint name with symbol '%c', not allowed in GAMS format; all '%c' replaced by '_' (consider using 'write genproblem'/'write gentransproblem').\n", *badchar, *badchar);
1201 }
1202 else
1203 {
1204 SCIPwarningMessage(scip, "there is a constraint name with symbol '%c', not allowed in GAMS format; use 'write genproblem'/'write gentransproblem', or set 'reading/gmsreader/replaceforbiddenchars' to TRUE and risk duplicate variable names.\n", *badchar);
1205 }
1206
1207 break;
1208 }
1209 }
1210 }
1211
1212 /* check if the constraint names are too long */
1213 for( c = 0; c < nconss; ++c )
1214 {
1215 cons = conss[c];
1216 assert( cons != NULL );
1217
1218 /* in case the transformed is written, only constraints are posted which are enabled in the current node */
1219 assert(!transformed || SCIPconsIsEnabled(cons));
1220
1221 conshdlr = SCIPconsGetHdlr(cons);
1222 assert( conshdlr != NULL );
1223
1224 conshdlrname = SCIPconshdlrGetName(conshdlr);
1225 assert( transformed == SCIPconsIsTransformed(cons) );
1226
1227 if( strcmp(conshdlrname, "linear") == 0 || strcmp(conshdlrname, "nonlinear") == 0 )
1228 {
1229 SCIP_Real lhs = strcmp(conshdlrname, "linear") == 0 ? SCIPgetLhsLinear(scip, cons) : SCIPgetLhsNonlinear(cons);
1230 SCIP_Real rhs = strcmp(conshdlrname, "linear") == 0 ? SCIPgetLhsLinear(scip, cons) : SCIPgetRhsNonlinear(cons);
1231
1232 if( SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN )
1233 {
1234 SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
1235 GMS_MAX_NAMELEN - 1);
1236 break;
1237 }
1238 else if( !SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN - 4 )
1239 {
1240 SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
1241 GMS_MAX_NAMELEN - 5);
1242 break;
1243 }
1244 }
1245 else if( strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN )
1246 {
1247 SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
1248 GMS_MAX_NAMELEN - 1);
1249 break;
1250 }
1251 }
1252 return SCIP_OKAY;
1253}
1254
1255
1256/*
1257 * Callback methods of reader
1258 */
1259
1260/** copy method for reader plugins (called when SCIP copies plugins) */
1261static
1263{ /*lint --e{715}*/
1264 assert(scip != NULL);
1265 assert(reader != NULL);
1266 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
1267
1268 /* call inclusion method of reader */
1270
1271 return SCIP_OKAY;
1272}
1273
1274
1275/** problem writing method of reader */
1276static
1278{ /*lint --e{715}*/
1279 SCIP_CALL( SCIPwriteGms(scip, file, name, transformed, objsense, objscale, objoffset, vars,
1280 nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
1281
1282 return SCIP_OKAY;
1283}
1284
1285/*
1286 * reader specific interface methods
1287 */
1288
1289/** includes the gms file reader in SCIP */
1291 SCIP* scip /**< SCIP data structure */
1292 )
1293{
1294 SCIP_READER* reader;
1295
1296 /* include reader */
1298
1299 /* set non fundamental callbacks via setter functions */
1300 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyGms) );
1301 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteGms) );
1302
1303 /* add gms reader parameters for writing routines*/
1305 "reading/gmsreader/replaceforbiddenchars", "shall characters '#', '*', '+', '/', and '-' in variable and constraint names be replaced by '_'?",
1306 NULL, FALSE, FALSE, NULL, NULL) );
1307
1309 "reading/gmsreader/bigmdefault", "default M value for big-M reformulation of indicator constraints in case no bound on slack variable is given",
1311
1313 "reading/gmsreader/indicatorreform", "which reformulation to use for indicator constraints: 'b'ig-M, 's'os1",
1315
1317 "reading/gmsreader/signpower", "is it allowed to use the gams function signpower(x,a)?",
1319
1320 return SCIP_OKAY;
1321}
1322
1323
1324/** writes problem to gms file */
1326 SCIP* scip, /**< SCIP data structure */
1327 FILE* file, /**< output file, or NULL if standard output should be used */
1328 const char* name, /**< problem name */
1329 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
1330 SCIP_OBJSENSE objsense, /**< objective sense */
1331 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
1332 * extobj = objsense * objscale * (intobj + objoffset) */
1333 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
1334 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
1335 int nvars, /**< number of active variables in the problem */
1336 int nbinvars, /**< number of binary variables */
1337 int nintvars, /**< number of general integer variables */
1338 int nimplvars, /**< number of implicit integer variables */
1339 int ncontvars, /**< number of continuous variables */
1340 SCIP_CONS** conss, /**< array with constraints of the problem */
1341 int nconss, /**< number of constraints in the problem */
1342 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
1343 )
1344{
1345 int c;
1346 int v;
1347 int linecnt;
1348 char linebuffer[GMS_MAX_PRINTLEN+1];
1349
1350 char varname[GMS_MAX_NAMELEN];
1351 char buffer[GMS_MAX_PRINTLEN];
1352
1353 SCIP_Real* objcoeffs;
1354
1355 SCIP_CONSHDLR* conshdlr;
1356 const char* conshdlrname;
1357 SCIP_CONS* cons;
1358
1359 char consname[GMS_MAX_NAMELEN];
1360
1361 SCIP_VAR** consvars;
1362 SCIP_Real* consvals;
1363 int nconsvars;
1364
1365 SCIP_VAR* var;
1366 SCIP_VAR* objvar;
1367 SCIP_Real lb;
1368 SCIP_Real ub;
1369 SCIP_Bool nondefbounds;
1370 SCIP_Bool nlcons = FALSE; /* whether there are nonlinear constraints */
1371 SCIP_Bool nqcons = TRUE; /* whether nonlinear constraints are at most quadratic */
1372 SCIP_Bool nsmooth = FALSE; /* whether there are nonsmooth nonlinear constraints */
1373 SCIP_Bool discrete;
1374 SCIP_Bool rangedrow;
1375 SCIP_Bool indicatorsosdef;
1376 SCIP_Bool signpowerallowed;
1377 SCIP_Bool needcomma;
1378
1379 assert( scip != NULL );
1380 assert( vars != NULL || nvars == 0 );
1381
1382 /* check if the variable names are not too long */
1383 SCIP_CALL( checkVarnames(scip, vars, nvars) );
1384 /* check if the constraint names are too long */
1385 SCIP_CALL( checkConsnames(scip, conss, nconss, transformed) );
1386
1387 SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/signpower", &signpowerallowed) );
1388
1389 /* check if the objective is a single continuous variable, so we would not have to introduce an auxiliary variable
1390 * for GAMS
1391 */
1392 objvar = NULL;
1393 if( objscale == 1.0 && objoffset == 0.0 )
1394 {
1395 for( v = 0; v < nvars; ++v )
1396 {
1397 if( SCIPvarGetObj(vars[v]) == 0.0 ) /*lint !e613*/
1398 continue;
1399
1400 if( objvar == NULL )
1401 {
1402 /* first variable with nonzero obj coefficient
1403 * if not active or having coefficient != 1.0, or being binary/integer, then give up
1404 */
1405 if( !SCIPvarIsActive(vars[v]) || SCIPvarGetObj(vars[v]) != 1.0 ||
1406 SCIPvarGetType(vars[v]) < SCIP_VARTYPE_IMPLINT ) /*lint !e613*/
1407 break;
1408
1409 objvar = vars[v]; /*lint !e613*/
1410 }
1411 else
1412 {
1413 /* second variable with nonzero obj coefficient -> give up */
1414 objvar = NULL;
1415 break;
1416 }
1417 }
1418 }
1419
1420 /* print statistics as comment to file */
1421 SCIPinfoMessage(scip, file, "$OFFLISTING\n");
1422 SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
1423 SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
1424 SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
1425 nvars, nbinvars, nintvars, nimplvars, ncontvars);
1426 SCIPinfoMessage(scip, file, "* Constraints : %d\n\n", nconss);
1427
1428 /* print flags */
1429 SCIPinfoMessage(scip, file, "$MAXCOL %d\n", GMS_MAX_LINELEN - 1);
1430 SCIPinfoMessage(scip, file, "$OFFDIGIT\n\n");
1431
1432 /* print variable section */
1433 SCIPinfoMessage(scip, file, "Variables\n");
1434 clearLine(linebuffer, &linecnt);
1435
1436 if( objvar == NULL )
1437 {
1438 /* auxiliary objective variable */
1439 SCIPinfoMessage(scip, file, " objvar%c", nvars > 0 ? ',' : ';');
1440 }
1441
1442 /* "model" variables */
1443 for( v = 0; v < nvars; ++v )
1444 {
1445 var = vars[v]; /*lint !e613*/
1446 assert( var != NULL );
1447
1449 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%c", varname, (v < nvars - 1) ? ',' : ';');
1450 appendLine(scip, file, linebuffer, &linecnt, buffer);
1451
1452 if( (linecnt > 0 && (v == nbinvars - 1 || v == nbinvars + nintvars - 1 ||
1453 v == nbinvars + nintvars + nimplvars - 1)) || v == nvars - 1 )
1454 {
1455 endLine(scip, file, linebuffer, &linecnt);
1456 clearLine(linebuffer, &linecnt);
1457 }
1458 }
1459
1460 SCIPinfoMessage(scip, file, "\n");
1461
1462 /* declare binary variables if present */
1463 if( nbinvars > 0 )
1464 {
1465 SCIPinfoMessage(scip, file, "Binary variables\n");
1466 clearLine(linebuffer, &linecnt);
1467
1468 for( v = 0; v < nbinvars; ++v )
1469 {
1470 var = vars[v]; /*lint !e613*/
1471
1473 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%s", varname, (v < nbinvars - 1) ? "," : ";");
1474
1475 appendLine(scip, file, linebuffer, &linecnt, buffer);
1476 }
1477
1478 endLine(scip, file, linebuffer, &linecnt);
1479 SCIPinfoMessage(scip, file, "\n");
1480 }
1481
1482 /* declare integer variables if present */
1483 if( nintvars > 0 )
1484 {
1485 SCIPinfoMessage(scip, file, "Integer variables\n");
1486 clearLine(linebuffer, &linecnt);
1487
1488 for( v = 0; v < nintvars; ++v )
1489 {
1490 var = vars[nbinvars + v]; /*lint !e613*/
1491
1493 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%s", varname, (v < nintvars - 1) ? "," : ";");
1494
1495 appendLine(scip, file, linebuffer, &linecnt, buffer);
1496 }
1497 endLine(scip, file, linebuffer, &linecnt);
1498 SCIPinfoMessage(scip, file, "\n");
1499 }
1500
1501 /* print variable bounds */
1502 SCIPinfoMessage(scip, file, "* Variable bounds\n");
1503 nondefbounds = FALSE;
1504
1505 for( v = 0; v < nvars; ++v )
1506 {
1507 var = vars[v]; /*lint !e613*/
1508 assert( var != NULL );
1509
1511
1512 if( transformed )
1513 {
1514 /* in case the transformed is written only local bounds are posted which are valid in the current node */
1515 lb = SCIPvarGetLbLocal(var);
1516 ub = SCIPvarGetUbLocal(var);
1517 }
1518 else
1519 {
1520 lb = SCIPvarGetLbOriginal(var);
1521 ub = SCIPvarGetUbOriginal(var);
1522 }
1523 assert( lb <= ub );
1524
1525 /* fixed */
1526 if( SCIPisEQ(scip, lb, ub) )
1527 {
1528 if( v < nintvars )
1529 SCIPinfoMessage(scip, file, " %s.fx = %g;\n", varname, SCIPfloor(scip, lb + 0.5));
1530 else
1531 SCIPinfoMessage(scip, file, " %s.fx = %.15g;\n", varname, lb);
1532 nondefbounds = TRUE;
1533
1534 /* no need to write lower and upper bounds additionally */
1535 continue;
1536 }
1537
1538 /* lower bound */
1539 if( v < nbinvars + nintvars )
1540 {
1541 /* default lower bound of binaries and integers is 0 */
1542 if( !SCIPisZero(scip, lb) )
1543 {
1544 if( !SCIPisInfinity(scip, -lb) )
1545 SCIPinfoMessage(scip, file, " %s.lo = %g;\n", varname, SCIPceil(scip, lb));
1546 else
1547 SCIPinfoMessage(scip, file, " %s.lo = -inf;\n", varname);
1548 nondefbounds = TRUE;
1549 }
1550 }
1551 else if( v >= nbinvars + nintvars && !SCIPisInfinity(scip, -lb) )
1552 {
1553 /* continuous variables are free by default */
1554 SCIPinfoMessage(scip, file, " %s.lo = %.15g;\n", varname, lb);
1555 nondefbounds = TRUE;
1556 }
1557
1558 /* upper bound */
1559 if( v < nbinvars )
1560 {
1561 /* binary variables have default upper bound 1.0 */
1562 if( !SCIPisFeasEQ(scip, ub, 1.0) )
1563 {
1564 SCIPinfoMessage(scip, file, " %s.up = %g;\n", varname, SCIPfeasFloor(scip, ub));
1565 nondefbounds = TRUE;
1566 }
1567 }
1568 else if( v < nbinvars + nintvars )
1569 {
1570 /* integer variables have default upper bound +inf */
1571 if( !SCIPisInfinity(scip, ub) )
1572 {
1573 SCIPinfoMessage(scip, file, " %s.up = %g;\n", varname, SCIPfeasFloor(scip, ub));
1574 nondefbounds = TRUE;
1575 }
1576 }
1577 else
1578 {
1579 /* continuous variables have default upper bound +inf */
1580 if( !SCIPisInfinity(scip, ub) )
1581 {
1582 SCIPinfoMessage(scip, file, " %s.up = %.15g;\n", varname, ub);
1583 nondefbounds = TRUE;
1584 }
1585 }
1586 }
1587
1588 if( !nondefbounds )
1589 SCIPinfoMessage(scip, file, "* (All other bounds at default value: binary [0,1], integer [0,+inf], continuous [-inf,+inf].)\n");
1590 SCIPinfoMessage(scip, file, "\n");
1591
1592 /* print equations section */
1593 if( nconss > 0 || objvar == NULL )
1594 {
1595 SCIPinfoMessage(scip, file, "Equations\n");
1596 clearLine(linebuffer, &linecnt);
1597 }
1598 needcomma = FALSE;
1599
1600 if( objvar == NULL )
1601 {
1602 SCIPinfoMessage(scip, file, " objequ");
1603 needcomma = TRUE;
1604 }
1605
1606 /* declare equations */
1607 for( c = 0; c < nconss; ++c )
1608 {
1609 cons = conss[c];
1610 assert( cons != NULL );
1611
1612 conshdlr = SCIPconsGetHdlr(cons);
1613 assert( conshdlr != NULL );
1614
1616 conshdlrname = SCIPconshdlrGetName(conshdlr);
1617 assert( transformed == SCIPconsIsTransformed(cons) );
1618
1619 rangedrow = strcmp(conshdlrname, "linear") == 0
1622 rangedrow = rangedrow || (strcmp(conshdlrname, "nonlinear") == 0
1625 rangedrow = rangedrow || (strcmp(conshdlrname, "varbound") == 0
1628
1629 /* we declare only those constraints which we can print in GAMS format */
1630 if( strcmp(conshdlrname, "knapsack") != 0 && strcmp(conshdlrname, "logicor") != 0 && strcmp(conshdlrname, "setppc") != 0
1631 && strcmp(conshdlrname, "linear") != 0 && strcmp(conshdlrname, "SOS1") != 0 && strcmp(conshdlrname, "SOS2") != 0
1632 && strcmp(conshdlrname, "nonlinear") != 0
1633 && strcmp(conshdlrname, "varbound") != 0
1634 && strcmp(conshdlrname, "indicator") != 0 )
1635 {
1636 SCIPwarningMessage(scip, "Constraint type <%s> not supported. Skip writing constraint <%s>.\n", conshdlrname, SCIPconsGetName(cons));
1637 continue;
1638 }
1639
1640 if( needcomma )
1641 appendLine(scip, file, linebuffer, &linecnt, ",");
1642
1644 if( rangedrow )
1645 {
1646 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%s%s%s", consname, "_lhs, ", consname, "_rhs");
1647 appendLine(scip, file, linebuffer, &linecnt, buffer);
1648 }
1649 else
1650 {
1651 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s", consname);
1652 appendLine(scip, file, linebuffer, &linecnt, buffer);
1653 }
1654 needcomma = TRUE;
1655 }
1656
1657 if( nconss > 0 || objvar == NULL )
1658 {
1659 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ";");
1660 appendLine(scip, file, linebuffer, &linecnt, buffer);
1661
1662 endLine(scip, file, linebuffer, &linecnt);
1663 SCIPinfoMessage(scip, file, "\n");
1664 }
1665
1666 if( objvar == NULL )
1667 {
1668 /* print objective function equation */
1669 clearLine(linebuffer, &linecnt);
1670 if( objoffset != 0.0 )
1671 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " objequ .. objvar =e= %.15g + ", objscale * objoffset);
1672 else
1673 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " objequ .. objvar =e= ");
1674 appendLine(scip, file, linebuffer, &linecnt, buffer);
1675
1676 SCIP_CALL( SCIPallocBufferArray(scip, &objcoeffs, nvars) );
1677
1678 for( v = 0; v < nvars; ++v )
1679 {
1680 var = vars[v]; /*lint !e613*/
1681 assert( var != NULL );
1682
1683 /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
1684 assert( transformed || SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL || SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED );
1685
1686 objcoeffs[v] = SCIPisZero(scip, SCIPvarGetObj(var)) ? 0.0 : objscale * SCIPvarGetObj(var);
1687 }
1688
1689 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "", ";", nvars, vars, objcoeffs, transformed) );
1690
1691 SCIPfreeBufferArray(scip, &objcoeffs);
1692 endLine(scip, file, linebuffer, &linecnt);
1693 SCIPinfoMessage(scip, file, "\n");
1694 }
1695
1696 /* print constraints */
1697 discrete = nbinvars > 0 || nintvars > 0;
1698 indicatorsosdef = FALSE;
1699 for( c = 0; c < nconss; ++c )
1700 {
1701 cons = conss[c];
1702 assert( cons != NULL );
1703
1704 /* in case the transformed is written, only constraints are posted which are enabled in the current node */
1705 assert(!transformed || SCIPconsIsEnabled(cons));
1706
1707 conshdlr = SCIPconsGetHdlr(cons);
1708 assert( conshdlr != NULL );
1709
1711 conshdlrname = SCIPconshdlrGetName(conshdlr);
1712 assert( transformed == SCIPconsIsTransformed(cons) );
1713
1714 if( strcmp(conshdlrname, "knapsack") == 0 )
1715 {
1716 SCIP_Longint* weights;
1717
1718 consvars = SCIPgetVarsKnapsack(scip, cons);
1719 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
1720
1721 /* copy Longint array to SCIP_Real array */
1722 weights = SCIPgetWeightsKnapsack(scip, cons);
1723 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
1724 for( v = 0; v < nconsvars; ++v )
1725 consvals[v] = (SCIP_Real)weights[v];
1726
1727 SCIP_CALL( printLinearCons(scip, file, consname, nconsvars, consvars, consvals,
1728 -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
1729
1730 SCIPfreeBufferArray(scip, &consvals);
1731 }
1732 else if( strcmp(conshdlrname, "linear") == 0 )
1733 {
1734 SCIP_CALL( printLinearCons(scip, file, consname,
1736 SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
1737 }
1738 else if( strcmp(conshdlrname, "logicor") == 0 )
1739 {
1740 SCIP_CALL( printLinearCons(scip, file, consname,
1742 1.0, SCIPinfinity(scip), transformed) );
1743 }
1744 else if( strcmp(conshdlrname, "nonlinear") == 0 )
1745 {
1746 SCIP_CALL( printNonlinearCons(scip, file, consname,
1747 SCIPgetExprNonlinear(cons), SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons), transformed, &nsmooth, &nqcons) );
1748 nlcons = TRUE;
1749 }
1750 else if( strcmp(conshdlrname, "setppc") == 0 )
1751 {
1752 consvars = SCIPgetVarsSetppc(scip, cons);
1753 nconsvars = SCIPgetNVarsSetppc(scip, cons);
1754
1755 switch( SCIPgetTypeSetppc(scip, cons) )
1756 {
1758 SCIP_CALL( printLinearCons(scip, file, consname,
1759 nconsvars, consvars, NULL, 1.0, 1.0, transformed) );
1760 break;
1762 SCIP_CALL( printLinearCons(scip, file, consname,
1763 nconsvars, consvars, NULL, -SCIPinfinity(scip), 1.0, transformed) );
1764 break;
1766 SCIP_CALL( printLinearCons(scip, file, consname,
1767 nconsvars, consvars, NULL, 1.0, SCIPinfinity(scip), transformed) );
1768 break;
1769 }
1770 }
1771 else if( strcmp(conshdlrname, "varbound") == 0 )
1772 {
1773 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
1774 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
1775
1776 consvars[0] = SCIPgetVarVarbound(scip, cons);
1777 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
1778
1779 consvals[0] = 1.0;
1780 consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
1781
1782 SCIP_CALL( printLinearCons(scip, file, consname,
1783 2, consvars, consvals,
1784 SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
1785
1786 SCIPfreeBufferArray(scip, &consvars);
1787 SCIPfreeBufferArray(scip, &consvals);
1788 }
1789 else if( strcmp(conshdlrname, "indicator") == 0 )
1790 {
1791 SCIP_CALL( printIndicatorCons(scip, file, consname,
1792 SCIPgetBinaryVarIndicator(cons), SCIPgetSlackVarIndicator(cons), &indicatorsosdef,
1793 transformed) );
1794 }
1795 else if( strcmp(conshdlrname, "SOS1") == 0 )
1796 {
1797 SCIP_CALL( printSOSCons(scip, file, consname,
1798 SCIPgetNVarsSOS1(scip, cons), SCIPgetVarsSOS1(scip, cons), 1,
1799 transformed) );
1800 discrete = TRUE;
1801 }
1802 else if( strcmp(conshdlrname, "SOS2") == 0 )
1803 {
1804 SCIP_CALL( printSOSCons(scip, file, consname,
1805 SCIPgetNVarsSOS2(scip, cons), SCIPgetVarsSOS2(scip, cons), 2,
1806 transformed) );
1807 discrete = TRUE;
1808 }
1809 else
1810 {
1811 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
1812 SCIPinfoMessage(scip, file, "* ");
1813 SCIP_CALL( SCIPprintCons(scip, cons, file) );
1814 SCIPinfoMessage(scip, file, ";\n");
1815 }
1816
1817 SCIPinfoMessage(scip, file, "\n");
1818 }
1819 /* if at most quadratic, then cannot have nonsmooth functions */
1820 assert(nlcons || !nsmooth);
1821
1822 /* print model creation */
1823 SCIPinfoMessage(scip, file, "Model m / all /;\n\n");
1824
1825 /* set some options to reduce listing file size */
1826 SCIPinfoMessage(scip, file, "option limrow = 0;\n");
1827 SCIPinfoMessage(scip, file, "option limcol = 0;\n");
1828 /* if GAMS >= 24.2, then set option to ensure default upper bound on integer vars is inf (since 32.1 this is also the default) */
1829 SCIPinfoMessage(scip, file, "$if gamsversion 242 option intvarup = 0;\n\n");
1830
1831 /* print solve command */
1832 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%s",
1833 discrete ? "MI" : "", nlcons ? (nqcons ? "QCP" : ((nsmooth && !discrete) ? "DNLP" : "NLP")) : (discrete > 0 ? "P" : "LP"));
1834
1835 if( objvar != NULL )
1836 {
1838 }
1839
1840 SCIPinfoMessage(scip, file, "$if not set %s $set %s %s\n", buffer, buffer, buffer);
1841 SCIPinfoMessage(scip, file, "Solve m using %%%s%% %simizing %s;\n",
1842 buffer, objsense == SCIP_OBJSENSE_MINIMIZE ? "min" : "max", objvar != NULL ? varname : "objvar");
1843
1844 *result = SCIP_SUCCESS;
1845
1846 return SCIP_OKAY;
1847}
constraint handler for indicator constraints
Constraint handler for knapsack constraints of the form , x binary and .
Constraint handler for linear constraints in their most general form, .
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
constraint handler for nonlinear constraints specified by algebraic expressions
Constraint handler for the set partitioning / packing / covering constraints .
constraint handler for SOS type 1 constraints
constraint handler for SOS type 2 constraints
Constraint handler for variable bound constraints .
#define NULL
Definition: def.h:267
#define SCIP_Longint
Definition: def.h:158
#define EPSISINT(x, eps)
Definition: def.h:210
#define SCIP_REAL_MAX
Definition: def.h:174
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:173
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define REALABS(x)
Definition: def.h:197
#define SCIP_CALL(x)
Definition: def.h:374
absolute expression handler
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2753
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9545
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2728
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9568
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9591
SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10808
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10783
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
@ SCIP_SETPPCTYPE_PARTITIONING
Definition: cons_setppc.h:87
@ SCIP_SETPPCTYPE_COVERING
Definition: cons_setppc.h:89
@ SCIP_SETPPCTYPE_PACKING
Definition: cons_setppc.h:88
SCIP_Bool SCIPisExprAbs(SCIP *scip, SCIP_EXPR *expr)
Definition: expr_abs.c:546
SCIP_RETCODE SCIPwriteGms(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)
Definition: reader_gms.c:1325
SCIP_RETCODE SCIPincludeReaderGms(SCIP *scip)
Definition: reader_gms.c:1290
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_RETCODE SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:167
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:139
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip_param.c:307
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 SCIPgetCharParam(SCIP *scip, const char *name, char *value)
Definition: scip_param.c:326
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4197
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8234
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2537
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8523
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8311
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8214
unsigned int SCIPexprhdlrGetPrecedence(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:565
SCIP_EXPRHDLR * SCIPgetExprhdlrSum(SCIP *scip)
Definition: scip_expr.c:902
SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
Definition: expr_pow.c:3456
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1464
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition: expriter.c:969
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1453
SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
Definition: expr.c:4240
SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1442
void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
Definition: expriter.c:664
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1431
SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2337
SCIP_EXPR * SCIPexpriterGetParentDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:740
SCIP_Bool SCIPisExprPower(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1475
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition: expriter.c:858
SCIP_RETCODE SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
Definition: scip_expr.c:2377
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:416
int SCIPexpriterGetChildIdxDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:707
void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2351
SCIP_EXPRITER_STAGE SCIPexpriterGetStageDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:696
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition: expriter.c:501
SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
Definition: expr.c:3883
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
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:109
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:557
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:219
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:1738
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12774
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17748
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17599
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17538
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18144
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:18024
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17926
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17584
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18088
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17419
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:18044
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18134
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17574
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
static const SCIP_Real scalars[]
Definition: lp.c:5743
memory allocation routines
public methods for managing constraints
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
public data structures and miscellaneous methods
public methods for input file readers
public methods for problem variables
static SCIP_DECL_READERWRITE(readerWriteGms)
Definition: reader_gms.c:1277
static void clearLine(char *linebuffer, int *linecnt)
Definition: reader_gms.c:135
static SCIP_DECL_READERCOPY(readerCopyGms)
Definition: reader_gms.c:1262
#define GMS_MAX_PRINTLEN
Definition: reader_gms.c:70
#define GMS_PRINTLEN
Definition: reader_gms.c:72
static SCIP_RETCODE printNonlinearCons(SCIP *scip, FILE *file, const char *rowname, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed, SCIP_Bool *nsmooth, SCIP_Bool *nqcons)
Definition: reader_gms.c:1060
static SCIP_RETCODE printSOSCons(SCIP *scip, FILE *file, const char *rowname, int nvars, SCIP_VAR **vars, int sostype, SCIP_Bool transformed)
Definition: reader_gms.c:741
static void endLineNoNewline(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_gms.c:171
#define GMS_DEFAULT_INDICATORREFORM
Definition: reader_gms.c:74
#define GMS_DEFAULT_SIGNPOWER
Definition: reader_gms.c:75
static SCIP_RETCODE checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
Definition: reader_gms.c:1110
static SCIP_RETCODE printLinearRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs)
Definition: reader_gms.c:431
static SCIP_RETCODE checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
Definition: reader_gms.c:1169
static SCIP_RETCODE printNonlinearRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_EXPR *expr, SCIP_Real rhs, SCIP_Bool transformed, SCIP_Bool *nsmooth, SCIP_Bool *nqcons)
Definition: reader_gms.c:1015
#define READER_DESC
Definition: reader_gms.c:65
#define GMS_DEFAULT_BIGM
Definition: reader_gms.c:73
static SCIP_RETCODE printLinearCons(SCIP *scip, FILE *file, const char *rowname, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_gms.c:518
static SCIP_RETCODE printConformName(SCIP *scip, char *t, int len, const char *name)
Definition: reader_gms.c:250
static SCIP_RETCODE printActiveVariables(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *prefix, const char *suffix, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool transformed)
Definition: reader_gms.c:275
static void conformName(char *name)
Definition: reader_gms.c:226
#define GMS_MAX_NAMELEN
Definition: reader_gms.c:71
#define READER_EXTENSION
Definition: reader_gms.c:66
static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_gms.c:149
static SCIP_RETCODE printIndicatorCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR *z, SCIP_VAR *s, SCIP_Bool *sossetdeclr, SCIP_Bool transformed)
Definition: reader_gms.c:613
#define READER_NAME
Definition: reader_gms.c:64
static SCIP_RETCODE printExpr(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, SCIP_Bool *nsmooth, SCIP_Bool *nqcons, SCIP_Bool transformed, SCIP_EXPR *expr)
Definition: reader_gms.c:798
static const char badchars[]
Definition: reader_gms.c:81
#define GMS_MAX_LINELEN
Definition: reader_gms.c:69
static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_gms.c:194
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, int *varssize, SCIP_Real *constant, SCIP_Bool transformed)
Definition: reader_gms.c:85
GAMS file reader and writer.
public methods for constraint handler plugins and constraints
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 reader plugins
public methods for SCIP variables
#define SCIP_EXPRITER_VISITINGCHILD
Definition: type_expr.h:693
@ SCIP_EXPRITER_DFS
Definition: type_expr.h:716
#define SCIP_EXPRITER_VISITEDCHILD
Definition: type_expr.h:694
#define SCIP_EXPRITER_LEAVEEXPR
Definition: type_expr.h:695
#define SCIP_EXPRITER_ALLSTAGES
Definition: type_expr.h:696
#define SCIP_EXPRITER_ENTEREXPR
Definition: type_expr.h:692
unsigned int SCIP_EXPRITER_STAGE
Definition: type_expr.h:699
@ SCIP_OBJSENSE_MINIMIZE
Definition: type_prob.h:48
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:50
@ SCIP_SUCCESS
Definition: type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
@ 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_VARTYPE_IMPLINT
Definition: type_var.h:64
@ SCIP_VARSTATUS_ORIGINAL
Definition: type_var.h:49
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:55