SCIP-SDP  2.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
objreader_sdpa.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programms based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2016 Discrete Optimization, TU Darmstadt */
9 /* */
10 /* */
11 /* This program is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
24 /* */
25 /* */
26 /* Based on SCIP - Solving Constraint Integer Programs */
27 /* Copyright (C) 2002-2016 Zuse Institute Berlin */
28 /* SCIP is distributed under the terms of the SCIP Academic Licence, */
29 /* see file COPYING in the SCIP distribution. */
30 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
40 /*#define SCIP_DEBUG*/
41 /*#define SCIP_MORE_DEBUG*/
42 
43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44 #include "objreader_sdpa.h"
45 
46 #include <cassert> // for assert
47 #include <cctype> // for isspace
48 #include <cstdio> // for printf
49 #include <cstdlib> // for abs /*lint !e10*//*lint !e129*/
50 #include <istream> // for istream, etc
51 #include <string> // for getline, string
52 
53 #include "BlockMemoryAllocator.h" // for BlockMemoryAllocator
54 #include "ScipStreamBuffer.h" // for ScipStreamBuffer
55 #include "scipsdp/cons_sdp.h" // for SCIPcreateConsSdp
56 
57 #include "scip/cons_linear.h" // for SCIPaddCoefLinear, etc
58 #include "scip/scip.h" // for SCIPinfinity, etc
59 
60 /* turn off lint warnings for whole file: */
61 /*lint --e{788,818}*/
62 
63 namespace
64 {
65 
66 /* drop spaces and all brackets that are allowed within the blocks in the sdpa format */
67  inline void drop_space(std::istream& line)
68  {
69  while(std::isspace(line.peek()) || line.peek() == '(' || line.peek() == '{' || line.peek() == ')' || line.peek() == '}' || line.peek() == ',')
70  {
71  line.ignore(1);/*lint !e747*//*lint !e534*/
72  }
73  return;
74  }
75 
76  inline void drop_rest_line (std::istream& s)
77  {
78  std::string tmp;
79  std::getline(s, tmp);/*lint !e534*/
80  return;
81  }
82 
83 }
84 
85 namespace scip
86 {
87 
89  static
90  SCIP_RETCODE dropComments(
91  std::istream* file /* the file instance that is read */
92  )
93  {
94  char fst_col('"');
95  fst_col = (*file).peek();/*lint !e734*//*lint !e838*/
96  while (fst_col == '"' || fst_col == '*')
97  {
98  drop_rest_line(*file);
99  fst_col = (*file).peek();/*lint !e734*/
100  }
101  return SCIP_OKAY;
102  }
103 
104  /* drop spaces and all brackets that are allowed within the blocks in the sdpa format, throws an error if it reaches a newline */
105  static
106  SCIP_RETCODE dropSpaceNewlineError(std::istream& line)
107  {
108  if ( line.peek() == '\n' )
109  {
110  SCIPerrorMessage("Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
111  return SCIP_ERROR;
112  }
113  while(std::isspace(line.peek()) || line.peek() == '(' || line.peek() == '{' || line.peek() == ')' || line.peek() == '}' || line.peek() == ',')
114  {
115  line.ignore(1);/*lint !e747*//*lint !e534*/
116  if ( line.peek() == '\n' )
117  {
118  SCIPerrorMessage("Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
119  return SCIP_ERROR;
120  }
121  }
122  return SCIP_OKAY;
123  }
124 
125  /* checks that only spaces, newlines or comments follow in the current line */
126  static
127  SCIP_RETCODE checkForLineEnd(std::istream& line)
128  {
129  if ( line.peek() == '\n' || line.peek() == '"' || line.peek() == '*' || line.peek() == EOF )
130  {
131  return SCIP_OKAY;
132  }
133  while(std::isspace(line.peek()) || line.peek() == '(' || line.peek() == '{' || line.peek() == ')' || line.peek() == '}' || line.peek() == ',')
134  {
135  line.ignore(1);/*lint !e747*//*lint !e534*/
136  if ( line.peek() == '\n' || line.peek() == '"' || line.peek() == '*' || line.peek() == EOF )
137  {
138  return SCIP_OKAY;
139  }
140  else if (std::isspace(line.peek()) || line.peek() == '(' || line.peek() == '{' || line.peek() == ')' || line.peek() == '}' || line.peek() == ',')
141  continue;
142  else
143  {
144  SCIPerrorMessage("Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
145  return SCIP_ERROR;
146  }
147  }
148  return SCIP_OKAY;
149  }
150 
152  static
153  SCIP_RETCODE testDigit(
154  std::istream* file /* the file instance that is read */
155  )
156  {
157  if ( (! isdigit((*file).peek())) && (! ((*file).peek() == '-')) )
158  {
159  SCIPerrorMessage("Input File invalid, only numerals allowed in SDP/LP-block rows, see data_format.txt\n");
160  return SCIP_ERROR;
161  }
162 
163  return SCIP_OKAY;
164  }
165 
167  static
168  SCIP_RETCODE checkIndex(
169  const char* indexname, /* name of the index that will be used in the error message */
170  int value, /* value to check against the upper bound */
171  int ub /* upper bound to check against */
172  )
173  {
174  if ( value > ub )
175  {
176  SCIPerrorMessage("In an SDP/LP-block-line %s index %d was larger than given number of %ss %d.\n", indexname, value, indexname, ub);
177  return SCIP_ERROR;
178  }
179  return SCIP_OKAY;
180  }
181 
191  SCIP* scip,
192  SCIP_READER* reader,
193  const char* filename,
194  SCIP_RESULT* result
195  )
196  {/*lint --e{715}*/
197  *result = SCIP_DIDNOTRUN;
198 
199  int numvars; //Number of variables
200  int numblocks; //Number of all blocks (SDP + LP)
201  int numsdpblocks; //Number of SDP-blocks
202  int numlpblocks; //Number of LP-blocks
203  int alllpblocksize; //Size of all LP-blocks added
204  int* nvarnonz; // nblockvarnonz[i] gives the number of nonzeros for variable i
205  SCIP_Real feastol; // used to check for nonzeros
206 #ifndef NDEBUG
207  int snprintfreturn; // to check return codes of snprintf
208 #endif
209 
210  std::vector<int, BlockMemoryAllocator<int> > blockpattern =
211  std::vector<int, BlockMemoryAllocator<int> >(BlockMemoryAllocator<int>(scip)); //Vector with the sizes of all blocks
212  std::vector<SCIP_Real> object; //Objectivevector
213  std::vector<SDPBlock> blockstruct; //Blockstructure
214  LPBlock LPData; //LP Data
215  std::vector<bool> blockislp; //Is the block an LP block?
216  std::vector<int> intvars; //Indices of integer variables
217  std::vector <int> lp_block_num;
218  std::vector <int> lp_block_size;
219  int new_row_index;
220  bool lp_block_already_done;
221 
222  SCIP_FILE* scip_file = SCIPfopen(filename, "r");
223  if (!scip_file)
224  return SCIP_READERROR;
225 
226  // setup buffer
227  ScipStreamBuffer scip_buffer(scip, scip_file, true);
228 
229  // setup our stream from the new buffer
230  std::istream file(&scip_buffer);
231 
232  // initialize feastol
233  SCIP_CALL( SCIPgetRealParam(scip, "numerics/feastol", &feastol) );
234 
235  if( !file )
236  return SCIP_READERROR;
237  file.clear();
238 
239  SCIP_CALL(dropComments(&file));
240 
241  // read numvar
242  drop_space(file);
243  file >> numvars;
244  drop_rest_line(file);
245 
246  SCIP_CALL(dropComments(&file));
247 
248  // read numblocks
249  drop_space(file);
250  file >> numblocks;
251 
252  drop_rest_line(file);
253 
254  numlpblocks = 0;
255  numsdpblocks = 0;
256  alllpblocksize = 0;
257 
258  SCIP_CALL(dropComments(&file));
259 
260  // read block pattern
261  blockpattern = std::vector<int, BlockMemoryAllocator<int> >(numblocks, 0, BlockMemoryAllocator<int>(scip));
262  blockislp = std::vector<bool>(numblocks, false);/*lint !e747*//*lint !e732*/
263  lp_block_num = std::vector<int>(numblocks, 0);
264  lp_block_size = std::vector<int>(numblocks, 0);
265 
266  for (int j = 0; j < numblocks; ++j)
267  {
268  drop_space(file);
269  file >> blockpattern[j];/*lint !e747*//*lint !e732*/
270  if (blockpattern[j] > 0)/*lint !e747*//*lint !e732*/
271  {
272  numsdpblocks++;
273  blockstruct.push_back(SDPBlock(blockpattern[j]));/*lint !e747*//*lint !e732*/
274 
275  }
276  else if (blockpattern[j] < 0)/*lint !e747*//*lint !e732*/
277  {
278  //LP block has a negative coefficient!
279  numlpblocks++;
280  alllpblocksize += abs(blockpattern[j]);/*lint !e747*//*lint !e732*/
281  blockislp[j] = true;/*lint !e747*//*lint !e732*//*lint !e1793*/
282  blockstruct.push_back(SDPBlock(0));
283  lp_block_num[j] = numlpblocks;/*lint !e747*//*lint !e732*/
284  lp_block_size[numlpblocks - 1] = abs(blockpattern[j]);/*lint !e747*//*lint !e732*/
285 
286  }
287  else
288  printf("Blocklength 0 seems a bit odd, don't you think!\n");
289  }
290 
291  assert(numblocks == numsdpblocks + numlpblocks);
292 
293  drop_rest_line(file);
294  drop_space(file);
295 
296  SCIP_CALL(dropComments(&file));
297 
298  // read objective
299  object = std::vector<SCIP_Real>(numvars, 0.0);/*lint !e747*//*lint !e732*/
300  for (int i = 0; i < numvars; ++i)
301  {
302  file >> object[i];/*lint !e747*//*lint !e732*/
303  drop_space(file);
304  }
305 
306  SCIPdebugMessage("Number of variables: %d \n", numvars);
307  SCIPdebugMessage("Number of blocks: %d \n", numblocks);
308  SCIPdebugMessage("Number of SDP- and LP-cones: %d, %d \n", numsdpblocks, numlpblocks);
309 
310 
311  // construct blocks
312 
313  //construct LP block
314  LPData.rows = std::vector<LProw>(alllpblocksize);/*lint !e747*//*lint !e732*/
315  LPData.numrows = alllpblocksize;
316  SCIPdebugMessage("Number of LP constraints: %d\n", alllpblocksize);
317 
318  std::string commentline;
319 
320  // read data
321  while(!file.eof())
322  {
323  if(file.peek() == '*') // comment
324  {
325  std::getline(file, commentline);/*lint !e534*/
326  if (commentline.find("*INT") == 0) // if current line starts with *INT then go to Integer definitions
327  {
328  drop_space(file); // drop \newline
329  break;
330  }
331  else // usual comment line
332  {
333  drop_space(file);
334  }
335  }
336  else
337  {
338  int var_index, block_index; // block id
339  int row_index, col_index; // position in matrix
340  SCIP_Real val;
341  drop_space(file);
342 
343  SCIP_CALL( testDigit(&file) );
344  file >> var_index;
345  SCIP_CALL( checkIndex("variable", var_index, numvars) );
346  SCIP_CALL( dropSpaceNewlineError(file) );
347 
348  SCIP_CALL( testDigit(&file) );
349  file >> block_index;
350  SCIP_CALL( checkIndex("block", block_index, numblocks) );
351  SCIP_CALL( dropSpaceNewlineError(file) );
352 
353  SCIP_CALL( testDigit(&file) );
354  file >> row_index;
355  SCIP_CALL( checkIndex("row", row_index, (blockislp[block_index - 1] ? LPData.numrows : blockstruct[block_index - 1].blocksize)) );/*lint !e732*//*lint !e747*/
356  SCIP_CALL( dropSpaceNewlineError(file) );
357 
358  SCIP_CALL( testDigit(&file) );
359  file >> col_index;
360  SCIP_CALL( checkIndex("column", col_index, (blockislp[block_index - 1] ? LPData.numrows : blockstruct[block_index - 1].blocksize)) );/*lint !e732*//*lint !e747*/
361  SCIP_CALL( dropSpaceNewlineError(file) );
362 
363  SCIP_CALL( testDigit(&file) );
364  file >> val;
365  SCIP_CALL( checkForLineEnd(file) );
366 
367  if (SCIPisEQ(scip, val, 0.0))
368  {
369  drop_rest_line(file);
370  drop_space(file);
371  continue;
372  }
373 
374  //sdp-block
375  if (!blockislp[block_index - 1])/*lint !e732*//*lint !e747*/
376  {
377  if (row_index < col_index)
378  {
379  int save_row = row_index;
380  row_index = col_index;
381  col_index = save_row;
382  }
383 
384  if (var_index == 0)
385  {
386  blockstruct[block_index - 1].constcolumns.push_back(col_index);/*lint !e732*//*lint !e747*/
387  blockstruct[block_index - 1].constrows.push_back(row_index);/*lint !e732*//*lint !e747*/
388  blockstruct[block_index - 1].constvalues.push_back(val);/*lint !e732*//*lint !e747*/
389  blockstruct[block_index - 1].constnum_nonzeros++;/*lint !e732*//*lint !e747*/
390  }
391  else
392  {
393  blockstruct[block_index - 1].columns.push_back(col_index);/*lint !e732*//*lint !e747*/
394  blockstruct[block_index - 1].rows.push_back(row_index);/*lint !e732*//*lint !e747*/
395  blockstruct[block_index - 1].values.push_back(val);/*lint !e732*//*lint !e747*/
396  blockstruct[block_index - 1].variables.push_back(var_index);/*lint !e732*//*lint !e747*/
397  blockstruct[block_index - 1].num_nonzeros++;/*lint !e732*//*lint !e747*/
398  }
399  SCIPdebugMessage("SDP entry: block_index: %d, row: %d, col: %d, var: %d, val: %g\n", block_index, row_index, col_index, var_index,val );/*lint !e525*/
400  }
401  //lp-block
402  else if (blockislp[block_index - 1])/*lint !e732*//*lint !e747*/
403  {
404  assert(row_index == col_index);
405  if ( lp_block_num[block_index - 1] == 1 )/*lint !e732*//*lint !e747*/
406  new_row_index = row_index - 1;
407  else //we combine all lp blocks to a single one, so we add the total number of rows of earlier blocks to the row index
408  {
409  int rowoffset;
410  int b;
411 
412  rowoffset = 0;
413 
414  for ( b = 0; b < lp_block_num[block_index - 1] - 1; b++ )/*lint !e732*//*lint !e747*/
415  rowoffset += lp_block_size[b];/*lint !e732*//*lint !e747*/
416 
417  new_row_index = rowoffset + row_index - 1;
418  }
419  LPData.rows[new_row_index].data.push_back(std::make_pair(var_index, val));/*lint !e732*//*lint !e747*/
420  SCIPdebugMessage("LP entry: row: %d, var: %d, val: %g\n", new_row_index, var_index,val );
421  }
422 
423  drop_rest_line(file);
424  drop_space(file);
425  }
426  }
427 
428  //read integer variables
429  intvars = std::vector<int>(numvars, 0);
430 
431  while(file.peek() == '*')
432  {
433  int index;/*lint !e578*/
434  file.ignore(1);/*lint !e534*//*lint !e747*/
435  file >> index;
436  //in the SDPA-file the variable numbers start at 1!
437  intvars[index - 1] = 1;/*lint !e732*//*lint !e747*/
438  SCIPdebugMessage("Variable %d is integer.\n", index - 1);
439  drop_rest_line(file);
440  drop_space(file);
441  }
442 
443 
444  /************************/
445  /* create empty problem */
446  /************************/
447 
448  SCIP_CALL( SCIPcreateProb(scip, filename, 0, 0, 0, 0, 0, 0, 0) );
449 
450  /*****************/
451  /* add variables */
452  /*****************/
453 
454  std::vector<SCIP_VAR*> VariablesX ( numvars );/*lint !e732*//*lint !e747*/
455 
456  for ( int i = 0; i < numvars; ++i)
457  {
458  SCIP_VAR* var;
459  char var_name[SCIP_MAXSTRLEN];
460 #ifndef NDEBUG
461  snprintfreturn = SCIPsnprintf(var_name, SCIP_MAXSTRLEN, "X_%d", i);
462  assert( snprintfreturn < SCIP_MAXSTRLEN);
463 #else
464  (void)SCIPsnprintf(var_name, SCIP_MAXSTRLEN, "X_%d", i);
465 #endif
466 
467 
468  if (intvars[i] == 1)/*lint !e732*//*lint !e747*/
469  {
470  SCIP_CALL( SCIPcreateVar(scip, &var, var_name, -SCIPinfinity(scip), SCIPinfinity(scip), object[i], SCIP_VARTYPE_INTEGER, TRUE, FALSE, 0, 0, 0, 0, 0));/*lint !e732*//*lint !e747*/
471  }
472  else
473  {
474  SCIP_CALL( SCIPcreateVar(scip, &var, var_name, -SCIPinfinity(scip), SCIPinfinity(scip), object[i],
475  SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, 0, 0, 0, 0, 0));/*lint !e732*//*lint !e747*/
476  }
477 
478  SCIP_CALL( SCIPaddVar(scip, var) );
479  VariablesX[i] = var;/*lint !e732*//*lint !e747*/
480 
481  /* release variable for the reader. */
482  SCIP_CALL( SCIPreleaseVar(scip, &var) );
483  }
484 
485 
486  /*********************************/
487  /* create SDP and LP constraints */
488  /*********************************/
489 
490  lp_block_already_done = false;
491  for (int bindex = 0; bindex < numblocks; ++bindex)
492  {
493  if (!blockislp[bindex])/*lint !e732*//*lint !e747*/
494  {
495  int nvars;
496  int nnonz;
497  int blocksize;
498  int* varind; /* this is used to sort the nonzeroes by variable-indices and check which variables are actually included in this block */
499  int* col;
500  int* row;
501  SCIP_Real* val;
502  int** colpointer;
503  int** rowpointer;
504  SCIP_Real** valpointer;
505  SCIP_Var** vars;
506  int constnnonz;
507  int* constcol;
508  int* constrow;
509  SCIP_Real* constval;
510  int k;
511  int ind;
512  int nextindaftervar;
513  int firstindforvar;
514  SCIP_Bool varused;
515 
516  SCIPdebugMessage("Begin construction of SDP constraint for block %d.\n", bindex);
517 
518  blocksize = blockpattern[bindex];/*lint !e732*//*lint !e747*/
519  nnonz = blockstruct[bindex].num_nonzeros;/*lint !e732*//*lint !e747*/
520  ind = 0;
521 
522  /* allocate memory */
523  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &varind, blockstruct[bindex].num_nonzeros) );/*lint !e732*//*lint !e530*/
524  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &col, blockstruct[bindex].num_nonzeros) );/*lint !e732*//*lint !e530*/
525  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &row, blockstruct[bindex].num_nonzeros) );/*lint !e732*//*lint !e530*/
526  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &val, blockstruct[bindex].num_nonzeros) );/*lint !e732*//*lint !e530*/
527  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &colpointer, numvars) );/*lint !e732*//*lint !e530*/
528  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &rowpointer, numvars) );/*lint !e732*//*lint !e530*/
529  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &valpointer, numvars) );/*lint !e732*//*lint !e530*/
530  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &vars, numvars) );/*lint !e732*//*lint !e530*/
531 
532  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constcol, blockstruct[bindex].constnum_nonzeros) );/*lint !e732*//*lint !e530*/
533  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constrow, blockstruct[bindex].constnum_nonzeros) );/*lint !e732*//*lint !e530*/
534  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constval, blockstruct[bindex].constnum_nonzeros) );/*lint !e732*//*lint !e530*/
535 
536  /* allocate memory for nblockvarnonz & initialize it with zero */
537  SCIP_CALL(SCIPallocBlockMemoryArray(scip, &nvarnonz, numvars));/*lint !e530*/
538  for (int i = 0; i < numvars; i++)
539  nvarnonz[i] = 0;
540 
541  /* prepare the constant arrays */
542  for (k = 0; k < blockstruct[bindex].constnum_nonzeros; ++k)/*lint !e732*//*lint !e747*/
543  {
544  if (blockstruct[bindex].constvalues[k] > feastol || blockstruct[bindex].constvalues[k] < -feastol)/*lint !e732*//*lint !e747*/
545  {
546  constcol[ind] = blockstruct[bindex].constcolumns[k] - 1;/*lint !e732*//*lint !e747*/ /* the sdpa format counts from 1 to blocksize, we want to start from 0 */
547  constrow[ind] = blockstruct[bindex].constrows[k] - 1;/*lint !e732*//*lint !e747*/
548  constval[ind] = blockstruct[bindex].constvalues[k];/*lint !e732*//*lint !e747*/
549  ind++;
550  }
551  }
552  constnnonz = ind;
553 
554  /* prepare the non-constant arrays */
555  ind = 0;
556  for (k = 0; k < nnonz; ++k)
557  {
558  if (blockstruct[bindex].values[k] > feastol || blockstruct[bindex].values[k] < -feastol)/*lint !e732*//*lint !e747*/
559  {
560  varind[ind] = blockstruct[bindex].variables[k] - 1;/*lint !e732*//*lint !e747*/
561  col[ind] = blockstruct[bindex].columns[k] - 1;/*lint !e732*//*lint !e747*/
562  row[ind] = blockstruct[bindex].rows[k] - 1;/*lint !e732*//*lint !e747*/
563  val[ind] = blockstruct[bindex].values[k];/*lint !e732*//*lint !e747*/
564  ind++;
565  }
566  }
567  nnonz = ind;
568 
569  SCIPsortIntIntIntReal(varind, col, row, val, nnonz); /* sort the nonzeroes by non-decreasing variable indices */
570 
571  /* create the pointer arrays and insert used variables into vars-array */
572  nextindaftervar = 0;
573  ind = 0; /* sdp index of the current variable */
574  for (k = 0; k < numvars; k++)
575  {
576  varused = FALSE;
577  firstindforvar = nextindaftervar; /* this variable starts where the last one ended */
578  while (nextindaftervar < nnonz && varind[nextindaftervar] == k) /* get the first index that doesn't belong to this variable */
579  {
580  nextindaftervar++;
581  varused = TRUE;
582  nvarnonz[ind]++;
583  }
584  if (varused)
585  {
586  vars[ind] = VariablesX[k];/*lint !e732*//*lint !e747*/ /* if the variable is used, add it to the vars array */
587  colpointer[ind] = &col[firstindforvar]; /* save a pointer to the first nonzero belonging to this variable */
588  rowpointer[ind] = &row[firstindforvar];
589  valpointer[ind] = &val[firstindforvar];
590  ind++;
591  }
592  }
593 
594  assert (nextindaftervar == nnonz);
595 
596  /* this was only needed to compute the vars arrays */
597  SCIPfreeBlockMemoryArray(scip, &varind, blockstruct[bindex].num_nonzeros);/*lint !e747*/
598 
599  nvars = ind;
600 
601  SCIP_CONS* sdpcon;
602  char sdpcon_name[SCIP_MAXSTRLEN];
603 #ifndef NDEBUG
604  snprintfreturn = SCIPsnprintf(sdpcon_name, SCIP_MAXSTRLEN, "SDP-Constraint-%d", bindex);
605  assert( snprintfreturn < SCIP_MAXSTRLEN);
606 #else
607  (void) SCIPsnprintf(sdpcon_name, SCIP_MAXSTRLEN, "SDP-Constraint-%d", bindex);
608 #endif
609  SCIP_CALL( SCIPcreateConsSdp(scip, &sdpcon, sdpcon_name, nvars, nnonz, blocksize, nvarnonz, colpointer,
610  rowpointer, valpointer, vars, constnnonz, constcol, constrow, constval) );
611 
612 #ifdef SCIP_MORE_DEBUG
613  SCIP_CALL( SCIPprintCons(scip, sdpcon, NULL) );
614 #endif
615 
616  SCIP_CALL( SCIPaddCons(scip, sdpcon) );
617 
618  SCIP_CALL( SCIPreleaseCons(scip, &sdpcon) );
619 
620  /* free the used arrays */
621  SCIPfreeBlockMemoryArray(scip, &nvarnonz, numvars);
622  SCIPfreeBlockMemoryArray(scip, &constval, blockstruct[bindex].constnum_nonzeros);/*lint !e747*/
623  SCIPfreeBlockMemoryArray(scip, &constrow, blockstruct[bindex].constnum_nonzeros);/*lint !e747*/
624  SCIPfreeBlockMemoryArray(scip, &constcol, blockstruct[bindex].constnum_nonzeros);/*lint !e747*/
625  SCIPfreeBlockMemoryArray(scip, &vars, numvars);
626  SCIPfreeBlockMemoryArray(scip, &valpointer, numvars);
627  SCIPfreeBlockMemoryArray(scip, &rowpointer, numvars);
628  SCIPfreeBlockMemoryArray(scip, &colpointer, numvars);
629  SCIPfreeBlockMemoryArray(scip, &val, blockstruct[bindex].num_nonzeros);/*lint !e747*/
630  SCIPfreeBlockMemoryArray(scip, &row, blockstruct[bindex].num_nonzeros);/*lint !e747*/
631  SCIPfreeBlockMemoryArray(scip, &col, blockstruct[bindex].num_nonzeros);/*lint !e747*/
632 
633  SCIPdebugMessage("Construction of SDP constraint for block %d completed.\n", bindex);
634  }
635  else
636  {
637  //construct lp-block only once
638  if (!lp_block_already_done)
639  {
640  lp_block_already_done = true;
641  SCIPdebugMessage("Begin construction of LP (block %d).\n", bindex);
642 
643  for (int row_i = 0; row_i < LPData.numrows; ++row_i)
644  {
645  SCIP_CONS* LPcon;
646  char LPcon_name[SCIP_MAXSTRLEN];
647 #ifndef NDEBUG
648  snprintfreturn = SCIPsnprintf(LPcon_name, SCIP_MAXSTRLEN, "LP-Con-%d", row_i);
649  assert( snprintfreturn < SCIP_MAXSTRLEN );
650 #else
651  (void) SCIPsnprintf(LPcon_name, SCIP_MAXSTRLEN, "LP-Con-%d", row_i);
652 #endif
653 
654  //Get right hand side of the constraint
655  SCIP_Real LPlhs = 0.0;
656 
657  for (unsigned int var_i = 0; var_i < LPData.rows[row_i].data.size(); ++var_i)/*lint !e732*//*lint !e747*/
658  {
659  if (LPData.rows[row_i].data[var_i].first == 0)/*lint !e732*//*lint !e747*/
660  {
661  LPlhs = LPData.rows[row_i].data[var_i].second;/*lint !e732*//*lint !e747*/
662  }
663  }
664 
665  //Create constraint
666  SCIP_CALL( SCIPcreateConsLinear(scip, &LPcon, LPcon_name, 0, 0, 0, LPlhs, SCIPinfinity(scip), TRUE, TRUE,
667  TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE));
668 
669  SCIP_CALL( SCIPaddCons(scip, LPcon) );
670 
671  //Insert variables into constraint:
672  for (unsigned int var_i = 0; var_i < LPData.rows[row_i].data.size(); ++var_i)/*lint !e732*//*lint !e747*/
673  {
674  if (LPData.rows[row_i].data[var_i].first != 0)/*lint !e732*//*lint !e747*/
675  {
676  SCIP_CALL( SCIPaddCoefLinear(scip, LPcon, VariablesX[LPData.rows[row_i].data[var_i].first - 1], LPData.rows[row_i].data[var_i].second) );/*lint !e732*//*lint !e747*/
677  }
678  }
679 #ifdef SCIP_MORE_DEBUG
680  SCIP_CALL( SCIPprintCons(scip, LPcon, NULL) );
681 #endif
682  SCIP_CALL( SCIPreleaseCons(scip, &LPcon) );
683  }
684  }
685  }
686  }
687 
688  *result = SCIP_SUCCESS;
689 
690  return SCIP_OKAY;
691  }
692 
693 }//end of namespace scip
An STL allocator class using SCIP block memory.
An std::streambuf that uses SCIP I/O routines (suitable for reading)
static SCIP_RETCODE dropSpaceNewlineError(std::istream &line)
std::vector< LProw > rows
Reader for SDPA-Files.
Constraint handler for SDP-constraints.
static SCIP_RETCODE checkForLineEnd(std::istream &line)
SCIP_RETCODE SCIPcreateConsSdp(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, int nnonz, int blocksize, int *nvarnonz, int **col, int **row, SCIP_Real **val, SCIP_VAR **vars, int constnnonz, int *constcol, int *constrow, SCIP_Real *constval)
Definition: cons_sdp.c:2634
static SCIP_RETCODE checkIndex(const char *indexname, int value, int ub)
static SCIP_RETCODE testDigit(std::istream *file)
virtual SCIP_RETCODE scip_read(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
static SCIP_RETCODE dropComments(std::istream *file)