SCIP-SDP  2.0.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-2015 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-2015 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 says this needs an include guard
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 namespace
61 {
62 
63 /* drop spaces and all brackets that are allowed within the blocks in the sdpa format */
64  inline void drop_space(std::istream& line)
65  {
66  while(std::isspace(line.peek()) || line.peek() == '(' || line.peek() == '{' || line.peek() == ')' || line.peek() == '}' || line.peek() == ',')
67  {
68  line.ignore(1);
69  }
70  return;
71  }
72 
73  inline void drop_rest_line (std::istream& s)
74  {
75  std::string tmp;
76  std::getline(s, tmp);
77  return;
78  }
79 
80 }
81 
82 namespace scip
83 {
84 
86  static
87  SCIP_RETCODE dropComments(
88  std::istream* file /* the file instance that is read */
89  )
90  {
91  char fst_col('"');
92  fst_col = (*file).peek();
93  while (fst_col == '"' || fst_col == '*')
94  {
95  drop_rest_line(*file);
96  fst_col = (*file).peek();
97  }
98  return SCIP_OKAY;
99  }
100 
101  /* drop spaces and all brackets that are allowed within the blocks in the sdpa format, throws an error if it reaches a newline */
102  static
103  SCIP_RETCODE dropSpaceNewlineError(std::istream& line)
104  {
105  if ( line.peek() == '\n' )
106  {
107  SCIPerrorMessage("Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
108  return SCIP_ERROR;
109  }
110  while(std::isspace(line.peek()) || line.peek() == '(' || line.peek() == '{' || line.peek() == ')' || line.peek() == '}' || line.peek() == ',')
111  {
112  line.ignore(1);
113  if ( line.peek() == '\n' )
114  {
115  SCIPerrorMessage("Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
116  return SCIP_ERROR;
117  }
118  }
119  return SCIP_OKAY;
120  }
121 
122  /* checks that only spaces, newlines or comments follow in the current line */
123  static
124  SCIP_RETCODE checkForLineEnd(std::istream& line)
125  {
126  if ( line.peek() == '\n' || line.peek() == '"' || line.peek() == '*' || line.peek() == EOF )
127  {
128  return SCIP_OKAY;
129  }
130  while(std::isspace(line.peek()) || line.peek() == '(' || line.peek() == '{' || line.peek() == ')' || line.peek() == '}' || line.peek() == ',')
131  {
132  line.ignore(1);
133  if ( line.peek() == '\n' || line.peek() == '"' || line.peek() == '*' || line.peek() == EOF )
134  {
135  return SCIP_OKAY;
136  }
137  else if (std::isspace(line.peek()) || line.peek() == '(' || line.peek() == '{' || line.peek() == ')' || line.peek() == '}' || line.peek() == ',')
138  continue;
139  else
140  {
141  SCIPerrorMessage("Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
142  return SCIP_ERROR;
143  }
144  }
145  return SCIP_OKAY;
146  }
147 
149  static
150  SCIP_RETCODE testDigit(
151  std::istream* file /* the file instance that is read */
152  )
153  {
154  if ( (! isdigit((*file).peek())) && (! ((*file).peek() == '-')) )
155  {
156  SCIPerrorMessage("Input File invalid, only numerals allowed in SDP/LP-block rows, see data_format.txt\n");
157  return SCIP_ERROR;
158  }
159 
160  return SCIP_OKAY;
161  }
162 
164  static
165  SCIP_RETCODE checkIndex(
166  const char* indexname, /* name of the index that will be used in the error message */
167  int value, /* value to check against the upper bound */
168  int ub /* upper bound to check against */
169  )
170  {
171  if ( value > ub )
172  {
173  SCIPerrorMessage("In an SDP/LP-block-line %s index %d was larger than given number of %ss %d.\n", indexname, value, indexname, ub);
174  return SCIP_ERROR;
175  }
176  return SCIP_OKAY;
177  }
178 
188  SCIP* scip,
189  SCIP_READER* reader,
190  const char* filename,
191  SCIP_RESULT* result
192  )
193  {
194  *result = SCIP_DIDNOTRUN;
195 
196  int numvars; //Number of variables
197  int numblocks; //Number of all blocks (SDP + LP)
198  int numsdpblocks; //Number of SDP-blocks
199  int numlpblocks; //Number of LP-blocks
200  int alllpblocksize; //Size of all LP-blocks added
201  int* nvarnonz; // nblockvarnonz[i] gives the number of nonzeros for variable i
202  SCIP_Real feastol; // used to check for nonzeros
203 
204  std::vector<int, BlockMemoryAllocator<int> > blockpattern =
205  std::vector<int, BlockMemoryAllocator<int> >(BlockMemoryAllocator<int>(scip)); //Vector with the sizes of all blocks
206  std::vector<double> object; //Objectivevector
207  std::vector<SDPBlock> blockstruct; //Blockstructure
208  LPBlock LPData; //LP Data
209  std::vector<bool> blockislp; //Is the block an LP block?
210  std::vector<int> intvars; //Indices of integer variables
211  std::vector <int> lp_block_num;
212  std::vector <int> lp_block_size;
213  int new_row_index;
214  bool lp_block_already_done;
215 
216  SCIP_FILE* scip_file = SCIPfopen(filename, "r");
217  if (!scip_file)
218  return SCIP_READERROR;
219 
220  // setup buffer
221  ScipStreamBuffer scip_buffer(scip, scip_file, true);
222 
223  // setup our stream from the new buffer
224  std::istream file(&scip_buffer);
225 
226  // initialize feastol
227  SCIP_CALL( SCIPgetRealParam(scip, "numerics/feastol", &feastol) );
228 
229  if( !file )
230  return SCIP_READERROR;
231  file.clear();
232 
233  SCIP_CALL(dropComments(&file));
234 
235  // read numvar
236  drop_space(file);
237  file >> numvars;
238  drop_rest_line(file);
239 
240  SCIP_CALL(dropComments(&file));
241 
242  // read numblocks
243  drop_space(file);
244  file >> numblocks;
245 
246  drop_rest_line(file);
247 
248  numlpblocks = 0;
249  numsdpblocks = 0;
250  alllpblocksize = 0;
251 
252  SCIP_CALL(dropComments(&file));
253 
254  // read block pattern
255  blockpattern = std::vector<int, BlockMemoryAllocator<int> >(numblocks, 0, BlockMemoryAllocator<int>(scip));
256  blockislp = std::vector<bool>(numblocks, false);
257  lp_block_num = std::vector<int>(numblocks, 0);
258  lp_block_size = std::vector<int>(numblocks, 0);
259 
260  for (int j = 0; j < numblocks; ++j)
261  {
262  drop_space(file);
263  file >> blockpattern[j];
264  if (blockpattern[j] > 0)
265  {
266  numsdpblocks++;
267  blockstruct.push_back(SDPBlock(blockpattern[j]));
268 
269  }
270  else if (blockpattern[j] < 0)
271  {
272  //LP block has a negative coefficient!
273  numlpblocks++;
274  alllpblocksize += abs(blockpattern[j]);
275  blockislp[j] = true;
276  blockstruct.push_back(SDPBlock(0));
277  lp_block_num[j] = numlpblocks;
278  lp_block_size[numlpblocks] = abs(blockpattern[j]);
279 
280  }
281  else
282  printf("Blocklength 0 seems a bit odd, don't you think!\n");
283  }
284 
285  assert(numblocks == numsdpblocks + numlpblocks);
286 
287  drop_rest_line(file);
288  drop_space(file);
289 
290  SCIP_CALL(dropComments(&file));
291 
292  // read objective
293  object = std::vector<double>(numvars, 0.0);
294  for (int i = 0; i < numvars; ++i)
295  {
296  file >> object[i];
297  drop_space(file);
298  }
299 
300  SCIPdebugMessage("Number of variables: %d \n", numvars);
301  SCIPdebugMessage("Number of blocks: %d \n", numblocks);
302  SCIPdebugMessage("Number of SDP- and LP-cones: %d, %d \n", numsdpblocks, numlpblocks);
303 
304 
305  // construct blocks
306 
307  //construct LP block
308  LPData.rows = std::vector<LProw>(alllpblocksize);
309  LPData.numrows = alllpblocksize;
310 
311  std::vector<int> for_indices;
312  std::string commentline;
313 
314  // read data
315  while(!file.eof())
316  {
317  if(file.peek() == '*') // comment
318  {
319  std::getline(file, commentline);
320  if (commentline.find("*INT") == 0) // if current line starts with *INT then go to Integer definitions
321  {
322  drop_space(file); // drop \newline
323  break;
324  }
325  else // usual comment line
326  {
327  drop_space(file);
328  }
329  }
330  else
331  {
332  int var_index, block_index; // block id
333  int row_index, col_index; // position in matrix
334  double val;
335  drop_space(file);
336 
337  SCIP_CALL( testDigit(&file) );
338  file >> var_index;
339  SCIP_CALL( checkIndex("variable", var_index, numvars) );
340  SCIP_CALL( dropSpaceNewlineError(file) );
341 
342  SCIP_CALL( testDigit(&file) );
343  file >> block_index;
344  SCIP_CALL( checkIndex("block", block_index, numblocks) );
345  SCIP_CALL( dropSpaceNewlineError(file) );
346 
347  SCIP_CALL( testDigit(&file) );
348  file >> row_index;
349  SCIP_CALL( checkIndex("row", row_index, (blockislp[block_index - 1] ? LPData.numrows : blockstruct[block_index - 1].blocksize)) );
350  SCIP_CALL( dropSpaceNewlineError(file) );
351 
352  SCIP_CALL( testDigit(&file) );
353  file >> col_index;
354  SCIP_CALL( checkIndex("column", col_index, (blockislp[block_index - 1] ? LPData.numrows : blockstruct[block_index - 1].blocksize)) );
355  SCIP_CALL( dropSpaceNewlineError(file) );
356 
357  SCIP_CALL( testDigit(&file) );
358  file >> val;
359  SCIP_CALL( checkForLineEnd(file) );
360 
361  if (SCIPisEQ(scip, val, 0.0))
362  {
363  drop_rest_line(file);
364  drop_space(file);
365  continue;
366  }
367 
368  //sdp-block
369  if (!blockislp[block_index - 1])
370  {
371  if (row_index < col_index)
372  {
373  int save_row = row_index;
374  row_index = col_index;
375  col_index = save_row;
376  }
377 
378  if (var_index == 0)
379  {
380  blockstruct[block_index - 1].constcolumns.push_back(col_index);
381  blockstruct[block_index - 1].constrows.push_back(row_index);
382  blockstruct[block_index - 1].constvalues.push_back(val);
383  blockstruct[block_index - 1].constnum_nonzeros++;
384  }
385  else
386  {
387  blockstruct[block_index - 1].columns.push_back(col_index);
388  blockstruct[block_index - 1].rows.push_back(row_index);
389  blockstruct[block_index - 1].values.push_back(val);
390  blockstruct[block_index - 1].variables.push_back(var_index);
391  blockstruct[block_index - 1].num_nonzeros++;
392  }
393  SCIPdebugMessage("SDP entry: block_index: %d, row: %d, col: %d, var: %d, val: %g\n", block_index, row_index, col_index, var_index,val );
394  }
395  //lp-block
396  else if (blockislp[block_index - 1])
397  {
398  assert(row_index == col_index);
399  new_row_index = (row_index - 1) + (lp_block_num[block_index - 1] - 1) * lp_block_size[lp_block_num[block_index - 1] - 1];
400  LPData.rows[new_row_index].data.push_back(std::make_pair(var_index, val));
401  SCIPdebugMessage("LP entry: block_index: %d, row: %d, var: %d, val: %g\n", block_index, new_row_index, var_index,val );
402  }
403 
404  drop_rest_line(file);
405  drop_space(file);
406  }
407  }
408 
409  //read integer variables
410  intvars = std::vector<int>(numvars, 0);
411 
412  while(file.peek() == '*')
413  {
414  int index;
415  file.ignore(1);
416  file >> index;
417  //in the SDPA-file the variable numbers start at 1!
418  intvars[index - 1] = 1;
419  SCIPdebugMessage("Variable %d is integer.\n", index - 1);
420  drop_rest_line(file);
421  drop_space(file);
422  }
423 
424 
425  /************************/
426  /* create empty problem */
427  /************************/
428 
429  SCIP_CALL( SCIPcreateProb(scip, filename, 0, 0, 0, 0, 0, 0, 0) );
430 
431  /*****************/
432  /* add variables */
433  /*****************/
434 
435  std::vector<SCIP_VAR*> VariablesX ( numvars );
436 
437  for ( int i = 0; i < numvars; ++i)
438  {
439  SCIP_VAR* var;
440  char var_name[255];
441  SCIPsnprintf(var_name, 255, "X_%d", i);
442 
443 
444  if (intvars[i] == 1)
445  {
446  SCIP_CALL( SCIPcreateVar(scip, &var, var_name, -SCIPinfinity(scip), SCIPinfinity(scip), object[i], SCIP_VARTYPE_INTEGER, TRUE, FALSE, 0, 0, 0, 0, 0));
447  }
448  else
449  {
450  SCIP_CALL( SCIPcreateVar(scip, &var, var_name, -SCIPinfinity(scip), SCIPinfinity(scip), object[i],
451  SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, 0, 0, 0, 0, 0));
452  }
453 
454  SCIP_CALL( SCIPaddVar(scip, var) );
455  VariablesX[i] = var;
456 
457  /* release variable for the reader. */
458  SCIP_CALL( SCIPreleaseVar(scip, &var) );
459  }
460 
461 
462  /*********************************/
463  /* create SDP and LP constraints */
464  /*********************************/
465 
466  lp_block_already_done = false;
467  for (int bindex = 0; bindex < numblocks; ++bindex)
468  {
469  if (!blockislp[bindex])
470  {
471  int nvars;
472  int nnonz;
473  int blocksize;
474  int* varind; /* this is used to sort the nonzeroes by variable-indices and check which variables are actually included in this block */
475  int* col;
476  int* row;
477  SCIP_Real* val;
478  int** colpointer;
479  int** rowpointer;
480  SCIP_Real** valpointer;
481  SCIP_Var** vars;
482  int constnnonz;
483  int* constcol;
484  int* constrow;
485  SCIP_Real* constval;
486  int k;
487  int ind;
488  int nextindaftervar;
489  int firstindforvar;
490  SCIP_Bool varused;
491 
492  SCIPdebugMessage("Begin construction of SDP constraint for block %d.\n", bindex);
493 
494  blocksize = blockpattern[bindex];
495  nnonz = blockstruct[bindex].num_nonzeros;
496  ind = 0;
497 
498  /* allocate memory */
499  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &varind, blockstruct[bindex].num_nonzeros) );
500  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &col, blockstruct[bindex].num_nonzeros) );
501  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &row, blockstruct[bindex].num_nonzeros) );
502  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &val, blockstruct[bindex].num_nonzeros) );
503  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &colpointer, numvars) );
504  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &rowpointer, numvars) );
505  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &valpointer, numvars) );
506  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &vars, numvars) );
507 
508  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constcol, blockstruct[bindex].constnum_nonzeros) );
509  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constrow, blockstruct[bindex].constnum_nonzeros) );
510  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constval, blockstruct[bindex].constnum_nonzeros) );
511 
512  /* allocate memory for nblockvarnonz & initialize it with zero */
513  SCIP_CALL(SCIPallocBlockMemoryArray(scip, &nvarnonz, numvars));
514  for (int i = 0; i < numvars; i++)
515  nvarnonz[i] = 0;
516 
517  /* prepare the constant arrays */
518  for (k = 0; k < blockstruct[bindex].constnum_nonzeros; ++k)
519  {
520  if (blockstruct[bindex].constvalues[k] > feastol || blockstruct[bindex].constvalues[k] < -feastol)
521  {
522  constcol[ind] = blockstruct[bindex].constcolumns[k] - 1; /* the sdpa format counts from 1 to blocksize, we want to start from 0 */
523  constrow[ind] = blockstruct[bindex].constrows[k] - 1;
524  constval[ind] = blockstruct[bindex].constvalues[k];
525  ind++;
526  }
527  }
528  constnnonz = ind;
529 
530  /* prepare the non-constant arrays */
531  ind = 0;
532  for (k = 0; k < nnonz; ++k)
533  {
534  if (blockstruct[bindex].values[k] > feastol || blockstruct[bindex].values[k] < -feastol)
535  {
536  varind[ind] = blockstruct[bindex].variables[k] - 1;
537  col[ind] = blockstruct[bindex].columns[k] - 1;
538  row[ind] = blockstruct[bindex].rows[k] - 1;
539  val[ind] = blockstruct[bindex].values[k];
540  ind++;
541  }
542  }
543  nnonz = ind;
544 
545  SCIPsortIntIntIntReal(varind, col, row, val, nnonz); /* sort the nonzeroes by non-decreasing variable indices */
546 
547  /* create the pointer arrays and insert used variables into vars-array */
548  nextindaftervar = 0;
549  ind = 0; /* sdp index of the current variable */
550  for (k = 0; k < numvars; k++)
551  {
552  varused = FALSE;
553  firstindforvar = nextindaftervar; /* this variable starts where the last one ended */
554  while (nextindaftervar < nnonz && varind[nextindaftervar] == k) /* get the first index that doesn't belong to this variable */
555  {
556  nextindaftervar++;
557  varused = TRUE;
558  nvarnonz[ind]++;
559  }
560  if (varused)
561  {
562  vars[ind] = VariablesX[k]; /* if the variable is used, add it to the vars array */
563  colpointer[ind] = &col[firstindforvar]; /* save a pointer to the first nonzero belonging to this variable */
564  rowpointer[ind] = &row[firstindforvar];
565  valpointer[ind] = &val[firstindforvar];
566  ind++;
567  }
568  }
569 
570  assert (nextindaftervar == nnonz);
571 
572  /* this was only needed to compute the vars arrays */
573  SCIPfreeBlockMemoryArray(scip, &varind, blockstruct[bindex].num_nonzeros);
574 
575  nvars = ind;
576 
577  SCIP_CONS* sdpcon;
578  char sdpcon_name[255];
579  SCIPsnprintf(sdpcon_name, 255, "SDP-Constraint-%d", bindex);
580  SCIP_CALL( SCIPcreateConsSdp(scip, &sdpcon, sdpcon_name, nvars, nnonz, blocksize, nvarnonz, colpointer,
581  rowpointer, valpointer, vars, constnnonz, constcol, constrow, constval) );
582 
583 #ifdef SCIP_MORE_DEBUG
584  SCIP_CALL( SCIPprintCons(scip, sdpcon, NULL) );
585 #endif
586 
587  SCIP_CALL( SCIPaddCons(scip, sdpcon) );
588 
589  SCIP_CALL( SCIPreleaseCons(scip, &sdpcon) );
590 
591  /* free the used arrays */
592  SCIPfreeBlockMemoryArray(scip, &nvarnonz, numvars);
593  SCIPfreeBlockMemoryArray(scip, &constval, blockstruct[bindex].constnum_nonzeros);
594  SCIPfreeBlockMemoryArray(scip, &constrow, blockstruct[bindex].constnum_nonzeros);
595  SCIPfreeBlockMemoryArray(scip, &constcol, blockstruct[bindex].constnum_nonzeros);
596  SCIPfreeBlockMemoryArray(scip, &vars, numvars);
597  SCIPfreeBlockMemoryArray(scip, &valpointer, numvars);
598  SCIPfreeBlockMemoryArray(scip, &rowpointer, numvars);
599  SCIPfreeBlockMemoryArray(scip, &colpointer, numvars);
600  SCIPfreeBlockMemoryArray(scip, &val, blockstruct[bindex].num_nonzeros);
601  SCIPfreeBlockMemoryArray(scip, &row, blockstruct[bindex].num_nonzeros);
602  SCIPfreeBlockMemoryArray(scip, &col, blockstruct[bindex].num_nonzeros);
603 
604  SCIPdebugMessage("Construction of SDP constraint for block %d completed.\n", bindex);
605  }
606  else
607  {
608  //construct lp-block only once
609  if (!lp_block_already_done)
610  {
611  lp_block_already_done = true;
612  SCIPdebugMessage("Begin construction of LP (block %d).\n", bindex);
613 
614  for (int row_i = 0; row_i < LPData.numrows; ++row_i)
615  {
616  SCIP_CONS* LPcon;
617  char LPcon_name[255];
618  SCIPsnprintf(LPcon_name, 255, "LP-Con-%d", row_i);
619 
620  //Get right hand side of the constraint
621  double LPlhs = 0.0;
622 
623  for (unsigned int var_i = 0; var_i < LPData.rows[row_i].data.size(); ++var_i)
624  {
625  if (LPData.rows[row_i].data[var_i].first == 0)
626  {
627  LPlhs = LPData.rows[row_i].data[var_i].second;
628  }
629  }
630 
631  //Create constraint
632  SCIP_CALL( SCIPcreateConsLinear(scip, &LPcon, LPcon_name, 0, 0, 0, LPlhs, SCIPinfinity(scip), TRUE, TRUE,
633  TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE));
634 
635  SCIP_CALL( SCIPaddCons(scip, LPcon) );
636 
637  //Insert variables into constraint:
638  for (unsigned int var_i = 0; var_i < LPData.rows[row_i].data.size(); ++var_i)
639  {
640  if (LPData.rows[row_i].data[var_i].first != 0)
641  {
642  SCIP_CALL( SCIPaddCoefLinear(scip, LPcon, VariablesX[LPData.rows[row_i].data[var_i].first - 1], LPData.rows[row_i].data[var_i].second) );
643  }
644  }
645 #ifdef SCIP_MORE_DEBUG
646  SCIP_CALL( SCIPprintCons(scip, LPcon, NULL) );
647 #endif
648  SCIP_CALL( SCIPreleaseCons(scip, &LPcon) );
649  }
650  }
651  }
652  }
653 
654  *result = SCIP_SUCCESS;
655 
656  return SCIP_OKAY;
657  }
658 
659 }//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:2275
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)