Scippy

SCIP

Solving Constraint Integer Programs

reader_osil.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-2021 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file reader_osil.c
17  * @ingroup DEFPLUGINS_READER
18  * @brief OS instance language (OSiL) format file reader
19  * @author Stefan Vigerske
20  * @author Ingmar Vierhaus
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #define _USE_MATH_DEFINES /* to get M_PI and M_E on Windows */ /*lint !750 */
26 #include "blockmemshell/memory.h"
27 #include "nlpi/pub_expr.h"
29 #include "scip/cons_linear.h"
30 #include "scip/cons_nonlinear.h"
31 #include "scip/cons_quadratic.h"
32 #include "scip/cons_sos1.h"
33 #include "scip/cons_sos2.h"
34 #include "scip/pub_cons.h"
35 #include "scip/pub_message.h"
36 #include "scip/pub_misc.h"
37 #include "scip/pub_nlp.h"
38 #include "scip/pub_var.h"
39 #include "scip/reader_osil.h"
40 #include "scip/scip_cons.h"
41 #include "scip/scip_mem.h"
42 #include "scip/scip_numerics.h"
43 #include "scip/scip_param.h"
44 #include "scip/scip_prob.h"
45 #include "scip/scip_reader.h"
46 #include "scip/scip_var.h"
47 #include <stdlib.h>
48 #include <string.h>
49 #include "xml/xml.h"
50 
51 #define READER_NAME "osilreader"
52 #define READER_DESC "file reader for OS instance language (OSiL) format"
53 #define READER_EXTENSION "osil"
54 
55 /*
56  * Data structures
57  */
58 
59 /** type of constraint */
60 typedef enum
61 {
62  LINEAR, /**< linear constraint */
63  QUADRATIC, /**< quadratic constraint */
64  NONLINEAR /**< general nonlinear constraint */
65 } CONSTYPE;
66 
67 
68 /*
69  * Local methods
70  */
71 
72 /** create variables with bounds and type according to xml data */
73 static
75  SCIP* scip, /**< SCIP data structure */
76  const XML_NODE* datanode, /**< XML root node for instance data */
77  SCIP_VAR*** vars, /**< buffer to store pointer to variable array */
78  int* nvars, /**< buffer to store number of variables */
79  SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
80  SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
81  SCIP_Bool dynamiccols, /**< should columns be added and removed dynamically to the LP? */
82  SCIP_Bool dynamicrows, /**< should rows be added and removed dynamically to the LP? */
83  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occured */
84  )
85 {
86  const XML_NODE* variables;
87  const XML_NODE* varnode;
88  const char* attrval;
89  int varssize;
90 
91  assert(scip != NULL);
92  assert(datanode != NULL);
93  assert(vars != NULL);
94  assert(nvars != NULL);
95  assert(doingfine != NULL);
96 
97  *vars = NULL;
98  *nvars = 0;
99 
100  variables = xmlFindNodeMaxdepth(datanode, "variables", 0, 1);
101 
102  if( variables == NULL )
103  {
104  /* no variables: strange but ok so far */
105  return SCIP_OKAY;
106  }
107 
108  /* get number of variables */
109  attrval = xmlGetAttrval(variables, "numberOfVariables");
110  if( attrval == NULL )
111  {
112  SCIPerrorMessage("Attribute \"numberOfVariables\" not found in <variables> node.\n");
113  *doingfine = FALSE;
114  return SCIP_OKAY;
115  }
116 
117  varssize = (int)strtol(attrval, (char**)&attrval, 10);
118  if( *attrval != '\0' || varssize < 0 )
119  {
120  SCIPerrorMessage("Invalid value '%s' for \"numberOfVariables\" attribute.\n", xmlGetAttrval(variables, "numberOfVariables"));
121  *doingfine = FALSE;
122  return SCIP_OKAY;
123  }
124  assert(varssize >= 0);
125 
126  SCIP_CALL( SCIPallocBufferArray(scip, vars, varssize) );
127 
128  /* parse variable nodes, create SCIP vars and add to problem
129  * create bounddisjunction constraints for semicontinuous/semiinteger variables
130  */
131  for( varnode = xmlFirstChild(variables); varnode != NULL; varnode = xmlNextSibl(varnode) )
132  {
133  const char* varname;
134  SCIP_VARTYPE vartype;
135  SCIP_Real varlb;
136  SCIP_Real varub;
137  SCIP_Real semibound;
138 
139  if( varssize == *nvars )
140  {
141  SCIPerrorMessage("Expected %d variables, got at least %d many.\n", varssize, *nvars+1);
142  *doingfine = FALSE;
143  return SCIP_OKAY;
144  }
145 
146  /* find variable name */
147  varname = xmlGetAttrval(varnode, "name");
148 
149  /* check for mult attribute */
150  attrval = xmlGetAttrval(varnode, "mult");
151  if( attrval != NULL && strcmp(attrval, "1") != 0 )
152  {
153  SCIPerrorMessage("Variable attribute 'mult' not supported (while parsing variable <%s>)\n", varname);
154  *doingfine = FALSE;
155  return SCIP_OKAY;
156  }
157 
158  /* find variable lower bound (default is 0.0 !) */
159  attrval = xmlGetAttrval(varnode, "lb");
160  if( attrval == NULL )
161  varlb = 0.0;
162  else if( strcmp(attrval, "-INF") == 0 )
163  varlb = -SCIPinfinity(scip);
164  else if( strcmp(attrval, "INF") == 0 )
165  varlb = SCIPinfinity(scip);
166  else
167  {
168  varlb = strtod(attrval, (char**)&attrval);
169  if( *attrval != '\0' )
170  {
171  SCIPerrorMessage("Error parsing variable lower bound '%s' for variable <%s>\n", attrval, varname);
172  *doingfine = FALSE;
173  return SCIP_OKAY;
174  }
175  }
176 
177  /* find variable upper bound (default is infinity) */
178  attrval = xmlGetAttrval(varnode, "ub");
179  if( attrval == NULL )
180  varub = SCIPinfinity(scip);
181  else if( strcmp(attrval, "-INF") == 0 )
182  varub = -SCIPinfinity(scip);
183  else if( strcmp(attrval, "INF") == 0 )
184  varub = SCIPinfinity(scip);
185  else
186  {
187  varub = strtod(attrval, (char**)&attrval);
188  if( *attrval != '\0' )
189  {
190  SCIPerrorMessage("Error parsing variable upper bound '%s' for variable <%s>\n", attrval, varname);
191  *doingfine = FALSE;
192  return SCIP_OKAY;
193  }
194  }
195 
196  semibound = SCIP_INVALID;
197 
198  /* find variable type (default is continuous)
199  * adjust variable lower bound for semicontinuous variables
200  */
201  attrval = xmlGetAttrval(varnode, "type");
202  if( attrval == NULL )
203  vartype = SCIP_VARTYPE_CONTINUOUS;
204  else switch( *attrval )
205  {
206  case 'C':
207  vartype = SCIP_VARTYPE_CONTINUOUS;
208  break;
209  case 'B':
210  vartype = SCIP_VARTYPE_BINARY;
211  if( varub > 1.0 )
212  varub = 1.0;
213  break;
214  case 'I':
215  vartype = SCIP_VARTYPE_INTEGER;
216  break;
217  case 'D':
218  vartype = SCIP_VARTYPE_CONTINUOUS;
219  if( varlb > 0.0 )
220  semibound = varlb;
221  varlb = 0.0;
222  break;
223  case 'J':
224  vartype = SCIP_VARTYPE_INTEGER;
225  if( varlb > 0.0 )
226  semibound = varlb;
227  varlb = 0.0;
228  break;
229  default:
230  SCIPerrorMessage("Unsupported variable type '%s' for variable <%s>\n", attrval, varname);
231  *doingfine = FALSE;
232  return SCIP_OKAY;
233  }
234 
235  if( vartype != SCIP_VARTYPE_CONTINUOUS )
236  {
237  varlb = SCIPceil(scip, varlb);
238  varub = SCIPfloor(scip, varub);
239  }
240 
241  /* create SCIP variable */
242  SCIP_CALL( SCIPcreateVar(scip, &(*vars)[*nvars], varname, varlb, varub, 0.0, vartype, !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) );
243  assert((*vars)[*nvars] != NULL);
244 
245  /* add variable to problem */
246  SCIP_CALL( SCIPaddVar(scip, (*vars)[*nvars]) );
247 
248  /* if variable is actually semicontinuous or semiintegral, create bounddisjunction constraint (var <= 0.0 || var >= semibound) */
249  if( semibound != SCIP_INVALID ) /*lint !e777*/
250  {
251  SCIP_CONS* cons;
252  SCIP_VAR* consvars[2];
253  SCIP_BOUNDTYPE boundtypes[2];
254  SCIP_Real bounds[2];
255  char name[SCIP_MAXSTRLEN];
256 
257  consvars[0] = (*vars)[*nvars];
258  consvars[1] = (*vars)[*nvars];
259 
260  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
261  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
262 
263  bounds[0] = 0.0;
264  bounds[1] = semibound;
265 
266  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_semibound", SCIPvarGetName((*vars)[*nvars]));
267 
268  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, name, 2, consvars, boundtypes, bounds,
269  initialconss, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows, FALSE) );
270  SCIP_CALL( SCIPaddCons(scip, cons) );
271  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
272  }
273 
274  ++*nvars;
275  }
276  if( *nvars < varssize )
277  {
278  SCIPerrorMessage("Expected %d variables, but got only %d many.\n", varssize, *nvars);
279  *doingfine = FALSE;
280  return SCIP_OKAY;
281  }
282 
283  return SCIP_OKAY;
284 }
285 
286 /** setup linear coefficients and constant of objective and objective sense */
287 static
289  SCIP* scip, /**< SCIP data structure */
290  const XML_NODE* datanode, /**< XML root node for instance data */
291  SCIP_VAR** vars, /**< variables in order of OSiL indices */
292  int nvars, /**< number of variables */
293  SCIP_Bool dynamiccols, /**< should columns be added and removed dynamically to the LP? */
294  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occured */
295  )
296 {
297  const XML_NODE* objective;
298  const XML_NODE* coefnode;
299  const char* attrval;
300 
301  assert(scip != NULL);
302  assert(datanode != NULL);
303  assert(vars != NULL || nvars == 0);
304  assert(doingfine != NULL);
305 
306  /* check for first objective */
307  objective = xmlFindNodeMaxdepth(datanode, "obj", 0, 2);
308 
309  /* if no objective, then nothing to do here */
310  if( objective == NULL )
311  return SCIP_OKAY;
312 
313  /* check for mult attribute */
314  attrval = xmlGetAttrval(objective, "mult");
315  if( attrval != NULL && strcmp(attrval, "1") != 0 )
316  {
317  SCIPerrorMessage("Objective attribute 'mult' not supported.\n");
318  *doingfine = FALSE;
319  return SCIP_OKAY;
320  }
321 
322  /* objective sense */
323  attrval = xmlGetAttrval(objective, "maxOrMin");
324  if( attrval == NULL )
325  {
326  SCIPerrorMessage("Objective sense missing.\n");
327  *doingfine = FALSE;
328  return SCIP_OKAY;
329  }
330  else if( strcmp(attrval, "min") == 0 )
331  {
333  }
334  else if( strcmp(attrval, "max") == 0 )
335  {
337  }
338  else
339  {
340  SCIPerrorMessage("Cannot parse objective sense '%s'.\n", attrval);
341  *doingfine = FALSE;
342  return SCIP_OKAY;
343  }
344 
345  /* objective coefficients */
346  for( coefnode = xmlFirstChild(objective); coefnode != NULL; coefnode = xmlNextSibl(coefnode) )
347  {
348  SCIP_Real val;
349  int idx;
350 
351  /* get variable index */
352  attrval = xmlGetAttrval(coefnode, "idx");
353  if( attrval == NULL )
354  {
355  SCIPerrorMessage("Missing \"idx\" attribute in objective coefficient.\n");
356  *doingfine = FALSE;
357  return SCIP_OKAY;
358  }
359  idx = (int)strtol(attrval, (char**)&attrval, 10);
360  if( *attrval != '\0' )
361  {
362  SCIPerrorMessage("Error parsing variable index '%s' of objective coefficient.\n", xmlGetAttrval(coefnode, "idx"));
363  *doingfine = FALSE;
364  return SCIP_OKAY;
365  }
366 
367  if( idx < 0 || idx >= nvars )
368  {
369  SCIPerrorMessage("Invalid variable index '%d' of objective coefficient.\n", idx);
370  *doingfine = FALSE;
371  return SCIP_OKAY;
372  }
373 
374  /* get coefficient value */
375  if( xmlFirstChild(coefnode) == NULL || xmlGetData(xmlFirstChild(coefnode)) == NULL )
376  {
377  SCIPerrorMessage("No objective coefficient stored for %d'th variable (<%s>).\n", idx, SCIPvarGetName(vars[idx])); /*lint !e613*/
378  *doingfine = FALSE;
379  return SCIP_OKAY;
380  }
381 
382  attrval = xmlGetData(xmlFirstChild(coefnode));
383  val = strtod(attrval, (char**)&attrval);
384  if( *attrval != '\0' )
385  {
386  SCIPerrorMessage("Error parsing objective coefficient value '%s' for %d'th variable (<%s>).\n", xmlGetData(xmlFirstChild(coefnode)), idx, SCIPvarGetName(vars[idx])); /*lint !e613*/
387  *doingfine = FALSE;
388  return SCIP_OKAY;
389  }
390 
391  /* change objective coefficient of SCIP variable */
392  SCIP_CALL( SCIPchgVarObj(scip, vars[idx], val) ); /*lint !e613*/
393  }
394 
395  /* objective constant: model as fixed variable, if nonzero */
396  attrval = xmlGetAttrval(objective, "constant");
397  if( attrval != NULL )
398  {
399  SCIP_Real objconst;
400 
401  objconst = strtod(attrval, (char**)&attrval);
402  if( *attrval != '\0' )
403  {
404  SCIPerrorMessage("Error parsing objective constant '%s'\n", xmlGetAttrval(objective, "constant"));
405  *doingfine = FALSE;
406  return SCIP_OKAY;
407  }
408 
409  if( objconst != 0.0 )
410  {
411  SCIP_VAR* objconstvar;
412 
413  SCIP_CALL( SCIPcreateVar(scip, &objconstvar, "objconstvar", objconst, objconst, 1.0, SCIP_VARTYPE_CONTINUOUS, !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) );
414  SCIP_CALL( SCIPaddVar(scip, objconstvar) );
415  SCIP_CALL( SCIPreleaseVar(scip, &objconstvar) );
416  }
417  }
418 
419  if( xmlNextSibl(objective) != NULL )
420  {
421  SCIPerrorMessage("Multiple objectives not supported by SCIP.\n");
422  *doingfine = FALSE;
423  return SCIP_OKAY;
424  }
425 
426  return SCIP_OKAY;
427 }
428 
429 /** setup constraint sides as linear constraints
430  *
431  * constraints are not added to the problem yet
432  */
433 static
435  SCIP* scip, /**< SCIP data structure */
436  const XML_NODE* datanode, /**< XML root node for instance data */
437  SCIP_CONS*** conss, /**< buffer to store array of (linear) constraints */
438  CONSTYPE** constypes, /**< buffer to store type of constraints (will be all LINEAR) */
439  int* nconss, /**< buffer to store number of constraints */
440  SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
441  SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
442  SCIP_Bool dynamicrows, /**< should rows be added and removed dynamically to the LP? */
443  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occured */
444  )
445 {
446  const XML_NODE* constraints;
447  const XML_NODE* consnode;
448  const char* attrval;
449  int consssize;
450  char name[20];
451 
452  assert(scip != NULL);
453  assert(datanode != NULL);
454  assert(conss != NULL);
455  assert(constypes != NULL);
456  assert(nconss != NULL);
457  assert(doingfine != NULL);
458 
459  *conss = NULL;
460  *constypes = NULL;
461  *nconss = 0;
462 
463  constraints = xmlFindNodeMaxdepth(datanode, "constraints", 0, 1);
464 
465  /* if no constraints, then nothing to do here */
466  if( constraints == NULL )
467  return SCIP_OKAY;
468 
469  /* read number of constraints */
470  attrval = xmlGetAttrval(constraints, "numberOfConstraints");
471  if( attrval == NULL )
472  {
473  SCIPerrorMessage("Attribute \"numberOfConstraints\" not found in <constraints> node.\n");
474  *doingfine = FALSE;
475  return SCIP_OKAY;
476  }
477 
478  consssize = (int)strtol(attrval, (char**)&attrval, 10);
479  if( *attrval != '\0' || consssize < 0 )
480  {
481  SCIPerrorMessage("Invalid value '%s' for \"numberOfConstraints\" attribute.\n", xmlGetAttrval(constraints, "numberOfConstraints"));
482  *doingfine = FALSE;
483  return SCIP_OKAY;
484  }
485  assert(consssize >= 0);
486 
487  SCIP_CALL( SCIPallocBufferArray(scip, conss, consssize) );
488  SCIP_CALL( SCIPallocBufferArray(scip, constypes, consssize) );
489 
490  /* read constraint names, lhs, rhs, constant */
491  for( consnode = xmlFirstChild(constraints); consnode != NULL; consnode = xmlNextSibl(consnode) )
492  {
493  const char* consname;
494  SCIP_Real conslhs;
495  SCIP_Real consrhs;
496 
497  if( consssize == *nconss )
498  {
499  SCIPerrorMessage("Expected %d constraints, but got at least %d many.\n", consssize, *nconss+1);
500  *doingfine = FALSE;
501  return SCIP_OKAY;
502  }
503 
504  /* find constraint name */
505  consname = xmlGetAttrval(consnode, "name");
506  if( consname == NULL )
507  {
508  (void) SCIPsnprintf(name, 20, "cons%d", *nconss);
509  consname = name;
510  }
511 
512  /* check for mult attribute */
513  attrval = xmlGetAttrval(consnode, "mult");
514  if( attrval != NULL && strcmp(attrval, "1") != 0 )
515  {
516  SCIPerrorMessage("Constraint attribute 'mult' not supported (while parsing constraint <%s>).\n", consname);
517  *doingfine = FALSE;
518  return SCIP_OKAY;
519  }
520 
521  /* find constraint lower bound (=lhs) (default is -infinity) */
522  attrval = xmlGetAttrval(consnode, "lb");
523  if( attrval == NULL )
524  conslhs = -SCIPinfinity(scip);
525  else if( strcmp(attrval, "-INF") == 0 )
526  conslhs = -SCIPinfinity(scip);
527  else if( strcmp(attrval, "INF") == 0 )
528  conslhs = SCIPinfinity(scip);
529  else
530  {
531  conslhs = strtod(attrval, (char**)&attrval);
532  if( *attrval != '\0' )
533  {
534  SCIPerrorMessage("Error parsing constraint lower bound '%s' for constraint <%s>.\n", attrval, consname);
535  *doingfine = FALSE;
536  return SCIP_OKAY;
537  }
538  }
539 
540  /* find constraint upper bound (=rhs) (default is +infinity) */
541  attrval = xmlGetAttrval(consnode, "ub");
542  if( attrval == NULL )
543  consrhs = SCIPinfinity(scip);
544  else if( strcmp(attrval, "-INF") == 0 )
545  consrhs = -SCIPinfinity(scip);
546  else if( strcmp(attrval, "INF") == 0 )
547  consrhs = SCIPinfinity(scip);
548  else
549  {
550  consrhs = strtod(attrval, (char**)&attrval);
551  if( *attrval != '\0' )
552  {
553  SCIPerrorMessage("Error parsing constraint upper bound '%s' for constraint <%s>.\n", attrval, consname);
554  *doingfine = FALSE;
555  return SCIP_OKAY;
556  }
557  }
558 
559  /* find constraint constant (default is 0.0) and substract from lhs/rhs */
560  attrval = xmlGetAttrval(consnode, "constant");
561  if( attrval != NULL )
562  {
563  SCIP_Real consconstant;
564 
565  consconstant = strtod(attrval, (char**)&attrval);
566  if( *attrval != '\0' )
567  {
568  SCIPerrorMessage("Error parsing constraint constant '%s' for constraint <%s>.\n", attrval, consname);
569  *doingfine = FALSE;
570  return SCIP_OKAY;
571  }
572  if( conslhs > -SCIPinfinity(scip) )
573  conslhs -= consconstant;
574  if( consrhs < SCIPinfinity(scip) )
575  consrhs -= consconstant;
576  }
577 
578  /* create SCIP linear constraint */
579  SCIP_CALL( SCIPcreateConsLinear(scip, &(*conss)[*nconss], consname, 0, NULL, NULL, conslhs, consrhs,
580  initialconss, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows, FALSE) );
581  assert((*conss)[*nconss] != NULL);
582 
583  (*constypes)[*nconss] = LINEAR;
584 
585  ++*nconss;
586  }
587 
588  if( *nconss < consssize )
589  {
590  SCIPerrorMessage("Got %d constraints, but expected %d many.\n", *nconss, consssize);
591  *doingfine = FALSE;
592  return SCIP_OKAY;
593  }
594 
595  return SCIP_OKAY;
596 }
597 
598 /** reads mult and incr attributes of an OSiL node
599  *
600  * if mult attribute is not present, then returns mult=1
601  * if incr attribute is not present, then returns incrint=0 and incrreal=0
602  */
603 static
605  const XML_NODE* node, /**< XML node to read attributes from */
606  int* mult, /**< buffer to store mult */
607  int* incrint, /**< buffer to store incr as int, or NULL if no int expected */
608  SCIP_Real* incrreal, /**< buffer to store incr as real, or NULL if no real expected */
609  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occured */
610  )
611 {
612  const char* attrval;
613 
614  assert(node != NULL);
615  assert(mult != NULL);
616  assert(doingfine != NULL);
617 
618  *mult = 1;
619  if( incrint != NULL )
620  *incrint = 0;
621  if( incrreal != NULL )
622  *incrreal = 0.0;
623 
624  attrval = xmlGetAttrval(node, "mult");
625  if( attrval == NULL )
626  return;
627 
628  /* read "mult" attribute */
629  *mult = (int)strtol(attrval, (char**)&attrval, 10);
630  if( *attrval != '\0' || *mult < 1 )
631  {
632  SCIPerrorMessage("Invalid value '%s' in \"mult\" attribute of node.\n", xmlGetAttrval(node, "mult"));
633  *doingfine = FALSE;
634  return;
635  }
636 
637  if( *mult == 1 )
638  return;
639 
640  /* read "incr" attribute */
641  attrval = xmlGetAttrval(node, "incr");
642  if( attrval == NULL )
643  return;
644 
645  if( incrint != NULL )
646  {
647  *incrint = (int)strtol(attrval, (char**)&attrval, 10);
648  if( *attrval != '\0' )
649  {
650  SCIPerrorMessage("Invalid value '%s' in \"incr\" attribute of node.\n", xmlGetAttrval(node, "incr"));
651  *doingfine = FALSE;
652  return;
653  }
654  }
655 
656  if( incrreal != NULL )
657  {
658  *incrreal = strtod(attrval, (char**)&attrval);
659  if( *attrval != '\0' || !SCIPisFinite(*incrreal) )
660  {
661  SCIPerrorMessage("Invalid value '%s' in \"incr\" attribute of node.\n", xmlGetAttrval(node, "incr"));
662  *doingfine = FALSE;
663  return;
664  }
665  }
666 }
667 
668 /** parse linear coefficients of constraints */
669 static
671  SCIP* scip, /**< SCIP data structure */
672  const XML_NODE* datanode, /**< XML root node for instance data */
673  SCIP_VAR** vars, /**< variables in order of OSiL indices */
674  int nvars, /**< number of variables */
675  SCIP_CONS** conss, /**< constraints in order of OSiL indices */
676  CONSTYPE* constypes, /**< type of constraints (assumed to be LINEAR) */
677  int nconss, /**< number of constraints */
678  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occured */
679  )
680 {
681  const XML_NODE* lincoef;
682  const XML_NODE* startnode;
683  const XML_NODE* idxnode;
684  const XML_NODE* valnode;
685  const XML_NODE* elnode;
686  const char* attrval;
687  SCIP_Bool rowmajor;
688  int* start;
689  int* idx;
690  SCIP_Real* val;
691  int nnz;
692  int count;
693  int mult;
694  int incrint;
695  SCIP_Real incrreal;
696 
697  assert(scip != NULL);
698  assert(datanode != NULL);
699  assert(vars != NULL || nvars == 0);
700  assert(conss != NULL || nconss == 0);
701  assert(constypes != NULL || nconss == 0);
702  assert(doingfine != NULL);
703 
704  lincoef = xmlFindNodeMaxdepth(datanode, "linearConstraintCoefficients", 0, 1);
705 
706  if( lincoef == NULL )
707  return SCIP_OKAY;
708 
709  /* get number of linear constraint coefficients */
710  attrval = xmlGetAttrval(lincoef, "numberOfValues");
711  if( attrval == NULL )
712  {
713  SCIPerrorMessage("Attribute \"numberOfValues\" not found for <linearConstraintCoefficients> node.\n");
714  *doingfine = FALSE;
715  return SCIP_OKAY;
716  }
717 
718  nnz = (int)strtol(attrval, (char**)&attrval, 10);
719  if( *attrval != '\0' || nnz < 0 )
720  {
721  SCIPerrorMessage("Invalid value '%s' for \"numberOfValues\" attribute in <linearConstraintCoefficients> node.\n", xmlGetAttrval(lincoef, "numberOfValues"));
722  *doingfine = FALSE;
723  return SCIP_OKAY;
724  }
725  assert(nnz >= 0);
726 
727  /* check for start, rowIdx, colIdx, and value nodes */
728  startnode = xmlFindNodeMaxdepth(lincoef, "start", 0, 1);
729  if( startnode == NULL )
730  {
731  SCIPerrorMessage("Node <start> not found inside <linearConstraintCoefficients> node.\n");
732  *doingfine = FALSE;
733  return SCIP_OKAY;
734  }
735 
736  idxnode = xmlFindNodeMaxdepth(lincoef, "rowIdx", 0, 1);
737  if( idxnode != NULL )
738  {
739  if( xmlFindNodeMaxdepth(lincoef, "colIdx", 0, 1) != NULL )
740  {
741  SCIPerrorMessage("Both <rowIdx> and <colIdx> found under <linearConstraintCoefficients> node.\n");
742  *doingfine = FALSE;
743  return SCIP_OKAY;
744  }
745  rowmajor = FALSE;
746  }
747  else
748  {
749  idxnode = xmlFindNodeMaxdepth(lincoef, "colIdx", 0, 1);
750  if( idxnode == NULL )
751  {
752  SCIPerrorMessage("Both <rowIdx> and <colIdx> not found under <linearConstraintCoefficients> node.\n");
753  *doingfine = FALSE;
754  return SCIP_OKAY;
755  }
756  rowmajor = TRUE;
757  }
758 
759  valnode = xmlFindNodeMaxdepth(lincoef, "value", 0, 1);
760  if( valnode == NULL )
761  {
762  SCIPerrorMessage("<value> node not found under <linearConstraintCoefficients> node.\n");
763  *doingfine = FALSE;
764  return SCIP_OKAY;
765  }
766 
767  start = NULL;
768  idx = NULL;
769  val = NULL;
770 
771  /* read row or column start indices */
772  SCIP_CALL( SCIPallocBufferArray(scip, &start, (rowmajor ? nconss : nvars) + 1) );
773 
774  count = 0;
775  for( elnode = xmlFirstChild(startnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
776  {
777  /* check for <el> node and read it's data */
778  if( strcmp(xmlGetName(elnode), "el") != 0 )
779  {
780  SCIPerrorMessage("Expected <el> node under <start> node in <linearConstraintCoefficients>, but got '%s'.\n", xmlGetName(elnode));
781  *doingfine = FALSE;
782  goto CLEANUP;
783  }
784  if( count >= (rowmajor ? nconss : nvars) + 1 )
785  {
786  SCIPerrorMessage("Too many elements under <start> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", (rowmajor ? nconss : nvars) + 1, count + 1);
787  *doingfine = FALSE;
788  goto CLEANUP;
789  }
790  if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
791  {
792  SCIPerrorMessage("No data in <el> node in <linearConstraintCoefficients>.\n");
793  *doingfine = FALSE;
794  goto CLEANUP;
795  }
796 
797  start[count] = (int)strtol(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval, 10);
798 
799  if( *attrval != '\0' || start[count] < 0 || (start[count] > nnz) )
800  {
801  SCIPerrorMessage("Invalid value '%s' in <el> node under <start> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode));
802  *doingfine = FALSE;
803  goto CLEANUP;
804  }
805 
806  /* add additional start-indices according to mult and incr attributes */
807  readMultIncr(elnode, &mult, &incrint, NULL, doingfine);
808  if( !*doingfine )
809  goto CLEANUP;
810 
811  for( --mult; mult > 0; --mult )
812  {
813  ++count;
814  if( count >= (rowmajor ? nconss : nvars) + 1 )
815  {
816  SCIPerrorMessage("Too many elements under <start> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", (rowmajor ? nconss : nvars) + 1, count + 1);
817  *doingfine = FALSE;
818  goto CLEANUP;
819  }
820  start[count] = start[count-1] + incrint;
821  }
822  }
823  if( count != (rowmajor ? nconss : nvars) + 1 )
824  {
825  SCIPerrorMessage("Got only %d <start> entries in <linearConstraintCoefficients>, but expected %d many.\n", count, (rowmajor ? nconss : nvars) + 1);
826  *doingfine = FALSE;
827  goto CLEANUP;
828  }
829 
830  /* read row or column indices */
831  SCIP_CALL( SCIPallocBufferArray(scip, &idx, nnz) );
832 
833  count = 0;
834  for( elnode = xmlFirstChild(idxnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
835  {
836  /* check for <el> node and read it's data */
837  if( strcmp(xmlGetName(elnode), "el") != 0 )
838  {
839  SCIPerrorMessage("Expected <el> node under <%s> node in <linearConstraintCoefficients>, but got '%s'.\n", rowmajor ? "colIdx" : "rowIdx", xmlGetName(elnode));
840  *doingfine = FALSE;
841  goto CLEANUP;
842  }
843  if( count >= nnz )
844  {
845  SCIPerrorMessage("Too many elements under <%s> node in <linearConstraintCoefficients>, expected %d many, but got at least %d.\n", rowmajor ? "colIdx" : "rowIdx", nnz, count + 1);
846  *doingfine = FALSE;
847  goto CLEANUP;
848  }
849  if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
850  {
851  SCIPerrorMessage("No data in <el> node under <%s> node in <linearConstraintCoefficients>.\n", rowmajor ? "colIdx" : "rowIdx");
852  *doingfine = FALSE;
853  goto CLEANUP;
854  }
855 
856  idx[count] = (int)strtol(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval, 10);
857 
858  if( *attrval != '\0' || idx[count] < 0 || (idx[count] >= (rowmajor ? nvars : nconss)) )
859  {
860  SCIPerrorMessage("Invalid value '%s' in <el> node under <%s> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode), rowmajor ? "colIdx" : "rowIdx");
861  *doingfine = FALSE;
862  goto CLEANUP;
863  }
864 
865  /* add additional indices according to mult and incr attributes */
866  readMultIncr(elnode, &mult, &incrint, NULL, doingfine);
867  if( !*doingfine )
868  goto CLEANUP;
869 
870  for( --mult; mult > 0; --mult )
871  {
872  ++count;
873  if( count >= nnz )
874  {
875  SCIPerrorMessage("Too many elements under <%s> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", rowmajor ? "colIdx" : "rowIdx", nnz, count + 1);
876  *doingfine = FALSE;
877  goto CLEANUP;
878  }
879  idx[count] = idx[count-1] + incrint;
880  }
881  }
882  if( count != nnz )
883  {
884  SCIPerrorMessage("Got only %d entries in <%s> node in <linearConstraintCoefficients>, expected %d many.\n", count, rowmajor ? "colIdx" : "rowIdx", nnz);
885  *doingfine = FALSE;
886  goto CLEANUP;
887  }
888 
889  /* read coefficient values */
890  SCIP_CALL( SCIPallocBufferArray(scip, &val, nnz) );
891 
892  count = 0;
893  for( elnode = xmlFirstChild(valnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
894  {
895  /* check for <el> node and read it's data */
896  if( strcmp(xmlGetName(elnode), "el") != 0 )
897  {
898  SCIPerrorMessage("Expected <el> node under <value> node in <linearConstraintCoefficients>, but got '%s'.\n", xmlGetName(elnode));
899  *doingfine = FALSE;
900  goto CLEANUP;
901  }
902  if( count >= nnz )
903  {
904  SCIPerrorMessage("Too many elements under <value> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", nnz, count + 1);
905  *doingfine = FALSE;
906  goto CLEANUP;
907  }
908  if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
909  {
910  SCIPerrorMessage("No data in <el> node under <value> node in <linearConstraintCoefficients>.\n");
911  *doingfine = FALSE;
912  goto CLEANUP;
913  }
914 
915  val[count] = strtod(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval);
916 
917  if( *attrval != '\0' || !SCIPisFinite(val[count]) )
918  {
919  SCIPerrorMessage("Invalid value '%s' in <el> node under <value> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode));
920  *doingfine = FALSE;
921  goto CLEANUP;
922  }
923 
924  /* add additional values according to mult and incr attributes */
925  readMultIncr(elnode, &mult, NULL, &incrreal, doingfine);
926  if( !*doingfine )
927  goto CLEANUP;
928 
929  for( --mult; mult > 0; --mult )
930  {
931  ++count;
932  if( count >= nnz )
933  {
934  SCIPerrorMessage("Too many elements under <value> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", nnz, count + 1);
935  *doingfine = FALSE;
936  goto CLEANUP;
937  }
938  val[count] = val[count-1] + incrreal;
939  }
940  }
941  if( count != nnz )
942  {
943  SCIPerrorMessage("Got only %d entries under <value> node in <linearConstraintCoefficients>, expected %d many.\n", count, nnz);
944  *doingfine = FALSE;
945  goto CLEANUP;
946  }
947 
948  /* add coefficients to linear constraints */
949  if( rowmajor )
950  {
951  int row;
952  int pos;
953  for( row = 0; row < nconss; ++row )
954  {
955  /* these asserts were checked above */
956  assert(start[row] >= 0);
957  assert(start[row+1] >= 0);
958  assert(start[row] <= nnz);
959  assert(start[row+1] <= nnz);
960  for( pos = start[row]; pos < start[row+1]; ++pos )
961  {
962  /* these asserts were checked above */
963  assert(pos >= 0);
964  assert(pos < nnz);
965  assert(idx[pos] >= 0);
966  assert(idx[pos] < nvars);
967 
968  assert(constypes[row] == LINEAR); /*lint !e613*/
969 
970  SCIP_CALL( SCIPaddCoefLinear(scip, conss[row], vars[idx[pos]], val[pos]) ); /*lint !e613*/
971  }
972  }
973  }
974  else
975  {
976  int col;
977  int pos;
978  for( col = 0; col < nvars; ++col )
979  {
980  /* these asserts were checked above */
981  assert(start[col] >= 0);
982  assert(start[col+1] >= 0);
983  assert(start[col] <= nnz);
984  assert(start[col+1] <= nnz);
985  for( pos = start[col]; pos < start[col+1]; ++pos )
986  {
987  /* these asserts were checked above */
988  assert(pos >= 0);
989  assert(pos < nnz);
990  assert(idx[pos] >= 0);
991  assert(idx[pos] < nconss);
992 
993  assert(constypes[idx[pos]] == LINEAR); /*lint !e613*/
994 
995  SCIP_CALL( SCIPaddCoefLinear(scip, conss[idx[pos]], vars[col], val[pos]) ); /*lint !e613*/
996  }
997  }
998  }
999 
1000  CLEANUP:
1001  SCIPfreeBufferArrayNull(scip, &val);
1002  SCIPfreeBufferArrayNull(scip, &idx);
1003  SCIPfreeBufferArrayNull(scip, &start);
1004 
1005  return SCIP_OKAY;
1006 }
1007 
1008 /** read quadratic coefficients of constraints and objective */
1009 static
1011  SCIP* scip, /**< SCIP data structure */
1012  const XML_NODE* datanode, /**< XML root node for instance data */
1013  SCIP_VAR** vars, /**< variables in order of OSiL indices */
1014  int nvars, /**< number of variables */
1015  SCIP_CONS** conss, /**< constraints in order of OSiL indices */
1016  CONSTYPE* constypes, /**< type of constraints (assumed to be LINEAR) */
1017  int nconss, /**< number of constraints */
1018  SCIP_CONS** objcons, /**< buffer to store constraint for nonlinear part of objective function, or to add to if already existing */
1019  CONSTYPE* objconstype, /**< buffer to store type of objective constraint, if created (should be QUADRATIC) */
1020  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occured */
1021  )
1022 {
1023  const XML_NODE* quadcoef;
1024  const XML_NODE* qterm;
1025  const char* attrval;
1026  SCIP_CONS* cons;
1027  int nqterms;
1028  int count;
1029  int considx;
1030  int varidx1;
1031  int varidx2;
1032  SCIP_Real coef;
1033  int c;
1034 
1035  /* quadratic terms, split up by constraints+objective */
1036  SCIP_VAR*** vars1;
1037  SCIP_VAR*** vars2;
1038  SCIP_Real** coefs;
1039  int* nterms;
1040  int* termssize;
1041 
1042  assert(scip != NULL);
1043  assert(datanode != NULL);
1044  assert(objcons != NULL);
1045  assert(doingfine != NULL);
1046  assert(conss != NULL || nconss == 0);
1047  assert(constypes != NULL || nconss == 0);
1048 
1049  quadcoef = xmlFindNodeMaxdepth(datanode, "quadraticCoefficients", 0, 1);
1050 
1051  if( quadcoef == NULL )
1052  return SCIP_OKAY;
1053 
1054  /* read number of quadratic terms */
1055  attrval = xmlGetAttrval(quadcoef, "numberOfQuadraticTerms");
1056  if( attrval == NULL )
1057  {
1058  SCIPerrorMessage("Attribute \"numberOfQuadraticTerms\" not found for <quadraticCoefficients> node.\n");
1059  *doingfine = FALSE;
1060  return SCIP_OKAY;
1061  }
1062 
1063  nqterms = (int)strtol(attrval, (char**)&attrval, 10);
1064  if( *attrval != '\0' || nqterms < 0 )
1065  {
1066  SCIPerrorMessage("Invalid value '%s' for \"numberOfQuadraticTerms\" attribute of <quadraticCoefficients> node.\n", xmlGetAttrval(quadcoef, "numberOfQuadraticTerms"));
1067  *doingfine = FALSE;
1068  return SCIP_OKAY;
1069  }
1070  assert(nqterms >= 0);
1071 
1072  if( nqterms == 0 )
1073  return SCIP_OKAY;
1074 
1075  assert(vars != NULL);
1076 
1077  SCIP_CALL( SCIPallocClearBufferArray(scip, &vars1, nconss+1) );
1078  SCIP_CALL( SCIPallocClearBufferArray(scip, &vars2, nconss+1) );
1079  SCIP_CALL( SCIPallocClearBufferArray(scip, &coefs, nconss+1) );
1080  SCIP_CALL( SCIPallocClearBufferArray(scip, &nterms, nconss+1) );
1081  SCIP_CALL( SCIPallocClearBufferArray(scip, &termssize, nconss+1) );
1082 
1083  count = 0;
1084  for( qterm = xmlFirstChild(quadcoef); qterm != NULL; qterm = xmlNextSibl(qterm), ++count )
1085  {
1086  /* check for qterm node */
1087  if( strcmp(xmlGetName(qterm), "qTerm") != 0 )
1088  {
1089  SCIPerrorMessage("Expected <qTerm> node under <quadraticCoefficients> node, but got <%s>\n", xmlGetName(qterm));
1090  *doingfine = FALSE;
1091  goto TERMINATE;
1092  }
1093  if( count >= nqterms )
1094  {
1095  SCIPerrorMessage("Too many quadratic terms under <quadraticCoefficients> node, expected %d many, but got at least %d.\n", nqterms, count + 1);
1096  *doingfine = FALSE;
1097  goto TERMINATE;
1098  }
1099 
1100  /* get constraint index, or -1 for objective */
1101  attrval = xmlGetAttrval(qterm, "idx");
1102  if( attrval == NULL )
1103  {
1104  SCIPerrorMessage("Missing \"idx\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1105  *doingfine = FALSE;
1106  goto TERMINATE;
1107  }
1108 
1109  considx = (int)strtol(attrval, (char**)&attrval, 10);
1110  if( *attrval != '\0' || considx < -1 || considx >= nconss )
1111  {
1112  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idx"), count);
1113  *doingfine = FALSE;
1114  goto TERMINATE;
1115  }
1116 
1117  /* get index of first variable */
1118  attrval = xmlGetAttrval(qterm, "idxOne");
1119  if( attrval == NULL )
1120  {
1121  SCIPerrorMessage("Missing \"idxOne\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1122  *doingfine = FALSE;
1123  goto TERMINATE;
1124  }
1125 
1126  varidx1 = (int)strtol(attrval, (char**)&attrval, 10);
1127  if( *attrval != '\0' || varidx1 < 0 || varidx1 >= nvars )
1128  {
1129  SCIPerrorMessage("Invalid value '%s' in \"idxOne\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idxOne"), count);
1130  *doingfine = FALSE;
1131  goto TERMINATE;
1132  }
1133 
1134  /* get index of second variable */
1135  attrval = xmlGetAttrval(qterm, "idxTwo");
1136  if( attrval == NULL )
1137  {
1138  SCIPerrorMessage("Missing \"idxTwo\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1139  *doingfine = FALSE;
1140  goto TERMINATE;
1141  }
1142 
1143  varidx2 = (int)strtol(attrval, (char**)&attrval, 10);
1144  if( *attrval != '\0' || varidx2 < 0 || varidx2 >= nvars )
1145  {
1146  SCIPerrorMessage("Invalid value '%s' in \"idxTwo\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idxTwo"), count);
1147  *doingfine = FALSE;
1148  goto TERMINATE;
1149  }
1150 
1151  /* get (optional) coefficient of quadratic term */
1152  attrval = xmlGetAttrval(qterm, "coef");
1153  if( attrval != NULL )
1154  {
1155  coef = strtod(attrval, (char**)&attrval);
1156  if( *attrval != '\0' || (coef != coef) ) /*lint !e777*/
1157  {
1158  SCIPerrorMessage("Invalid value '%s' in \"coef\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "coef"), count);
1159  *doingfine = FALSE;
1160  goto TERMINATE;
1161  }
1162  }
1163  else
1164  {
1165  /* default is 1.0 according to specification */
1166  coef = 1.0;
1167  }
1168 
1169  /* skip zero coefficients */
1170  if( coef == 0.0 )
1171  continue;
1172 
1173  /* put objective at end of array */
1174  if( considx == -1 )
1175  considx = nconss;
1176 
1177  if( nterms[considx] + 1 > termssize[considx] )
1178  {
1179  termssize[considx] = SCIPcalcMemGrowSize(scip, nterms[considx] + 1);
1180  SCIP_CALL( SCIPreallocBufferArray(scip, &vars1[considx], termssize[considx]) ); /*lint !e866*/
1181  SCIP_CALL( SCIPreallocBufferArray(scip, &vars2[considx], termssize[considx]) ); /*lint !e866*/
1182  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs[considx], termssize[considx]) ); /*lint !e866*/
1183  }
1184 
1185  vars1[considx][nterms[considx]] = vars[varidx1];
1186  vars2[considx][nterms[considx]] = vars[varidx2];
1187  coefs[considx][nterms[considx]] = coef;
1188  ++nterms[considx];
1189  }
1190 
1191  if( count != nqterms )
1192  {
1193  SCIPerrorMessage("Got only %d quadratic terms under <quadraticCoefficients> node, but expected %d many.\n", count, nqterms);
1194  *doingfine = FALSE;
1195  goto TERMINATE;
1196  }
1197 
1198  if( nterms[nconss] > 0 )
1199  {
1200  /* create constraint to hold quadratic part of objective; note that
1201  * reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model constraints and
1202  * variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary objective
1203  * variable is loose with infinite best bound, triggering the problem that an LP that is unbounded because
1204  * of loose variables with infinite best bound cannot be solved)
1205  */
1206 
1207  SCIP_VAR* objvar;
1208  SCIP_Real minusone;
1209 
1210  /* we should have only looked at the linear part of the problem before, so there was no need to add a constraint for the objective */
1211  assert(*objcons == NULL);
1212 
1213  SCIP_CALL( SCIPcreateVar(scip, &objvar, "quadobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
1215  SCIP_CALL( SCIPaddVar(scip, objvar) );
1216 
1217  minusone = -1.0;
1218  SCIP_CALL( SCIPcreateConsQuadratic(scip, objcons, "quadobj", 1, &objvar, &minusone, nterms[nconss], vars1[nconss], vars2[nconss], coefs[nconss],
1219  SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE ? -SCIPinfinity(scip) : 0.0,
1220  SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE ? SCIPinfinity(scip) : 0.0,
1221  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1222  *objconstype = QUADRATIC;
1223 
1224  SCIP_CALL( SCIPreleaseVar(scip, &objvar) );
1225 
1226  SCIPfreeBufferArray(scip, &coefs[nconss]);
1227  SCIPfreeBufferArray(scip, &vars2[nconss]);
1228  SCIPfreeBufferArray(scip, &vars1[nconss]);
1229  }
1230 
1231  for( c = nconss-1; c >= 0; --c )
1232  {
1233  if( nterms[c] == 0 )
1234  continue;
1235 
1236  /* we should have looked only at the linear part of the problem before, so all constraints should still be linear */
1237  assert(constypes[c] == LINEAR); /*lint !e613*/
1238 
1239  /* replace linear constraint by quadratic constraint */
1240  cons = conss[c]; /*lint !e613*/
1241 
1242  /* coverity[negative_returns] */
1244  SCIPgetNVarsLinear(scip, cons), SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons),
1245  nterms[c], vars1[c], vars2[c], coefs[c],
1246  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons),
1250 
1251  SCIP_CALL( SCIPreleaseCons(scip, &conss[c]) ); /*lint !e613*/
1252 
1253  conss[c] = cons; /*lint !e613*/
1254  constypes[c] = QUADRATIC; /*lint !e613*/
1255 
1256  SCIPfreeBufferArray(scip, &coefs[c]);
1257  SCIPfreeBufferArray(scip, &vars2[c]);
1258  SCIPfreeBufferArray(scip, &vars1[c]);
1259  }
1260 
1261  TERMINATE:
1262  SCIPfreeBufferArray(scip, &termssize);
1263  SCIPfreeBufferArray(scip, &nterms);
1264  SCIPfreeBufferArray(scip, &coefs);
1265  SCIPfreeBufferArray(scip, &vars2);
1266  SCIPfreeBufferArray(scip, &vars1);
1267 
1268  return SCIP_OKAY;
1269 }
1270 
1271 /** transforms OSnL expression tree into SCIP expression */
1272 static
1274  SCIP* scip, /**< SCIP data structure */
1275  SCIP_EXPR** expr, /**< buffer to store pointer to created expression */
1276  const XML_NODE* node, /**< root node of expression to be read */
1277  int* exprvaridx, /**< array with index of problem variables in expression graph */
1278  int* nexprvars, /**< number of variables in currently processed expression so far */
1279  int nvars, /**< total number of variables in problem (and length of exprvaridx array) */
1280  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
1281  )
1282 {
1283  const char* exprname;
1284 
1285  assert(scip != NULL);
1286  assert(expr != NULL);
1287  assert(node != NULL);
1288  assert(exprvaridx != NULL || nvars == 0);
1289  assert(nexprvars != NULL);
1290  assert(doingfine != NULL);
1291 
1292  exprname = xmlGetName(node);
1293  assert(exprname != NULL);
1294 
1295  *expr = NULL;
1296 
1297  /* zero argument operands */
1298  if( strcmp(exprname, "variable") == 0 )
1299  {
1300  const char* attrval;
1301  SCIP_Real coef;
1302  int idx;
1303 
1304  /* read variable index */
1305  attrval = xmlGetAttrval(node, "idx");
1306  if( attrval == NULL )
1307  {
1308  SCIPerrorMessage("Attribute \"idx\" required for <variable> node in nonlinear expression\n");
1309  *doingfine = FALSE;
1310  return SCIP_OKAY;
1311  }
1312 
1313  idx = (int)strtol(attrval, (char**)&attrval, 10);
1314  if( *attrval != '\0' || idx < 0 || idx >= nvars )
1315  {
1316  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of <variable> node in nonlinear expression.\n", xmlGetAttrval(node, "idx"));
1317  *doingfine = FALSE;
1318  return SCIP_OKAY;
1319  }
1320 
1321  /* read variable coefficient */
1322  attrval = xmlGetAttrval(node, "coef");
1323  if( attrval != NULL )
1324  {
1325  coef = strtod(attrval, (char**)&attrval);
1326  if( *attrval != '\0' || !SCIPisFinite(coef) )
1327  {
1328  SCIPerrorMessage("Invalid value '%s' in \"coef\" attribute of <variable> node in nonlinear expression.\n", xmlGetAttrval(node, "coef"));
1329  *doingfine = FALSE;
1330  return SCIP_OKAY;
1331  }
1332  }
1333  else
1334  {
1335  coef = 1.0;
1336  }
1337 
1338  /* assign index to variable, if we see it the first time */
1339  if( exprvaridx[idx] == -1 ) /*lint !e613*/
1340  {
1341  exprvaridx[idx] = *nexprvars; /*lint !e613*/
1342  ++*nexprvars;
1343  }
1344 
1345  /* create VARIDX expression, put into LINEAR expression if we have coefficient != 1 */
1346  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_VARIDX, exprvaridx[idx]) ); /*lint !e613*/
1347  if( coef != 1.0 )
1348  {
1349  SCIP_CALL( SCIPexprCreateLinear(SCIPblkmem(scip), expr, 1, expr, &coef, 0.0) );
1350  }
1351 
1352  return SCIP_OKAY;
1353  }
1354 
1355  if( strcmp(exprname, "number") == 0 )
1356  {
1357  const char* attrval;
1358  SCIP_Real val;
1359 
1360  attrval = xmlGetAttrval(node, "type");
1361  if( attrval != NULL && (strcmp(attrval, "real") != 0) )
1362  {
1363  SCIPerrorMessage("Type '%s' for <number> node in nonlinear expression not supported.\n", attrval);
1364  *doingfine = FALSE;
1365  return SCIP_OKAY;
1366  }
1367 
1368  attrval = xmlGetAttrval(node, "value");
1369  if( attrval != NULL )
1370  {
1371  val = strtod(attrval, (char**)&attrval);
1372  if( *attrval != '\0' || !SCIPisFinite(val) )
1373  {
1374  SCIPerrorMessage("Invalid value '%s' in \"value\" attribute of <number> node in nonlinear expression.\n", xmlGetAttrval(node, "value"));
1375  *doingfine = FALSE;
1376  return SCIP_OKAY;
1377  }
1378  }
1379  else
1380  {
1381  /* according to OSnL.xsd, the value attribute is optional
1382  * I guess the default is the empty string, which should correspond to 0.0
1383  */
1384  val = 0.0;
1385  }
1386 
1387  /* create CONST expression */
1388  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_CONST, val) );
1389 
1390  return SCIP_OKAY;
1391  }
1392 
1393  if( strcmp(exprname, "PI") == 0 )
1394  {
1395  /* create CONST expression with PI value*/
1397 
1398  return SCIP_OKAY;
1399  }
1400 
1401  if( strcmp(exprname, "E") == 0 )
1402  {
1403  /* create CONST expression with E value*/
1404  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_CONST, M_E) );
1405 
1406  return SCIP_OKAY;
1407  }
1408 
1409  /* single argument operands */
1410  if( strcmp(exprname, "negate") == 0 ||
1411  strcmp(exprname, "abs") == 0 ||
1412  strcmp(exprname, "squareRoot") == 0 ||
1413  strcmp(exprname, "sqrt") == 0 ||
1414  strcmp(exprname, "square") == 0 ||
1415  strcmp(exprname, "exp") == 0 ||
1416  strcmp(exprname, "ln") == 0 ||
1417  strcmp(exprname, "log10") == 0
1418  )
1419  {
1420  SCIP_EXPR* arg;
1421 
1422  /* check number of children */
1423  if( xmlFirstChild(node) == NULL || xmlNextSibl(xmlFirstChild(node)) != NULL )
1424  {
1425  SCIPerrorMessage("Expected exactly one child in <%s> node in nonlinear expression\n", exprname);
1426  *doingfine = FALSE;
1427  return SCIP_OKAY;
1428  }
1429 
1430  /* read child expression */
1431  SCIP_CALL( readExpression(scip, &arg, xmlFirstChild(node), exprvaridx, nexprvars, nvars, doingfine) );
1432  if( !*doingfine )
1433  return SCIP_OKAY;
1434 
1435  /* create SCIP expression according to expression name */
1436  if( strcmp(exprname, "negate") == 0 )
1437  {
1438  SCIP_Real minusone;
1439 
1440  minusone = -1.0;
1441  SCIP_CALL( SCIPexprCreateLinear(SCIPblkmem(scip), expr, 1, &arg, &minusone, 0.0) );
1442  }
1443  else if( strcmp(exprname, "abs") == 0 )
1444  {
1445  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_ABS, arg) );
1446  }
1447  else if( strcmp(exprname, "squareRoot") == 0 || strcmp(exprname, "sqrt") == 0 )
1448  {
1449  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_SQRT, arg) );
1450  }
1451  else if( strcmp(exprname, "square") == 0 )
1452  {
1453  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_SQUARE, arg) );
1454  }
1455  else if( strcmp(exprname, "exp") == 0 )
1456  {
1457  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_EXP, arg) );
1458  }
1459  else if( strcmp(exprname, "ln") == 0 )
1460  {
1461  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_LOG, arg) );
1462  }
1463  else /* if( strcmp(exprname, "log10") == 0 ) */
1464  {
1465  /* log10(expr) = ln(expr)*1/ln(10) */
1466  SCIP_EXPR* tmp;
1467 
1468  assert(strcmp(exprname, "log10") == 0);
1469 
1470  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &tmp, SCIP_EXPR_CONST, 1.0/log(10.0)) );
1471  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &arg, SCIP_EXPR_LOG, arg) );
1472  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_MUL, arg, tmp) );
1473  }
1474 
1475  return SCIP_OKAY;
1476  }
1477 
1478  /* two argument operands */
1479  if( strcmp(exprname, "plus") == 0 ||
1480  strcmp(exprname, "minus") == 0 ||
1481  strcmp(exprname, "times") == 0 ||
1482  strcmp(exprname, "divide") == 0 ||
1483  strcmp(exprname, "power") == 0 ||
1484  strcmp(exprname, "signpower") == 0 ||
1485  strcmp(exprname, "log") == 0
1486  )
1487  {
1488  SCIP_EXPR* arg1;
1489  SCIP_EXPR* arg2;
1490 
1491  /* check number of children */
1492  if( xmlFirstChild(node) == NULL ||
1493  xmlNextSibl(xmlFirstChild(node)) == NULL ||
1495  {
1496  SCIPerrorMessage("Expected exactly two children in <%s> node in nonlinear expression.\n", exprname);
1497  *doingfine = FALSE;
1498  return SCIP_OKAY;
1499  }
1500 
1501  /* read first child expression */
1502  SCIP_CALL( readExpression(scip, &arg1, xmlFirstChild(node), exprvaridx, nexprvars, nvars, doingfine) );
1503  if( !*doingfine )
1504  return SCIP_OKAY;
1505 
1506  /* read second child expression */
1507  SCIP_CALL( readExpression(scip, &arg2, xmlNextSibl(xmlFirstChild(node)), exprvaridx, nexprvars, nvars, doingfine) );
1508  if( !*doingfine )
1509  {
1510  SCIPexprFreeDeep(SCIPblkmem(scip), &arg1);
1511  return SCIP_OKAY;
1512  }
1513 
1514  if( strcmp(exprname, "plus") == 0 )
1515  {
1516  SCIP_CALL( SCIPexprAdd(SCIPblkmem(scip), expr, 1.0, arg1, 1.0, arg2, 0.0) );
1517  /* SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_PLUS, arg1, arg2) ); */
1518  }
1519  else if( strcmp(exprname, "minus") == 0 )
1520  {
1521  SCIP_CALL( SCIPexprAdd(SCIPblkmem(scip), expr, 1.0, arg1, -1.0, arg2, 0.0) );
1522  /* SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_MINUS, arg1, arg2) ); */
1523  }
1524  else if( strcmp(exprname, "times") == 0 )
1525  {
1526  if( SCIPexprGetOperator(arg1) == SCIP_EXPR_CONST )
1527  {
1528  SCIP_CALL( SCIPexprMulConstant(SCIPblkmem(scip), expr, arg2, SCIPexprGetOpReal(arg1)) );
1529  SCIPexprFreeDeep(SCIPblkmem(scip), &arg1);
1530  }
1531  else if( SCIPexprGetOperator(arg2) == SCIP_EXPR_CONST )
1532  {
1533  SCIP_CALL( SCIPexprMulConstant(SCIPblkmem(scip), expr, arg1, SCIPexprGetOpReal(arg2)) );
1534  SCIPexprFreeDeep(SCIPblkmem(scip), &arg2);
1535  }
1536  else
1537  {
1538  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_MUL, arg1, arg2) );
1539  }
1540  }
1541  else if( strcmp(exprname, "divide") == 0 )
1542  {
1543  if( SCIPexprGetOperator(arg2) == SCIP_EXPR_CONST )
1544  {
1545  assert(SCIPexprGetOpReal(arg2) != 0.0);
1546  SCIP_CALL( SCIPexprMulConstant(SCIPblkmem(scip), expr, arg1, 1.0/SCIPexprGetOpReal(arg2)) );
1547  SCIPexprFreeDeep(SCIPblkmem(scip), &arg2);
1548  }
1549  else
1550  {
1551  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_DIV, arg1, arg2) );
1552  }
1553  }
1554  else if( strcmp(exprname, "power") == 0 )
1555  {
1556  if( SCIPexprGetOperator(arg2) == SCIP_EXPR_CONST )
1557  {
1558  /* expr^number is intpower or realpower */
1559  if( SCIPisIntegral(scip, SCIPexprGetOpReal(arg2)) )
1560  {
1561  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_INTPOWER, arg1, (int)SCIPround(scip, SCIPexprGetOpReal(arg2))) );
1562  }
1563  else
1564  {
1566  }
1567  SCIPexprFreeDeep(SCIPblkmem(scip), &arg2);
1568  }
1569  else if( SCIPexprGetOperator(arg1) == SCIP_EXPR_CONST )
1570  {
1571  /* number^arg2 is exp(arg2 * ln(number)) */
1572  if( SCIPexprGetOpReal(arg1) < 0.0 )
1573  {
1574  SCIPerrorMessage("Negative base in <power> node with nonconstant exponent not allowed in nonlinear expression.\n");
1575  SCIPexprFreeDeep(SCIPblkmem(scip), &arg1);
1576  SCIPexprFreeDeep(SCIPblkmem(scip), &arg2);
1577  *doingfine = FALSE;
1578  return SCIP_OKAY;
1579  }
1580  else
1581  {
1582  SCIP_EXPR* tmp;
1583 
1585  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &tmp, SCIP_EXPR_MUL, tmp, arg2) );
1586  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_EXP, tmp) );
1587  SCIPexprFreeDeep(SCIPblkmem(scip), &arg1);
1588  }
1589  }
1590  else
1591  {
1592  /* arg1^arg2 is exp(arg2 * ln(arg1)) */
1593  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &arg1, SCIP_EXPR_LOG, arg1) );
1594  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &arg2, SCIP_EXPR_MUL, arg1, arg2) );
1595  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_EXP, arg2) );
1596  }
1597  }
1598  else if( strcmp(exprname, "signpower") == 0 )
1599  {
1600  /* signpower(expr,number) with number > 1 is the only one we can handle */
1601  if( SCIPexprGetOperator(arg2) != SCIP_EXPR_CONST )
1602  {
1603  SCIPerrorMessage("Signpower only supported for constant exponents, but got %s.\n", SCIPexpropGetName(SCIPexprGetOperator(arg2)));
1604  SCIPexprFreeDeep(SCIPblkmem(scip), &arg1);
1605  SCIPexprFreeDeep(SCIPblkmem(scip), &arg2);
1606  *doingfine = FALSE;
1607  return SCIP_OKAY;
1608  }
1609  if( SCIPexprGetOpReal(arg2) <= 1.0 )
1610  {
1611  SCIPerrorMessage("Signpower only supported for exponents > 1, but got %g.\n", SCIPexprGetOpReal(arg2));
1612  SCIPexprFreeDeep(SCIPblkmem(scip), &arg1);
1613  SCIPexprFreeDeep(SCIPblkmem(scip), &arg2);
1614  *doingfine = FALSE;
1615  return SCIP_OKAY;
1616  }
1617 
1619  SCIPexprFreeDeep(SCIPblkmem(scip), &arg2);
1620  }
1621  else if( strcmp(exprname, "log") == 0 )
1622  {
1623  /* logarithm of arg2 w.r.t. base arg1 = ln(arg2) / ln(arg1) */
1624  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &arg1, SCIP_EXPR_LOG, arg1) );
1625  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &arg2, SCIP_EXPR_LOG, arg2) );
1626  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_DIV, arg2, arg1) );
1627  }
1628  else if( strcmp(exprname, "min") == 0 )
1629  {
1630  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_MIN, arg1, arg2) );
1631  }
1632  else /* if( strcmp(exprname, "max") == 0 ) */
1633  {
1634  assert(strcmp(exprname, "max") == 0);
1635 
1636  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_MAX, arg1, arg2) );
1637  }
1638 
1639  return SCIP_OKAY;
1640  }
1641 
1642  /* arbitrary argument operands */
1643  if( strcmp(exprname, "sum") == 0 || strcmp(exprname, "product") == 0 )
1644  {
1645  const XML_NODE* argnode;
1646  SCIP_EXPR** args;
1647  int nargs;
1648  int argssize;
1649 
1650  /* a sum or product w.r.t. 0 arguments is constant */
1651  if( xmlFirstChild(node) == NULL )
1652  {
1653  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_CONST, (strcmp(exprname, "sum") == 0) ? 0.0 : 1.0) );
1654 
1655  return SCIP_OKAY;
1656  }
1657 
1658  /* read all child expressions */
1659  argssize = 5;
1660  SCIP_CALL( SCIPallocBufferArray(scip, &args, argssize) );
1661 
1662  nargs = 0;
1663  for( argnode = xmlFirstChild(node); argnode != NULL; argnode = xmlNextSibl(argnode), ++nargs )
1664  {
1665  if( nargs >= argssize )
1666  {
1667  argssize = SCIPcalcMemGrowSize(scip, nargs + 1);
1668  SCIP_CALL( SCIPreallocBufferArray(scip, &args, argssize) );
1669  }
1670  assert(nargs < argssize);
1671 
1672  SCIP_CALL( readExpression(scip, &args[nargs], argnode, exprvaridx, nexprvars, nvars, doingfine) );
1673  if( !*doingfine )
1674  {
1675  assert(args[nargs] == NULL);
1676  break;
1677  }
1678  }
1679 
1680  if( *doingfine )
1681  {
1682  switch( nargs )
1683  {
1684  case 0:
1685  {
1686  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_CONST, (strcmp(exprname, "sum") == 0) ? 0.0 : 1.0) );
1687  break;
1688  }
1689  case 1:
1690  {
1691  *expr = args[0];
1692  break;
1693  }
1694  case 2:
1695  {
1696  if( strcmp(exprname, "sum") == 0 )
1697  {
1698  SCIP_CALL( SCIPexprAdd(SCIPblkmem(scip), expr, 1.0, args[0], 1.0, args[1], 0.0) );
1699  }
1700  else
1701  {
1702  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, SCIP_EXPR_MUL, args[0], args[1]) );
1703  }
1704  break;
1705  }
1706  default:
1707  {
1708  /* create sum or product expression */
1709  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, (strcmp(exprname, "sum") == 0) ? SCIP_EXPR_SUM : SCIP_EXPR_PRODUCT, nargs, args) );
1710  break;
1711  }
1712  }
1713  }
1714  else
1715  {
1716  /* cleanup if parsing error */
1717  for( ; nargs > 0; --nargs )
1718  SCIPexprFreeDeep(SCIPblkmem(scip), &args[nargs-1]);
1719  }
1720 
1721  SCIPfreeBufferArray(scip, &args);
1722 
1723  return SCIP_OKAY;
1724  }
1725 
1726  if( strcmp(exprname, "min") == 0 || strcmp(exprname, "max") == 0 )
1727  {
1728  const XML_NODE* argnode;
1729  SCIP_EXPROP exprop;
1730  SCIP_EXPR* arg2;
1731 
1732  /* check that we have children */
1733  if( xmlFirstChild(node) == NULL )
1734  {
1735  SCIPerrorMessage("Expected at least one child in <%s> node of nonlinear expression.\n", exprname);
1736  *doingfine = FALSE;
1737  return SCIP_OKAY;
1738  }
1739 
1740  /* read expression corresponding to first child and store in expr */
1741  argnode = xmlFirstChild(node);
1742  SCIP_CALL( readExpression(scip, expr, argnode, exprvaridx, nexprvars, nvars, doingfine) );
1743  if( !*doingfine )
1744  {
1745  assert(*expr == NULL);
1746  return SCIP_OKAY;
1747  }
1748  arg2 = NULL;
1749 
1750  exprop = (strcmp(exprname, "min") == 0) ? SCIP_EXPR_MIN : SCIP_EXPR_MAX;
1751 
1752  /* read expressions corresponding to other children in arg and store exprop(expr, arg) in expr */
1753  for( argnode = xmlNextSibl(argnode); argnode != NULL; argnode = xmlNextSibl(argnode) )
1754  {
1755  assert(arg2 == NULL);
1756  SCIP_CALL( readExpression(scip, &arg2, argnode, exprvaridx, nexprvars, nvars, doingfine) );
1757  if( !*doingfine )
1758  {
1759  assert(arg2 == NULL);
1760  break;
1761  }
1762 
1763  assert(*expr != NULL);
1764  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), expr, exprop, *expr, arg2) );
1765  arg2 = NULL;
1766  }
1767 
1768  if( !*doingfine )
1769  {
1770  /* cleanup if failure */
1771  SCIPexprFreeDeep(SCIPblkmem(scip), expr);
1772  }
1773  assert(arg2 == NULL);
1774 
1775  return SCIP_OKAY;
1776  }
1777 
1778  if( strcmp(exprname, "quadratic") == 0 )
1779  {
1780  const char* attrval;
1781  const XML_NODE* qterm;
1782  SCIP_QUADELEM* quadelems;
1783  int nquadelems;
1784  int quadelemssize;
1785  int* quadvarsidxs;
1786  int nquadvars;
1787  int i;
1788 
1789  quadelemssize = 5;
1790  SCIP_CALL( SCIPallocBufferArray(scip, &quadelems, quadelemssize) );
1791  nquadelems = 0;
1792 
1793  SCIP_CALL( SCIPallocBufferArray(scip, &quadvarsidxs, nvars) );
1794  for( i = 0; i < nvars; ++i )
1795  quadvarsidxs[i] = -1;
1796  nquadvars = 0;
1797 
1798  /* read quadratic terms */
1799  for( qterm = xmlFirstChild(node); qterm != NULL; qterm = xmlNextSibl(qterm), ++nquadelems )
1800  {
1801  /* check for qpTerm node */
1802  if( strcmp(xmlGetName(qterm), "qpTerm") != 0 )
1803  {
1804  SCIPerrorMessage("Unexpected <%s> node under <quadratic> node in nonlinear expression, expected <qpTerm>.\n", xmlGetName(qterm));
1805  *doingfine = FALSE;
1806  break;
1807  }
1808 
1809  if( nquadelems >= quadelemssize )
1810  {
1811  quadelemssize = SCIPcalcMemGrowSize(scip, nquadelems + 1);
1812  SCIP_CALL( SCIPreallocBufferArray(scip, &quadelems, quadelemssize) );
1813  }
1814  assert(quadelemssize > nquadelems);
1815 
1816  /* get index of first variable */
1817  attrval = xmlGetAttrval(qterm, "idxOne");
1818  if( attrval == NULL )
1819  {
1820  SCIPerrorMessage("Missing \"idxOne\" attribute in %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", nquadelems);
1821  *doingfine = FALSE;
1822  break;
1823  }
1824 
1825  quadelems[nquadelems].idx1 = (int)strtol(attrval, (char**)&attrval, 10);
1826  if( *attrval != '\0' || quadelems[nquadelems].idx1 < 0 || quadelems[nquadelems].idx1 >= nvars )
1827  {
1828  SCIPerrorMessage("Invalid value '%s' for \"idxOne\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "idxOne"), nquadelems);
1829  *doingfine = FALSE;
1830  break;
1831  }
1832 
1833  /* get index of second variable */
1834  attrval = xmlGetAttrval(qterm, "idxTwo");
1835  if( attrval == NULL )
1836  {
1837  SCIPerrorMessage("Missing \"idxTwo\" attribute in %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", nquadelems);
1838  *doingfine = FALSE;
1839  break;
1840  }
1841 
1842  quadelems[nquadelems].idx2 = (int)strtol(attrval, (char**)&attrval, 10);
1843  if( *attrval != '\0' || quadelems[nquadelems].idx2 < 0 || quadelems[nquadelems].idx2 >= nvars )
1844  {
1845  SCIPerrorMessage("Invalid value '%s' for \"idxTwo\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "idxTwo"), nquadelems);
1846  *doingfine = FALSE;
1847  break;
1848  }
1849 
1850  /* get coefficient */
1851  attrval = xmlGetAttrval(qterm, "coef");
1852  if( attrval != NULL )
1853  {
1854  quadelems[nquadelems].coef = strtod(attrval, (char**)&attrval);
1855  if( *attrval != '\0' || (quadelems[nquadelems].coef != quadelems[nquadelems].coef) ) /*lint !e777*/
1856  {
1857  SCIPerrorMessage("Invalid value '%s' for \"coef\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "coef"), nquadelems);
1858  *doingfine = FALSE;
1859  break;
1860  }
1861  }
1862  else
1863  {
1864  quadelems[nquadelems].coef = 1.0;
1865  }
1866 
1867  /* get index for first variable in quadratic element */
1868  if( quadvarsidxs[quadelems[nquadelems].idx1] < 0 )
1869  {
1870  quadvarsidxs[quadelems[nquadelems].idx1] = nquadvars;
1871  quadelems[nquadelems].idx1 = nquadvars;
1872 
1873  ++nquadvars;
1874  }
1875  else
1876  {
1877  quadelems[nquadelems].idx1 = quadvarsidxs[quadelems[nquadelems].idx1];
1878  }
1879 
1880  /* get index for second variable in quadratic element */
1881  if( quadvarsidxs[quadelems[nquadelems].idx2] < 0 )
1882  {
1883  quadvarsidxs[quadelems[nquadelems].idx2] = nquadvars;
1884  quadelems[nquadelems].idx2 = nquadvars;
1885 
1886  ++nquadvars;
1887  }
1888  else
1889  {
1890  quadelems[nquadelems].idx2 = quadvarsidxs[quadelems[nquadelems].idx2];
1891  }
1892 
1893  /* swap indices if in wrong order */
1894  if( quadelems[nquadelems].idx1 > quadelems[nquadelems].idx2 )
1895  {
1896  int tmp;
1897 
1898  tmp = quadelems[nquadelems].idx1;
1899  quadelems[nquadelems].idx1 = quadelems[nquadelems].idx2;
1900  quadelems[nquadelems].idx2 = tmp;
1901  }
1902  }
1903 
1904  if( *doingfine )
1905  {
1906  SCIP_EXPR** children;
1907 
1908  /* setup array with children expressions corresponding to variables */
1909  SCIP_CALL( SCIPallocBufferArray(scip, &children, nquadvars) );
1910  for( i = 0; i < nvars; ++i )
1911  {
1912  if( quadvarsidxs[i] == -1 )
1913  continue;
1914 
1915  /* assign new index to variable, if we see it the first time in this exprtree */
1916  if( exprvaridx[i] == -1 ) /*lint !e613*/
1917  {
1918  exprvaridx[i] = *nexprvars; /*lint !e613*/
1919  ++*nexprvars;
1920  }
1921 
1922  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &children[quadvarsidxs[i]], SCIP_EXPR_VARIDX, exprvaridx[i]) ); /*lint !e613*/
1923  }
1924 
1925  /* create quadratic expression */
1926  SCIP_CALL( SCIPexprCreateQuadratic(SCIPblkmem(scip), expr, nquadvars, children, 0.0, NULL, nquadelems, quadelems) );
1927 
1928  SCIPfreeBufferArray(scip, &children);
1929  }
1930 
1931  SCIPfreeBufferArray(scip, &quadelems);
1932  SCIPfreeBufferArray(scip, &quadvarsidxs);
1933  }
1934 
1935  SCIPerrorMessage("Expression operand <%s> in nonlinear expression not supported by SCIP so far.\n", exprname);
1936  *doingfine = FALSE;
1937 
1938  return SCIP_OKAY;
1939 }
1940 
1941 
1942 /** read nonlinear expressions of constraints and objective */
1943 static
1945  SCIP* scip, /**< SCIP data structure */
1946  const XML_NODE* datanode, /**< XML root node for instance data */
1947  SCIP_VAR** vars, /**< variables in order of OSiL indices */
1948  int nvars, /**< number of variables */
1949  SCIP_CONS** conss, /**< constraints in order of OSiL indices */
1950  CONSTYPE* constypes, /**< type of constraints (assumed to be LINEAR) */
1951  int nconss, /**< number of constraints */
1952  SCIP_CONS** objcons, /**< buffer to store constraint for nonlinear part of objective function, or to add to if already existing */
1953  CONSTYPE* objconstype, /**< buffer to store type of objective constraint, if created (should be QUADRATIC) */
1954  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
1955  )
1956 {
1957  const XML_NODE* nlexprs;
1958  const XML_NODE* nlexpr;
1959  const char* attrval;
1960  SCIP_EXPRTREE* exprtree;
1961  SCIP_EXPR* expr;
1962  SCIP_VAR** exprvars;
1963  int* exprvaridx;
1964  SCIP_RETCODE retcode;
1965  int nexprvars;
1966  int nnlexprs;
1967  int count;
1968  int considx;
1969  int i;
1970 
1971  assert(scip != NULL);
1972  assert(datanode != NULL);
1973  assert(vars != NULL || nvars == 0);
1974  assert(conss != NULL || nconss == 0);
1975  assert(constypes != NULL || nconss == 0);
1976  assert(objcons != NULL);
1977  assert(doingfine != NULL);
1978 
1979  retcode = SCIP_OKAY;
1980 
1981  nlexprs = xmlFindNodeMaxdepth(datanode, "nonlinearExpressions", 0, 1);
1982 
1983  if( nlexprs == NULL )
1984  return SCIP_OKAY;
1985 
1986  /* get number of nonlinear expressions */
1987  attrval = xmlGetAttrval(nlexprs, "numberOfNonlinearExpressions");
1988  if( attrval == NULL )
1989  {
1990  SCIPerrorMessage("Attribute \"numberOfNonlinearExpressions\" in <nonlinearExpressions> node not found.\n");
1991  *doingfine = FALSE;
1992  return SCIP_OKAY;
1993  }
1994 
1995  nnlexprs = (int)strtol(attrval, (char**)&attrval, 10);
1996  if( *attrval != '\0' || nnlexprs < 0 )
1997  {
1998  SCIPerrorMessage("Invalid value '%s' for \"numberOfNonlinearExpressions\" attribute in <nonlinearExpressions>.\n", xmlGetAttrval(nlexprs, "numberOfNonlinearExpressions"));
1999  *doingfine = FALSE;
2000  return SCIP_OKAY;
2001  }
2002  assert(nnlexprs >= 0);
2003 
2004  /* buffer array to store index of variable in expression graph, or -1 if not present */
2005  SCIP_CALL( SCIPallocBufferArray(scip, &exprvaridx, nvars) );
2006  SCIP_CALL( SCIPallocBufferArray(scip, &exprvars, nvars) );
2007 
2008  /* read nonlinear expressions and store in constraints */
2009  count = 0;
2010  for( nlexpr = xmlFirstChild(nlexprs); nlexpr != NULL; nlexpr = xmlNextSibl(nlexpr), ++count )
2011  {
2012  if( strcmp(xmlGetName(nlexpr), "nl") != 0 )
2013  {
2014  SCIPerrorMessage("Expected <nl> node under <nonlinearExpressions> node, but got '%s'.\n", xmlGetName(nlexpr));
2015  *doingfine = FALSE;
2016  break;
2017  }
2018  if( count >= nnlexprs )
2019  {
2020  SCIPerrorMessage("Too many nonlinear expressions under <nonlinearExpressions> node, expected %d many, but got at least %d.\n", nnlexprs, count + 1);
2021  *doingfine = FALSE;
2022  break;
2023  }
2024 
2025  /* treat empty expression as 0.0 and continue */
2026  if( xmlFirstChild(nlexprs) == NULL )
2027  continue;
2028 
2029  /* get constraint index, or -1 for objective */
2030  attrval = xmlGetAttrval(nlexpr, "idx");
2031  if( attrval == NULL )
2032  {
2033  SCIPerrorMessage("Missing \"idx\" attribute in %d'th <nl> node under <nonlinearExpressions> node.\n", count);
2034  *doingfine = FALSE;
2035  break;
2036  }
2037 
2038  considx = (int)strtol(attrval, (char**)&attrval, 10);
2039  if( *attrval != '\0' || considx < -1 || considx >= nconss )
2040  {
2041  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of %d'th <nl> node under <nonlinearExpressions> node.\n", xmlGetAttrval(nlexpr, "idx"), count);
2042  *doingfine = FALSE;
2043  break;
2044  }
2045 
2046  expr = NULL;
2047  nexprvars = 0;
2048  for( i = 0; i < nvars; ++i )
2049  exprvaridx[i] = -1;
2050 
2051  /* turn OSiL expression into SCIP expression and assign indices to variables */
2052  SCIP_CALL( readExpression(scip, &expr, xmlFirstChild(nlexpr), exprvaridx, &nexprvars, nvars, doingfine) );
2053  if( !*doingfine )
2054  {
2055  assert(expr == NULL);
2056  break;
2057  }
2058 
2059  /* assemble array with SCIP_VAR*'s */
2060  for( i = 0; i < nvars; ++i )
2061  {
2062  assert(exprvaridx[i] < nexprvars );
2063 
2064  if( exprvaridx[i] >= 0 )
2065  exprvars[exprvaridx[i]] = vars[i]; /*lint !e613*/
2066  }
2067 
2068  /* create expression tree */
2069  SCIP_CALL( SCIPexprtreeCreate(SCIPblkmem(scip), &exprtree, expr, nexprvars, 0, NULL) );
2070  SCIP_CALL( SCIPexprtreeSetVars(exprtree, nexprvars, exprvars) );
2071 
2072  /* add expression tree to objective or constraint */
2073  if( considx == -1 && *objcons == NULL )
2074  {
2075  /* create constraint to hold nonlinear part of objective; note that
2076  * reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model constraints and variables,
2077  * not to an auxiliary objective constraint (otherwise it can happen that an auxiliary objective variable is
2078  * loose with infinite best bound, triggering the problem that an LP that is unbounded because of loose
2079  * variables with infinite best bound cannot be solved)
2080  */
2081 
2082  SCIP_VAR* objvar;
2083  SCIP_Real minusone;
2084  SCIP_Real one;
2085 
2086  SCIP_CALL( SCIPcreateVar(scip, &objvar, "nlobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
2088  SCIP_CALL( SCIPaddVar(scip, objvar) );
2089 
2090  minusone = -1.0;
2091  one = 1.0;
2092  SCIP_CALL_TERMINATE( retcode, SCIPcreateConsNonlinear(scip, objcons, "nlobj", 1, &objvar, &minusone, 1, &exprtree, &one,
2093  SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE ? -SCIPinfinity(scip) : 0.0,
2094  SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE ? SCIPinfinity(scip) : 0.0,
2095  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE), TERMINATE );
2096  *objconstype = NONLINEAR;
2097 
2098  SCIP_CALL( SCIPreleaseVar(scip, &objvar) );
2099  }
2100  else
2101  {
2102  SCIP_CONS** cons;
2103  SCIP_CONS* oldcons;
2104  CONSTYPE* constype;
2105 
2106  if( considx == -1 )
2107  {
2108  cons = objcons;
2109  constype = objconstype;
2110  }
2111  else
2112  {
2113  cons = &conss[considx]; /*lint !e613*/
2114  constype = &constypes[considx]; /*lint !e613*/
2115  }
2116  oldcons = *cons;
2117 
2118  /* replace cons by nonlinear constraint or add to already existing nonlinear constraint */
2119  switch( *constype )
2120  {
2121  case LINEAR:
2122  {
2123  SCIP_Real one;
2124 
2125  one = 1.0;
2126  /* coverity[negative_returns] */
2127  SCIP_CALL_TERMINATE( retcode, SCIPcreateConsNonlinear(scip, cons, SCIPconsGetName(*cons),
2128  SCIPgetNVarsLinear(scip, *cons), SCIPgetVarsLinear(scip, *cons), SCIPgetValsLinear(scip, *cons),
2129  1, &exprtree, &one,
2130  SCIPgetLhsLinear(scip, *cons), SCIPgetRhsLinear(scip, *cons),
2134  SCIPconsIsStickingAtNode(*cons)), TERMINATE );
2135 
2136  SCIP_CALL( SCIPreleaseCons(scip, &oldcons) );
2137 
2138  break;
2139  }
2140 
2141  case QUADRATIC:
2142  {
2143  SCIP_EXPRTREE* exprtrees[2];
2144  SCIP_Real exprcoefs[2];
2145 
2146  SCIP_EXPR* quadexpr;
2147  SCIP_QUADELEM* quadelems;
2148  SCIP_Real* lincoefs;
2149  SCIP_EXPR** children;
2150  SCIP_QUADVARTERM* quadvarterms;
2151  SCIP_BILINTERM* bilinterms;
2152  int nquadelems;
2153  int nquadvars;
2154  int nbilin;
2155  int j;
2156 
2157  exprtrees[0] = exprtree;
2158  exprcoefs[0] = 1.0;
2159 
2160  /* turn quadratic part into expression tree */
2161  SCIP_CALL( SCIPsortQuadVarTermsQuadratic(scip, *cons) );
2162 
2163  quadvarterms = SCIPgetQuadVarTermsQuadratic(scip, *cons);
2164  nquadvars = SCIPgetNQuadVarTermsQuadratic(scip, *cons);
2165  bilinterms = SCIPgetBilinTermsQuadratic(scip, *cons);
2166  nbilin = SCIPgetNBilinTermsQuadratic(scip, *cons);
2167 
2168  SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nquadvars) );
2169  SCIP_CALL( SCIPallocBufferArray(scip, &children, nquadvars) );
2170  SCIP_CALL( SCIPallocBufferArray(scip, &quadelems, nbilin + nquadvars) );
2171  nquadelems = 0;
2172 
2173  for( i = 0; i < nquadvars; ++i )
2174  {
2175  lincoefs[i] = quadvarterms[i].lincoef;
2176  exprvars[i] = quadvarterms[i].var;
2177 
2178  if( quadvarterms[i].sqrcoef != 0.0 )
2179  {
2180  quadelems[nquadelems].idx1 = i;
2181  quadelems[nquadelems].idx2 = i;
2182  quadelems[nquadelems].coef = quadvarterms[i].sqrcoef;
2183  ++nquadelems;
2184  }
2185 
2186  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &children[i], SCIP_EXPR_VARIDX, i) );
2187 
2188  for( j = 0; j < quadvarterms[i].nadjbilin; ++j )
2189  {
2190  if( bilinterms[quadvarterms[i].adjbilin[j]].var1 == quadvarterms[i].var )
2191  {
2192  int otheridx;
2193 
2194  assert(bilinterms[quadvarterms[i].adjbilin[j]].var2 != quadvarterms[i].var);
2195 
2196  SCIP_CALL( SCIPfindQuadVarTermQuadratic(scip, *cons, bilinterms[quadvarterms[i].adjbilin[j]].var2, &otheridx) );
2197  assert(otheridx >= 0);
2198  assert(otheridx < nquadvars);
2199 
2200  quadelems[nquadelems].idx1 = MIN(i, otheridx);
2201  quadelems[nquadelems].idx2 = MAX(i, otheridx);
2202  quadelems[nquadelems].coef = bilinterms[quadvarterms[i].adjbilin[j]].coef;
2203  ++nquadelems;
2204  }
2205  }
2206  }
2207 
2208  SCIP_CALL( SCIPexprCreateQuadratic(SCIPblkmem(scip), &quadexpr, nquadvars, children, 0.0, lincoefs, nquadelems, quadelems) );
2209  SCIP_CALL( SCIPexprtreeCreate(SCIPblkmem(scip), &exprtrees[1], quadexpr, nquadvars, 0, NULL) );
2210  SCIP_CALL( SCIPexprtreeSetVars(exprtrees[1], nquadvars, exprvars) );
2211  exprcoefs[1] = 1.0;
2212 
2213  SCIPfreeBufferArray(scip, &lincoefs);
2214  SCIPfreeBufferArray(scip, &children);
2215  SCIPfreeBufferArray(scip, &quadelems);
2216 
2217  SCIP_CALL_TERMINATE( retcode, SCIPcreateConsNonlinear(scip, cons, SCIPconsGetName(*cons),
2218  SCIPgetNLinearVarsNonlinear(scip, *cons), SCIPgetLinearVarsNonlinear(scip, *cons),
2219  SCIPgetLinearCoefsNonlinear(scip, *cons), 2, exprtrees, exprcoefs,
2220  SCIPgetLhsNonlinear(scip, *cons), SCIPgetRhsNonlinear(scip, *cons),
2224  SCIPconsIsStickingAtNode(*cons)), TERMINATE );
2225 
2226  SCIP_CALL( SCIPreleaseCons(scip, &oldcons) );
2227 
2228  break;
2229  }
2230 
2231  case NONLINEAR:
2232  {
2233  SCIP_Real one;
2234 
2235  one = 1.0;
2236  SCIP_CALL( SCIPaddExprtreesNonlinear(scip, *cons, 1, &exprtree, &one) );
2237  break;
2238  }
2239  }
2240 
2241  *constype = NONLINEAR;
2242  }
2243 
2244  TERMINATE:
2245  SCIP_CALL( SCIPexprtreeFree(&exprtree) );
2246 
2247  if( retcode != SCIP_OKAY )
2248  break;
2249  }
2250 
2251  SCIPfreeBufferArray(scip, &exprvars);
2252  SCIPfreeBufferArray(scip, &exprvaridx);
2253 
2254  SCIP_CALL( retcode );
2255 
2256  return SCIP_OKAY;
2257 }
2258 
2259 
2260 /** read sos1 and sos2 constraints
2261  *
2262  * sos constraints are expected to be given as a node of <instanceData> in the following way:
2263  * @code
2264  * <specialOrderedSets numberOfSpecialOrderedSets="1">
2265  * <sos numberOfVar="2" order="2">
2266  * <var idx="1"></var>
2267  * <var idx="2"></var>
2268  * </sos>
2269  * </specialOrderedSets>
2270  * @endcode
2271  * Weights are determined by the order in which the variables are given
2272  *
2273  */
2274 static
2276  SCIP* scip, /**< SCIP data structure */
2277  const XML_NODE* datanode, /**< XML root node for instance data */
2278  SCIP_VAR** vars, /**< variables in order of OSiL indices */
2279  int nvars, /**< number of variables */
2280  SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
2281  SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
2282  SCIP_Bool dynamicrows, /**< should rows be added and removed dynamically to the LP? */
2283  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
2284  )
2285 {
2286  const XML_NODE* soscons;
2287  const XML_NODE* sosvar;
2288  const char* attrval;
2289  int nsoscons;
2290  int nsosvars;
2291  int sosorder;
2292  int type;
2293  int count;
2294  int varcount;
2295  int idx;
2296  SCIP_Bool initial;
2297  SCIP_Bool separate;
2298  SCIP_Bool enforce;
2299  SCIP_Bool check;
2300  SCIP_Bool propagate;
2301  SCIP_Bool local;
2302  SCIP_Bool dynamic;
2303  SCIP_Bool removable;
2304  char name[SCIP_MAXSTRLEN];
2305 
2306  /* standard settings for SOS constraints: */
2307  initial = initialconss;
2308  separate = TRUE;
2309  enforce = TRUE;
2310  check = TRUE;
2311  propagate = TRUE;
2312  local = FALSE;
2313  dynamic = dynamicconss;
2314  removable = dynamicrows;
2315 
2316  soscons= xmlFindNodeMaxdepth(datanode, "specialOrderedSets", 0, 1);
2317 
2318  if( soscons== NULL )
2319  return SCIP_OKAY;
2320 
2321  /* get number of sos constraints */
2322  attrval = xmlGetAttrval(soscons, "numberOfSOS");
2323  if( attrval == NULL )
2324  {
2325  SCIPerrorMessage("Attribute \"numberOfSOS in <specialOrderedSets> node not found.\n");
2326  *doingfine = FALSE;
2327  return SCIP_OKAY;
2328  }
2329 
2330  nsoscons = (int)strtol(attrval, (char**)&attrval, 10);
2331  if( *attrval != '\0' || nsoscons < 0 )
2332  {
2333  SCIPerrorMessage("Invalid value '%s' for \"numberOfSOS\" attribute in <specialOrderedSets>.\n", xmlGetAttrval(soscons, "numberOfSOS"));
2334  *doingfine = FALSE;
2335  return SCIP_OKAY;
2336  }
2337  assert(nsoscons >= 0);
2338 
2339  /* read sos constraints and create corresponding constraint */
2340  count = 0;
2341  for( soscons = xmlFirstChild(soscons); soscons != NULL; soscons = xmlNextSibl(soscons), ++count )
2342  {
2343  SCIP_CONS* cons;
2344 
2345  /* Make sure we get a sos node and not more then announced*/
2346  if( strcmp(xmlGetName(soscons), "sos") != 0 )
2347  {
2348  SCIPerrorMessage("Expected <sos> node under <specialOrderedSet> node, but got '%s'.\n", xmlGetName(soscons));
2349  *doingfine = FALSE;
2350  break;
2351  }
2352 
2353  if( count >= nsoscons)
2354  {
2355  SCIPerrorMessage("Too many sos under <specialOrderedSets> node, expected %d many, but got at least %d.\n", nsoscons, count + 1);
2356  *doingfine = FALSE;
2357  break;
2358  }
2359 
2360  /* get number of variables in this sos constraint */
2361  attrval = xmlGetAttrval(soscons, "numberOfVar");
2362  if( attrval == NULL )
2363  {
2364  SCIPerrorMessage("Attribute \"numberOfVar in <sos> node not found.\n");
2365  *doingfine = FALSE;
2366  return SCIP_OKAY;
2367  }
2368 
2369  nsosvars = (int)strtol(attrval, (char**)&attrval, 10);
2370  if( *attrval != '\0' || nsosvars < 0 )
2371  {
2372  SCIPerrorMessage("Invalid value '%s' for \"numberOfVar\" attribute in <sos>.\n", xmlGetAttrval(soscons, "numberOfVar"));
2373  *doingfine = FALSE;
2374  return SCIP_OKAY;
2375  }
2376  assert(nsosvars >= 0);
2377 
2378  /* get order of this sos constraint */
2379  attrval = xmlGetAttrval(soscons, "type");
2380  if( attrval == NULL )
2381  {
2382  SCIPerrorMessage("Attribute \"order\" in <sos> node not found.\n");
2383  *doingfine = FALSE;
2384  return SCIP_OKAY;
2385  }
2386 
2387  sosorder = (int)strtol(attrval, (char**)&attrval, 10);
2388  if( *attrval != '\0' || sosorder < 0 || sosorder > 2 )
2389  {
2390  SCIPerrorMessage("Invalid/unsupported value '%s' for \"order\" attribute in <sos>.\n", xmlGetAttrval(soscons, "order"));
2391  *doingfine = FALSE;
2392  return SCIP_OKAY;
2393  }
2394  assert(sosorder == 1 || sosorder == 2);
2395  type = sosorder;
2396 
2397  /* set artificial name for sos constraint*/
2398  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "SOS%d_%d", type, count);
2399 
2400  /* Create sos constraint */
2401  switch( type )
2402  {
2403  case 1:
2404  SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2405  local, dynamic, removable, FALSE) );
2406  break;
2407  case 2:
2408  SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2409  local, dynamic, removable, FALSE) );
2410  break;
2411  default:
2412  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2413  SCIPABORT();
2414  return SCIP_INVALIDDATA; /*lint !e527*/
2415  }
2416 
2417  varcount = 0;
2418  for( sosvar = xmlFirstChild(soscons); sosvar!= NULL; sosvar = xmlNextSibl(sosvar), ++varcount )
2419  {
2420  /* get variable id*/
2421  attrval = xmlGetAttrval(sosvar, "idx");
2422  if( attrval == NULL )
2423  {
2424  SCIPerrorMessage("Attribute \"idx\" in <var> node below <specialOrderedSets> node not found.\n");
2425  *doingfine = FALSE;
2426  return SCIP_OKAY;
2427  }
2428 
2429  idx = (int)strtol(attrval, (char**)&attrval, 10);
2430  if( *attrval != '\0' || idx < 0 || idx > nvars - 1 )
2431  {
2432  SCIPerrorMessage("Invalid value '%s' for \"idx\" attribute in <var>.\n", xmlGetAttrval(sosvar, "idx"));
2433  *doingfine = FALSE;
2434  return SCIP_OKAY;
2435  }
2436  assert(idx >= 0);
2437 
2438  /* we now know that we have a variable/weight pair -> add variable*/
2439  switch( type )
2440  {
2441  case 1:
2442  SCIP_CALL( SCIPaddVarSOS1(scip, cons, vars[idx], (SCIP_Real) (nsosvars - varcount)) );
2443  break;
2444  case 2:
2445  SCIP_CALL( SCIPaddVarSOS2(scip, cons, vars[idx], (SCIP_Real) (nsosvars - varcount)) );
2446  break;
2447  /* coverity[dead_error_begin] */
2448  default:
2449  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2450  SCIPABORT();
2451  return SCIP_INVALIDDATA; /*lint !e527*/
2452  }
2453  } /* Close loop over variables in sos constraint */
2454 
2455  /* add the SOS constraint */
2456  SCIP_CALL( SCIPaddCons(scip, cons) );
2457  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2458  }
2459 
2460  return SCIP_OKAY;
2461 }
2462 
2463  /*
2464  * Callback methods of reader
2465  */
2466 
2467 
2468 /** copy method for reader plugins (called when SCIP copies plugins) */
2469 static
2470 SCIP_DECL_READERCOPY(readerCopyOsil)
2471 { /*lint --e{715}*/
2472  assert(scip != NULL);
2473 
2475 
2476  return SCIP_OKAY;
2477 }
2478 
2479 /** problem reading method of reader */
2480 static
2481 SCIP_DECL_READERREAD(readerReadOsil)
2482 { /*lint --e{715}*/
2483  const char* name;
2484  XML_NODE* start;
2485  const XML_NODE* header;
2486  const XML_NODE* data;
2487  SCIP_RETCODE retcode;
2488  SCIP_Bool doingfine;
2489  SCIP_Bool initialconss;
2490  SCIP_Bool dynamicconss;
2491  SCIP_Bool dynamiccols;
2492  SCIP_Bool dynamicrows;
2493  SCIP_VAR** vars;
2494  int nvars;
2495  SCIP_CONS** conss;
2496  CONSTYPE* constypes;
2497  int nconss;
2498  SCIP_CONS* objcons;
2499  CONSTYPE objconstype;
2500  int i;
2501 
2502  assert(scip != NULL);
2503  assert(reader != NULL);
2504  assert(result != NULL);
2505  assert(filename != NULL);
2506 
2507  *result = SCIP_DIDNOTRUN;
2508  retcode = SCIP_READERROR;
2509  doingfine = TRUE;
2510  vars = NULL;
2511  nvars = 0;
2512  conss = NULL;
2513  constypes = NULL;
2514  nconss = 0;
2515  objcons = NULL;
2516 
2517  /* read OSiL xml file */
2518  start = xmlProcess(filename);
2519 
2520  if( start == NULL )
2521  {
2522  SCIPerrorMessage("Some error occurred when parsing the OSiL XML file '%s'.\n", filename);
2523  goto CLEANUP;
2524  }
2525 
2526  SCIPdebug( xmlShowNode(start) );
2527 
2528  /* parse header to get problem name */
2529  name = filename;
2530  header = xmlFindNodeMaxdepth(start, "instanceHeader", 0, 2);
2531  if( header != NULL )
2532  {
2533  const XML_NODE* namenode;
2534 
2535  namenode = xmlFindNodeMaxdepth(header, "name", 0, 2);
2536 
2537  if( namenode != NULL && xmlFirstChild(namenode) != NULL )
2538  name = xmlGetData(xmlFirstChild(namenode));
2539  else
2540  {
2541  namenode = xmlFindNodeMaxdepth(header, "description", 0, 2);
2542 
2543  if( namenode != NULL && xmlFirstChild(namenode) != NULL )
2544  name = xmlGetData(xmlFirstChild(namenode));
2545  }
2546  }
2547 
2548  /* create SCIP problem */
2550 
2551  /* process instance data */
2552  data = xmlFindNodeMaxdepth(start, "instanceData", 0, 2);
2553  if( data == NULL )
2554  {
2555  SCIPerrorMessage("Node <instanceData> not found.\n");
2556  goto CLEANUP;
2557  }
2558 
2559  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &initialconss) );
2560  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &dynamicconss) );
2561  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
2562  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
2563 
2564  /* read variables */
2565  SCIP_CALL_TERMINATE( retcode, readVariables(scip, data, &vars, &nvars, initialconss, dynamicconss, dynamiccols, dynamicrows, &doingfine), CLEANUP );
2566  if( !doingfine )
2567  goto CLEANUP;
2568  assert(vars != NULL || nvars == 0);
2569 
2570  /* read objective sense, coefficient, and constant */
2571  SCIP_CALL_TERMINATE( retcode, readObjective(scip, data, vars, nvars, dynamiccols, &doingfine), CLEANUP );
2572  if( !doingfine )
2573  goto CLEANUP;
2574 
2575  /* read constraint data (names, constants, lhs/rhs) */
2576  SCIP_CALL_TERMINATE( retcode, readConstraints(scip, data, &conss, &constypes, &nconss, initialconss, dynamicconss, dynamicrows, &doingfine), CLEANUP );
2577  if( !doingfine )
2578  goto CLEANUP;
2579  assert(conss != NULL || nconss == 0);
2580 
2581  /* read linear coefficients matrix */
2582  SCIP_CALL_TERMINATE( retcode, readLinearCoefs(scip, data, vars, nvars, conss, constypes, nconss, &doingfine), CLEANUP );
2583  if( !doingfine )
2584  goto CLEANUP;
2585 
2586  /* read quadratic coefficients (turns linear constraints into quadratic ones, may create objcons) */
2587  SCIP_CALL_TERMINATE( retcode, readQuadraticCoefs(scip, data, vars, nvars, conss, constypes, nconss, &objcons, &objconstype, &doingfine), CLEANUP );
2588  if( !doingfine )
2589  goto CLEANUP;
2590 
2591  /* read nonlinear expressions (turns constraints into nonlinear ones, may create objcons) */
2592  SCIP_CALL_TERMINATE( retcode, readNonlinearExprs(scip, data, vars, nvars, conss, constypes, nconss, &objcons, &objconstype, &doingfine), CLEANUP );
2593  if( !doingfine )
2594  goto CLEANUP;
2595 
2596  /* add constraints to problem */
2597  for( i = 0; i < nconss; ++i )
2598  {
2599  assert(conss[i] != NULL); /*lint !e613*/
2600  SCIP_CALL( SCIPaddCons(scip, conss[i]) ); /*lint !e613*/
2601  }
2602  if( objcons != NULL )
2603  {
2604  SCIP_CALL( SCIPaddCons(scip, objcons) );
2605  }
2606 
2607  /* read sos2 constraints and add to problem*/
2608  SCIP_CALL_TERMINATE( retcode, readSOScons(scip, data, vars, nvars, initialconss, dynamicconss, dynamicrows, &doingfine), CLEANUP );
2609  if( !doingfine )
2610  goto CLEANUP;
2611 
2612  *result = SCIP_SUCCESS;
2613  retcode = SCIP_OKAY;
2614 
2615  CLEANUP:
2616  /* free xml data */
2617  if( start != NULL )
2618  xmlFreeNode(start);
2619 
2620  /* free constraints */
2621  for( i = 0; i < nconss; ++i )
2622  {
2623  SCIP_CALL( SCIPreleaseCons(scip, &conss[i]) ); /*lint !e613*/
2624  }
2625  SCIPfreeBufferArrayNull(scip, &constypes);
2626  SCIPfreeBufferArrayNull(scip, &conss);
2627 
2628  /* free variables */
2629  for( i = 0; i < nvars; ++i )
2630  {
2631  SCIP_CALL( SCIPreleaseVar(scip, &vars[i]) ); /*lint !e613*/
2632  }
2633  SCIPfreeBufferArrayNull(scip, &vars);
2634 
2635  if( objcons != NULL )
2636  {
2637  SCIP_CALL( SCIPreleaseCons(scip, &objcons) );
2638  }
2639 
2640  /* return read error retcode if something went wrong */
2641  if( !doingfine )
2642  return SCIP_READERROR;
2643 
2644  if( retcode == SCIP_PLUGINNOTFOUND )
2645  retcode = SCIP_READERROR;
2646 
2647  SCIP_CALL( retcode );
2648 
2649  return SCIP_OKAY;
2650 }
2651 
2652 /*
2653  * reader specific interface methods
2654  */
2655 
2656 /** includes the osil file reader in SCIP */
2658  SCIP* scip /**< SCIP data structure */
2659  )
2660 {
2661  SCIP_READER* reader;
2662 
2663  /* include osil reader */
2665 
2666  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyOsil) );
2667  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadOsil) );
2668 
2669  return SCIP_OKAY;
2670 }
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
void SCIPexprFreeDeep(BMS_BLKMEM *blkmem, SCIP_EXPR **expr)
Definition: expr.c:6187
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
static volatile int nterms
Definition: interrupt.c:38
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
public methods for SCIP parameter handling
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
#define READER_EXTENSION
Definition: reader_osil.c:53
static SCIP_RETCODE readNonlinearExprs(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, SCIP_CONS **conss, CONSTYPE *constypes, int nconss, SCIP_CONS **objcons, CONSTYPE *objconstype, SCIP_Bool *doingfine)
Definition: reader_osil.c:1944
#define READER_NAME
Definition: reader_osil.c:51
static SCIP_DECL_READERCOPY(readerCopyOsil)
Definition: reader_osil.c:2470
SCIP_RETCODE SCIPincludeReaderOsil(SCIP *scip)
Definition: reader_osil.c:2657
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8316
SCIP_BILINTERM * SCIPgetBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
public methods for memory management
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition: scip_mem.h:113
SCIP_EXPROP SCIPexprGetOperator(SCIP_EXPR *expr)
Definition: expr.c:5697
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8276
#define SCIP_MAXSTRLEN
Definition: def.h:279
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1240
const char * SCIPexpropGetName(SCIP_EXPROP op)
Definition: expr.c:3265
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:241
CONSTYPE
Definition: reader_osil.c:60
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:186
#define FALSE
Definition: def.h:73
SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos1.c:10376
SCIP_QUADVARTERM * SCIPgetQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:138
#define TRUE
Definition: def.h:72
#define SCIPdebug(x)
Definition: pub_message.h:84
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8246
SCIP_Real SCIPgetRhsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos2.c:2351
public methods for problem variables
XML_NODE * xmlProcess(const char *filename)
Definition: xmlparse.c:1076
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
OS instance language (OSiL) format file reader.
const XML_NODE * xmlFirstChild(const XML_NODE *node)
Definition: xmlparse.c:1460
const char * xmlGetData(const XML_NODE *node)
Definition: xmlparse.c:1500
SCIP_RETCODE SCIPexprtreeCreate(BMS_BLKMEM *blkmem, SCIP_EXPRTREE **tree, SCIP_EXPR *root, int nvars, int nparams, SCIP_Real *params)
Definition: expr.c:8773
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:123
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
public methods for SCIP variables
static SCIP_RETCODE readSOScons(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, SCIP_Bool initialconss, SCIP_Bool dynamicconss, SCIP_Bool dynamicrows, SCIP_Bool *doingfine)
Definition: reader_osil.c:2275
SCIP_RETCODE SCIPfindQuadVarTermQuadratic(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, int *pos)
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsortQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
public methods for numerical tolerances
public methods for expressions, expression trees, expression graphs, and related stuff ...
void xmlShowNode(const XML_NODE *root)
Definition: xmlparse.c:1300
SCIP_Real coef
Definition: type_expr.h:104
public methods for managing constraints
#define READER_DESC
Definition: reader_osil.c:52
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17017
static SCIP_DECL_READERREAD(readerReadOsil)
Definition: reader_osil.c:2481
SCIP_RETCODE SCIPexprCreateQuadratic(BMS_BLKMEM *blkmem, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real constant, SCIP_Real *lincoefs, int nquadelems, SCIP_QUADELEM *quadelems)
Definition: expr.c:6588
#define SCIPerrorMessage
Definition: pub_message.h:55
enum SCIP_ExprOp SCIP_EXPROP
Definition: type_expr.h:91
static SCIP_RETCODE readExpression(SCIP *scip, SCIP_EXPR **expr, const XML_NODE *node, int *exprvaridx, int *nexprvars, int nvars, SCIP_Bool *doingfine)
Definition: reader_osil.c:1273
struct XML_NODE_struct XML_NODE
Definition: xml.h:41
SCIP_RETCODE SCIPaddExprtreesNonlinear(SCIP *scip, SCIP_CONS *cons, int nexprtrees, SCIP_EXPRTREE **exprtrees, SCIP_Real *coefs)
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:124
const XML_NODE * xmlFindNodeMaxdepth(const XML_NODE *node, const char *name, int depth, int maxdepth)
Definition: xmlparse.c:1410
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:48
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
constraint handler for quadratic constraints
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip_prob.c:1223
SCIP_RETCODE SCIPcreateConsNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nexprtrees, SCIP_EXPRTREE **exprtrees, SCIP_Real *nonlincoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
#define SCIP_CALL(x)
Definition: def.h:370
SCIP_RETCODE SCIPexprMulConstant(BMS_BLKMEM *blkmem, SCIP_EXPR **expr, SCIP_EXPR *term, SCIP_Real factor)
Definition: expr.c:6408
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:10513
public methods for constraint handler plugins and constraints
public methods for NLP management
SCIP_RETCODE SCIPexprAdd(BMS_BLKMEM *blkmem, SCIP_EXPR **expr, SCIP_Real coef1, SCIP_EXPR *term1, SCIP_Real coef2, SCIP_EXPR *term2, SCIP_Real constant)
Definition: expr.c:6250
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8346
int SCIPgetNLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:111
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
SCIP_Real SCIPinfinity(SCIP *scip)
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:70
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2450
SCIP_RETCODE SCIPexprtreeSetVars(SCIP_EXPRTREE *tree, int nvars, SCIP_VAR **vars)
Definition: nlp.c:113
constraint handler for nonlinear constraints
static SCIP_RETCODE readLinearCoefs(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, SCIP_CONS **conss, CONSTYPE *constypes, int nconss, SCIP_Bool *doingfine)
Definition: reader_osil.c:670
#define MAX(x, y)
Definition: tclique_def.h:83
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:105
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPexprCreate(BMS_BLKMEM *blkmem, SCIP_EXPR **expr, SCIP_EXPROP op,...)
Definition: expr.c:5977
SCIP_RETCODE SCIPexprtreeFree(SCIP_EXPRTREE **tree)
Definition: expr.c:8854
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:100
SCIP_Real SCIPgetLhsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8256
SCIPInterval log(const SCIPInterval &x)
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
Definition: scip_prob.c:107
Constraint handler for linear constraints in their most general form, .
const char * xmlGetName(const XML_NODE *node)
Definition: xmlparse.c:1480
SCIP_Real * SCIPgetLinearCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1666
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8336
static SCIP_RETCODE readConstraints(SCIP *scip, const XML_NODE *datanode, SCIP_CONS ***conss, CONSTYPE **constypes, int *nconss, SCIP_Bool initialconss, SCIP_Bool dynamicconss, SCIP_Bool dynamicrows, SCIP_Bool *doingfine)
Definition: reader_osil.c:434
#define M_PI
Definition: pricer_rpa.c:88
static SCIP_RETCODE readObjective(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, SCIP_Bool dynamiccols, SCIP_Bool *doingfine)
Definition: reader_osil.c:288
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
static void readMultIncr(const XML_NODE *node, int *mult, int *incrint, SCIP_Real *incrreal, SCIP_Bool *doingfine)
Definition: reader_osil.c:604
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4507
SCIP_Real SCIPexprGetOpReal(SCIP_EXPR *expr)
Definition: expr.c:5738
const char * xmlGetAttrval(const XML_NODE *node, const char *name)
Definition: xmlparse.c:1328
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8266
int SCIPgetNBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
public methods for message output
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8077
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
static SCIP_RETCODE readQuadraticCoefs(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, SCIP_CONS **conss, CONSTYPE *constypes, int nconss, SCIP_CONS **objcons, CONSTYPE *objconstype, SCIP_Bool *doingfine)
Definition: reader_osil.c:1010
#define SCIP_Real
Definition: def.h:163
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:391
static SCIP_RETCODE readVariables(SCIP *scip, const XML_NODE *datanode, SCIP_VAR ***vars, int *nvars, SCIP_Bool initialconss, SCIP_Bool dynamicconss, SCIP_Bool dynamiccols, SCIP_Bool dynamicrows, SCIP_Bool *doingfine)
Definition: reader_osil.c:74
constraint handler for SOS type 1 constraints
#define SCIP_INVALID
Definition: def.h:183
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8356
#define SCIPisFinite(x)
Definition: pub_misc.h:1861
declarations for XML parsing
SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2764
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:60
constraint handler for SOS type 2 constraints
SCIP_RETCODE SCIPcreateConsQuadratic(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable)
void xmlFreeNode(XML_NODE *node)
Definition: xmlparse.c:1266
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
SCIP_RETCODE SCIPexprCreateLinear(BMS_BLKMEM *blkmem, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefs, SCIP_Real constant)
Definition: expr.c:6506
constraint handler for bound disjunction constraints
public methods for reader plugins
#define SCIPABORT()
Definition: def.h:342
public methods for global and local (sub)problems
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8296
const XML_NODE * xmlNextSibl(const XML_NODE *node)
Definition: xmlparse.c:1440
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8326
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
memory allocation routines