56 #include "scip/cons_linear.h" 57 #include "scip/scip.h" 65 while ( std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',' )
67 (void) line.ignore(1);
75 (void) std::getline(s, tmp);
85 fst_col = (char) (*file).peek();
86 while (fst_col ==
'"' || fst_col ==
'*')
89 fst_col = (char) (*file).peek();
99 if ( line.peek() ==
'\n' )
101 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt.\n");
105 while ( std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',' )
107 (void) line.ignore(1);
108 if ( (
char) line.peek() ==
'\n' )
110 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
123 if ( line.peek() ==
'\n' || line.peek() ==
'"' || line.peek() ==
'*' || line.peek() == EOF )
126 while ( std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',' )
128 (void) line.ignore(1);
130 if ( line.peek() ==
'\n' || line.peek() ==
'"' || line.peek() ==
'*' || line.peek() == EOF )
132 else if ( std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',' )
136 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
149 if ( (! isdigit((*file).peek())) && (! ((*file).peek() ==
'-')) )
151 SCIPerrorMessage(
"Input File invalid, got character '%c', but only numerals allowed in SDP/LP-block rows, see data_format.txt\n", (*file).peek());
152 return SCIP_READERROR;
161 const char* indexname,
169 SCIPerrorMessage(
"In an SDP/LP-block-line %s index %d was smaller than %d.\n", indexname, value, lb);
174 SCIPerrorMessage(
"In an SDP/LP-block-line %s index %d was larger than given number of %ss %d.\n", indexname, value, indexname, ub);
200 assert(
scip != NULL );
201 assert( filename != NULL );
202 assert( result != NULL );
204 *result = SCIP_DIDNOTRUN;
206 std::vector<int, BlockMemoryAllocator<int> > blockpattern =
208 std::vector<SCIP_Real> object;
209 std::vector<SDPBlock> blockstruct;
211 std::vector<bool> blockislp;
212 std::vector<int> intvars;
213 std::vector<int> lp_block_num;
214 std::vector<int> lp_block_size;
216 bool lp_block_already_done;
218 SCIP_FILE* scip_file = SCIPfopen(filename,
"r");
220 return SCIP_READERROR;
226 std::istream file(&scip_buffer);
229 return SCIP_READERROR;
239 SCIPerrorMessage(
"Number of variables is negative!\n");
240 return SCIP_READERROR;
251 SCIPerrorMessage(
"Number of blocks is negative!\n");
252 return SCIP_READERROR;
264 blockislp = std::vector<bool>(numblocks,
false);
265 lp_block_num = std::vector<int>(numblocks, 0);
266 lp_block_size = std::vector<int>(numblocks, 0);
268 for (
int j = 0; j < numblocks; ++j)
271 file >> blockpattern[j];
272 if ( blockpattern[j] > 0 )
275 blockstruct.push_back(
SDPBlock(blockpattern[j]));
277 else if ( blockpattern[j] < 0 )
281 alllpblocksize += abs(blockpattern[j]);
284 lp_block_num[j] = numlpblocks;
285 lp_block_size[numlpblocks - 1] = abs(blockpattern[j]);
288 SCIPwarningMessage(
scip,
"A blocklength 0 seems a bit odd, don't you think!\n");
290 assert(numblocks == numsdpblocks + numlpblocks);
297 object = std::vector<SCIP_Real>(numvars, 0.0);
298 for (
int i = 0; i < numvars; ++i)
304 SCIPdebugMsg(
scip,
"Number of variables: %d \n", numvars);
305 SCIPdebugMsg(
scip,
"Number of blocks: %d \n", numblocks);
306 SCIPdebugMsg(
scip,
"Number of SDP-cones: %d\n", numsdpblocks);
307 SCIPdebugMsg(
scip,
"Number of LP-cones: %d\n", numlpblocks);
312 LPData.
rows = std::vector<LProw>(alllpblocksize);
313 LPData.
numrows = alllpblocksize;
314 SCIPdebugMsg(
scip,
"Number of LP constraints: %d\n", alllpblocksize);
316 std::string commentline;
319 while ( ! file.eof() )
321 if ( file.peek() ==
'*' )
323 (void) std::getline(file, commentline);
324 if ( commentline.find(
"*INT") == 0 )
336 int var_index, block_index;
337 int row_index, col_index;
344 SCIP_CALL(
checkIndex(
"variable", var_index, 0, numvars) );
349 SCIP_CALL(
checkIndex(
"block", block_index, 1, numblocks) );
354 SCIP_CALL(
checkIndex(
"row", row_index, 1, (blockislp[block_index - 1] ? LPData.
numrows : blockstruct[block_index - 1].blocksize)) );
359 SCIP_CALL(
checkIndex(
"column", col_index, 1, (blockislp[block_index - 1] ? LPData.
numrows : blockstruct[block_index - 1].blocksize)) );
366 if ( SCIPisEQ(
scip, val, 0.0) )
374 if ( ! blockislp[block_index - 1] )
376 if ( row_index < col_index )
378 int save_row = row_index;
379 row_index = col_index;
380 col_index = save_row;
383 if ( var_index == 0 )
385 blockstruct[block_index - 1].constcolumns.push_back(col_index);
386 blockstruct[block_index - 1].constrows.push_back(row_index);
387 blockstruct[block_index - 1].constvalues.push_back(val);
388 blockstruct[block_index - 1].constnum_nonzeros++;
392 blockstruct[block_index - 1].columns.push_back(col_index);
393 blockstruct[block_index - 1].rows.push_back(row_index);
394 blockstruct[block_index - 1].values.push_back(val);
395 blockstruct[block_index - 1].variables.push_back(var_index);
396 blockstruct[block_index - 1].num_nonzeros++;
398 SCIPdebugMsg(
scip,
"SDP entry: block_index: %d, row: %d, col: %d, var: %d, val: %g\n", block_index, row_index, col_index, var_index,val );
401 else if ( blockislp[block_index - 1] )
403 assert( row_index == col_index );
404 if ( lp_block_num[block_index - 1] == 1 )
405 new_row_index = row_index - 1;
410 for (
int b = 0; b < lp_block_num[block_index - 1] - 1; b++)
411 rowoffset += lp_block_size[b];
413 new_row_index = rowoffset + row_index - 1;
415 LPData.
rows[new_row_index].data.push_back(std::make_pair(var_index, val));
416 SCIPdebugMsg(
scip,
"LP entry: row: %d, var: %d, val: %g\n", new_row_index, var_index,val );
425 intvars = std::vector<int>(numvars, 0);
428 (void) std::getline(file, str);
429 while ( str[0] ==
'*' && isdigit(str[1]) )
433 (void) str.erase(0, 1);
434 idx = atoi(str.c_str());
435 SCIP_CALL(
checkIndex(
"variable", idx, 1, numvars) );
438 intvars[idx - 1] = 1;
439 SCIPdebugMsg(
scip,
"Variable %d is integer.\n", idx - 1);
441 (void) std::getline(file, str);
449 SCIP_CALL( SCIPcreateProb(
scip, filename, 0, 0, 0, 0, 0, 0, 0) );
455 std::vector<SCIP_VAR*> VariablesX ( numvars );
457 for (
int i = 0; i < numvars; ++i)
460 char var_name[SCIP_MAXSTRLEN];
462 int snprintfreturn = SCIPsnprintf(var_name, SCIP_MAXSTRLEN,
"X_%d", i);
463 assert( snprintfreturn < SCIP_MAXSTRLEN);
465 (void) SCIPsnprintf(var_name, SCIP_MAXSTRLEN,
"X_%d", i);
468 if ( intvars[i] == 1 )
470 SCIP_CALL( SCIPcreateVar(
scip, &var, var_name, -SCIPinfinity(
scip), SCIPinfinity(
scip),
object[i], SCIP_VARTYPE_INTEGER, TRUE, FALSE, 0, 0, 0, 0, 0));
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));
478 SCIP_CALL( SCIPaddVar(
scip, var) );
482 SCIP_CALL( SCIPreleaseVar(
scip, &var) );
490 lp_block_already_done =
false;
491 for (
int bindex = 0; bindex < numblocks; ++bindex)
493 if ( ! blockislp[bindex] )
504 SCIP_Real** valpointer;
516 SCIPdebugMsg(
scip,
"Begin construction of SDP constraint for block %d.\n", bindex);
518 blocksize = blockpattern[bindex];
519 nnonz = blockstruct[bindex].num_nonzeros;
523 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &varind, blockstruct[bindex].num_nonzeros) );
524 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &col, blockstruct[bindex].num_nonzeros) );
525 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &row, blockstruct[bindex].num_nonzeros) );
526 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &val, blockstruct[bindex].num_nonzeros) );
527 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &colpointer, numvars) );
528 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &rowpointer, numvars) );
529 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &valpointer, numvars) );
530 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &vars, numvars) );
532 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &constcol, blockstruct[bindex].constnum_nonzeros) );
533 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &constrow, blockstruct[bindex].constnum_nonzeros) );
534 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &constval, blockstruct[bindex].constnum_nonzeros) );
537 SCIP_CALL(SCIPallocBlockMemoryArray(
scip, &nvarnonz, numvars));
538 for (
int i = 0; i < numvars; i++)
542 for (k = 0; k < blockstruct[bindex].constnum_nonzeros; ++k)
544 if ( ! SCIPisZero(
scip, blockstruct[bindex].constvalues[k]) )
546 constcol[ind] = blockstruct[bindex].constcolumns[k] - 1;
547 constrow[ind] = blockstruct[bindex].constrows[k] - 1;
548 constval[ind] = blockstruct[bindex].constvalues[k];
556 for (k = 0; k < nnonz; ++k)
558 if ( ! SCIPisZero(
scip, blockstruct[bindex].values[k]) )
560 varind[ind] = blockstruct[bindex].variables[k] - 1;
561 col[ind] = blockstruct[bindex].columns[k] - 1;
562 row[ind] = blockstruct[bindex].rows[k] - 1;
563 val[ind] = blockstruct[bindex].values[k];
569 SCIPsortIntIntIntReal(varind, col, row, val, nnonz);
574 for (k = 0; k < numvars; k++)
577 firstindforvar = nextindaftervar;
578 while ( nextindaftervar < nnonz && varind[nextindaftervar] == k )
586 vars[ind] = VariablesX[k];
587 colpointer[ind] = &col[firstindforvar];
588 rowpointer[ind] = &row[firstindforvar];
589 valpointer[ind] = &val[firstindforvar];
594 assert (nextindaftervar == nnonz);
597 SCIPfreeBlockMemoryArray(
scip, &varind, blockstruct[bindex].num_nonzeros);
602 char sdpcon_name[SCIP_MAXSTRLEN];
604 int snprintfreturn = SCIPsnprintf(sdpcon_name, SCIP_MAXSTRLEN,
"SDP-Constraint-%d", bindex);
605 assert( snprintfreturn < SCIP_MAXSTRLEN);
607 (void) SCIPsnprintf(sdpcon_name, SCIP_MAXSTRLEN,
"SDP-Constraint-%d", bindex);
609 SCIP_CALL(
SCIPcreateConsSdp(
scip, &sdpcon, sdpcon_name, nvars, nnonz, blocksize, nvarnonz, colpointer,
610 rowpointer, valpointer, vars, constnnonz, constcol, constrow, constval) );
612 #ifdef SCIP_MORE_DEBUG 613 SCIP_CALL( SCIPprintCons(
scip, sdpcon, NULL) );
616 SCIP_CALL( SCIPaddCons(
scip, sdpcon) );
618 SCIP_CALL( SCIPreleaseCons(
scip, &sdpcon) );
621 SCIPfreeBlockMemoryArray(
scip, &nvarnonz, numvars);
622 SCIPfreeBlockMemoryArray(
scip, &constval, blockstruct[bindex].constnum_nonzeros);
623 SCIPfreeBlockMemoryArray(
scip, &constrow, blockstruct[bindex].constnum_nonzeros);
624 SCIPfreeBlockMemoryArray(
scip, &constcol, blockstruct[bindex].constnum_nonzeros);
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);
630 SCIPfreeBlockMemoryArray(
scip, &row, blockstruct[bindex].num_nonzeros);
631 SCIPfreeBlockMemoryArray(
scip, &col, blockstruct[bindex].num_nonzeros);
633 SCIPdebugMsg(
scip,
"Construction of SDP constraint for block %d completed.\n", bindex);
638 if ( ! lp_block_already_done )
640 lp_block_already_done =
true;
641 SCIPdebugMsg(
scip,
"Begin construction of LP (block %d).\n", bindex);
643 for (
int row_i = 0; row_i < LPData.
numrows; ++row_i)
646 char LPcon_name[SCIP_MAXSTRLEN];
648 int snprintfreturn = SCIPsnprintf(LPcon_name, SCIP_MAXSTRLEN,
"LP-Con-%d", row_i);
649 assert( snprintfreturn < SCIP_MAXSTRLEN );
651 (void) SCIPsnprintf(LPcon_name, SCIP_MAXSTRLEN,
"LP-Con-%d", row_i);
655 SCIP_Real LPlhs = 0.0;
656 for (
unsigned int var_i = 0; var_i < LPData.
rows[row_i].data.size(); ++var_i)
658 if (LPData.
rows[row_i].data[var_i].first == 0)
660 LPlhs = LPData.
rows[row_i].data[var_i].second;
665 SCIP_CALL( SCIPcreateConsLinear(
scip, &LPcon, LPcon_name, 0, 0, 0, LPlhs, SCIPinfinity(
scip), TRUE, TRUE,
666 TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE));
668 SCIP_CALL( SCIPaddCons(
scip, LPcon) );
671 for (
unsigned int var_i = 0; var_i < LPData.
rows[row_i].data.size(); ++var_i)
673 if (LPData.
rows[row_i].data[var_i].first != 0)
675 SCIP_CALL( SCIPaddCoefLinear(
scip, LPcon, VariablesX[LPData.
rows[row_i].data[var_i].first - 1], LPData.
rows[row_i].data[var_i].second) );
678 #ifdef SCIP_MORE_DEBUG 679 SCIP_CALL( SCIPprintCons(
scip, LPcon, NULL) );
681 SCIP_CALL( SCIPreleaseCons(
scip, &LPcon) );
687 *result = SCIP_SUCCESS;
SCIP_DECL_READERREAD(ObjReaderSDPA::scip_read)
An STL allocator class using SCIP block memory.
An std::streambuf that uses SCIP I/O routines (suitable for reading)
std::vector< LProw > rows
static SCIP_RETCODE dropSpaceNewlineError(std::istream &line)
void drop_rest_line(std::istream &s)
Constraint handler for SDP-constraints.
static SCIP_RETCODE testDigit(std::istream *file)
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)
void drop_space(std::istream &line)
static void dropComments(std::istream *file)
static SCIP_RETCODE checkIndex(const char *indexname, int value, int lb, int ub)
static SCIP_RETCODE checkForLineEnd(std::istream &line)