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 
36 #include "blockmemshell/memory.h"
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 
81 static const char badchars[] = "#*+/-@$[](){}";
82 
83 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
84 static
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) );
116  SCIP_CALL( SCIPreallocBufferArray(scip, scalars, *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 */
134 static
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 */
148 static
149 void endLine(
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 */
170 static
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 */
193 static
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 '_' */
225 static
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 */
249 static
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 */
274 static
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 
375  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
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) */
430 static
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 
493  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
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 */
517 static
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  * */
612 static
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  {
670  SCIP_CALL( SCIPgetNegatedVar(scip, z, &z) );
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  {
709  SCIP_CALL( SCIPgetNegatedVar(scip, z, &z) );
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  */
740 static
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 */
797 static
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;
810  SCIP_EXPRITER_STAGE stage;
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 
844  SCIP_CALL( SCIPcreateExpriter(scip, &it) );
847 
848  sumprecedence = SCIPexprhdlrGetPrecedence(SCIPgetExprhdlrSum(scip));
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 */
1014 static
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) */
1059 static
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 */
1109 static
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 */
1168 static
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) */
1261 static
1262 SCIP_DECL_READERCOPY(readerCopyGms)
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 */
1276 static
1277 SCIP_DECL_READERWRITE(readerWriteGms)
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 
1448  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
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 
1472  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
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 
1492  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
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 
1510  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
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 
1615  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, SCIPconsGetName(cons)) );
1616  conshdlrname = SCIPconshdlrGetName(conshdlr);
1617  assert( transformed == SCIPconsIsTransformed(cons) );
1618 
1619  rangedrow = strcmp(conshdlrname, "linear") == 0
1620  && !SCIPisInfinity(scip, -SCIPgetLhsLinear(scip, cons)) && !SCIPisInfinity(scip, SCIPgetRhsLinear(scip, cons))
1621  && !SCIPisEQ(scip, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons));
1622  rangedrow = rangedrow || (strcmp(conshdlrname, "nonlinear") == 0
1623  && !SCIPisInfinity(scip, -SCIPgetLhsNonlinear(cons)) && !SCIPisInfinity(scip, SCIPgetRhsNonlinear(cons))
1624  && !SCIPisEQ(scip, SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons)));
1625  rangedrow = rangedrow || (strcmp(conshdlrname, "varbound") == 0
1626  && !SCIPisInfinity(scip, -SCIPgetLhsVarbound(scip, cons)) && !SCIPisInfinity(scip, SCIPgetRhsVarbound(scip, cons))
1627  && !SCIPisEQ(scip, SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons)));
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 
1643  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, SCIPconsGetName(cons)) );
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 
1710  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, SCIPconsGetName(cons)) );
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,
1735  SCIPgetNVarsLinear(scip, cons), SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons),
1736  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
1737  }
1738  else if( strcmp(conshdlrname, "logicor") == 0 )
1739  {
1740  SCIP_CALL( printLinearCons(scip, file, consname,
1741  SCIPgetNVarsLogicor(scip, cons), SCIPgetVarsLogicor(scip, cons), NULL,
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  {
1837  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(objvar)) );
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 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
#define SCIP_EXPRITER_ALLSTAGES
Definition: type_expr.h:696
SCIP_RETCODE SCIPgetCharParam(SCIP *scip, const char *name, char *value)
Definition: scip_param.c:326
#define GMS_MAX_LINELEN
Definition: reader_gms.c:69
static SCIP_DECL_READERWRITE(readerWriteGms)
Definition: reader_gms.c:1277
#define NULL
Definition: def.h:267
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition: expriter.c:501
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8313
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for SCIP parameter handling
Constraint handler for variable bound constraints .
SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10808
public methods for memory management
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9553
SCIP_EXPR * SCIPexpriterGetParentDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:740
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip_param.c:307
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define READER_DESC
Definition: reader_gms.c:65
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18135
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
static void clearLine(char *linebuffer, int *linecnt)
Definition: reader_gms.c:135
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:557
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17600
constraint handler for indicator constraints
SCIP_RETCODE SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
Definition: scip_expr.c:2377
#define FALSE
Definition: def.h:94
#define EPSISINT(x, eps)
Definition: def.h:210
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
Definition: expr_pow.c:3457
#define TRUE
Definition: def.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
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
#define GMS_DEFAULT_INDICATORREFORM
Definition: reader_gms.c:74
static SCIP_RETCODE printConformName(SCIP *scip, char *t, int len, const char *name)
Definition: reader_gms.c:250
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8525
public methods for problem variables
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
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
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2721
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPRHDLR * SCIPgetExprhdlrSum(SCIP *scip)
Definition: scip_expr.c:902
Constraint handler for the set partitioning / packing / covering constraints .
public methods for SCIP variables
#define SCIP_EXPRITER_ENTEREXPR
Definition: type_expr.h:692
#define SCIP_EXPRITER_VISITEDCHILD
Definition: type_expr.h:694
SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
Definition: expr.c:4234
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
static SCIP_RETCODE checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
Definition: reader_gms.c:1110
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1464
public methods for numerical tolerances
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18089
public methods for managing constraints
Constraint handler for knapsack constraints of the form , x binary and .
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
Definition: reader_gms.c:1169
static void conformName(char *name)
Definition: reader_gms.c:226
#define SCIPerrorMessage
Definition: pub_message.h:64
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4199
SCIP_RETCODE SCIPincludeReaderGms(SCIP *scip)
Definition: reader_gms.c:1290
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:18025
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2746
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:416
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:18045
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8216
SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1442
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17420
static SCIP_DECL_READERCOPY(readerCopyGms)
Definition: reader_gms.c:1262
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
#define REALABS(x)
Definition: def.h:197
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
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1453
#define SCIP_CALL(x)
Definition: def.h:380
int SCIPexpriterGetChildIdxDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:707
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:1740
#define GMS_MAX_NAMELEN
Definition: reader_gms.c:71
public methods for constraint handler plugins and constraints
SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2337
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
#define GMS_MAX_PRINTLEN
Definition: reader_gms.c:70
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:91
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
#define GMS_DEFAULT_SIGNPOWER
Definition: reader_gms.c:75
static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_gms.c:149
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:50
#define READER_EXTENSION
Definition: reader_gms.c:66
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9599
constraint handler for nonlinear constraints specified by algebraic expressions
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2537
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8236
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
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17927
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10783
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition: expriter.c:858
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:219
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
Definition: expr.c:3877
Constraint handler for linear constraints in their most general form, .
SCIP_Bool SCIPisExprPower(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1475
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12775
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
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
absolute expression handler
static void endLineNoNewline(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_gms.c:171
static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_gms.c:194
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9576
#define SCIP_REAL_MAX
Definition: def.h:174
void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
Definition: expriter.c:664
void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2351
static const char badchars[]
Definition: reader_gms.c:81
GAMS file reader and writer.
#define GMS_DEFAULT_BIGM
Definition: reader_gms.c:73
general public methods
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
unsigned int SCIPexprhdlrGetPrecedence(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:565
static const SCIP_Real scalars[]
Definition: lp.c:5743
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
#define READER_NAME
Definition: reader_gms.c:64
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 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
SCIP_EXPRITER_STAGE SCIPexpriterGetStageDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:696
public methods for message output
SCIP_Bool SCIPisExprAbs(SCIP *scip, SCIP_EXPR *expr)
Definition: expr_abs.c:546
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
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1431
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17539
#define SCIP_Real
Definition: def.h:173
public methods for input file readers
#define GMS_PRINTLEN
Definition: reader_gms.c:72
constraint handler for SOS type 1 constraints
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
public methods for message handling
#define SCIP_Longint
Definition: def.h:158
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17585
#define SCIP_EXPRITER_LEAVEEXPR
Definition: type_expr.h:695
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
unsigned int SCIP_EXPRITER_STAGE
Definition: type_expr.h:699
constraint handler for SOS type 2 constraints
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18145
#define SCIP_EXPRITER_VISITINGCHILD
Definition: type_expr.h:693
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition: expriter.c:969
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
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
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
public methods for reader plugins
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
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
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
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_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1529
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_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17749
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17575
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
memory allocation routines