57 #include "scip/cons_linear.h"
58 #include "scip/scip.h"
67 inline void drop_space(std::istream& line)
69 while(std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',')
76 inline void drop_rest_line (std::istream& s)
95 fst_col = (*file).peek();
96 while (fst_col ==
'"' || fst_col ==
'*')
98 drop_rest_line(*file);
99 fst_col = (*file).peek();
108 if ( line.peek() ==
'\n' )
110 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
113 while(std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',')
116 if ( line.peek() ==
'\n' )
118 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
129 if ( line.peek() ==
'\n' || line.peek() ==
'"' || line.peek() ==
'*' || line.peek() == EOF )
133 while(std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',')
136 if ( line.peek() ==
'\n' || line.peek() ==
'"' || line.peek() ==
'*' || line.peek() == EOF )
140 else if (std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',')
144 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
157 if ( (! isdigit((*file).peek())) && (! ((*file).peek() ==
'-')) )
159 SCIPerrorMessage(
"Input File invalid, only numerals allowed in SDP/LP-block rows, see data_format.txt\n");
169 const char* indexname,
176 SCIPerrorMessage(
"In an SDP/LP-block-line %s index %d was larger than given number of %ss %d.\n", indexname, value, indexname, ub);
193 const char* filename,
197 *result = SCIP_DIDNOTRUN;
210 std::vector<int, BlockMemoryAllocator<int> > blockpattern =
212 std::vector<SCIP_Real> object;
213 std::vector<SDPBlock> blockstruct;
215 std::vector<bool> blockislp;
216 std::vector<int> intvars;
217 std::vector <int> lp_block_num;
218 std::vector <int> lp_block_size;
220 bool lp_block_already_done;
222 SCIP_FILE* scip_file = SCIPfopen(filename,
"r");
224 return SCIP_READERROR;
230 std::istream file(&scip_buffer);
233 SCIP_CALL( SCIPgetRealParam(scip,
"numerics/feastol", &feastol) );
236 return SCIP_READERROR;
244 drop_rest_line(file);
252 drop_rest_line(file);
262 blockislp = std::vector<bool>(numblocks,
false);
263 lp_block_num = std::vector<int>(numblocks, 0);
264 lp_block_size = std::vector<int>(numblocks, 0);
266 for (
int j = 0; j < numblocks; ++j)
269 file >> blockpattern[j];
270 if (blockpattern[j] > 0)
273 blockstruct.push_back(
SDPBlock(blockpattern[j]));
276 else if (blockpattern[j] < 0)
280 alllpblocksize += abs(blockpattern[j]);
283 lp_block_num[j] = numlpblocks;
284 lp_block_size[numlpblocks - 1] = abs(blockpattern[j]);
288 printf(
"Blocklength 0 seems a bit odd, don't you think!\n");
291 assert(numblocks == numsdpblocks + numlpblocks);
293 drop_rest_line(file);
299 object = std::vector<SCIP_Real>(numvars, 0.0);
300 for (
int i = 0; i < numvars; ++i)
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);
314 LPData.
rows = std::vector<LProw>(alllpblocksize);
315 LPData.
numrows = alllpblocksize;
316 SCIPdebugMessage(
"Number of LP constraints: %d\n", alllpblocksize);
318 std::string commentline;
323 if(file.peek() ==
'*')
325 std::getline(file, commentline);
326 if (commentline.find(
"*INT") == 0)
338 int var_index, block_index;
339 int row_index, col_index;
345 SCIP_CALL(
checkIndex(
"variable", var_index, numvars) );
350 SCIP_CALL(
checkIndex(
"block", block_index, numblocks) );
355 SCIP_CALL(
checkIndex(
"row", row_index, (blockislp[block_index - 1] ? LPData.
numrows : blockstruct[block_index - 1].blocksize)) );
360 SCIP_CALL(
checkIndex(
"column", col_index, (blockislp[block_index - 1] ? LPData.
numrows : blockstruct[block_index - 1].blocksize)) );
367 if (SCIPisEQ(scip, val, 0.0))
369 drop_rest_line(file);
375 if (!blockislp[block_index - 1])
377 if (row_index < col_index)
379 int save_row = row_index;
380 row_index = col_index;
381 col_index = save_row;
386 blockstruct[block_index - 1].constcolumns.push_back(col_index);
387 blockstruct[block_index - 1].constrows.push_back(row_index);
388 blockstruct[block_index - 1].constvalues.push_back(val);
389 blockstruct[block_index - 1].constnum_nonzeros++;
393 blockstruct[block_index - 1].columns.push_back(col_index);
394 blockstruct[block_index - 1].rows.push_back(row_index);
395 blockstruct[block_index - 1].values.push_back(val);
396 blockstruct[block_index - 1].variables.push_back(var_index);
397 blockstruct[block_index - 1].num_nonzeros++;
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 );
402 else if (blockislp[block_index - 1])
404 assert(row_index == col_index);
405 if ( lp_block_num[block_index - 1] == 1 )
406 new_row_index = row_index - 1;
414 for ( b = 0; b < lp_block_num[block_index - 1] - 1; b++ )
415 rowoffset += lp_block_size[b];
417 new_row_index = rowoffset + row_index - 1;
419 LPData.
rows[new_row_index].data.push_back(std::make_pair(var_index, val));
420 SCIPdebugMessage(
"LP entry: row: %d, var: %d, val: %g\n", new_row_index, var_index,val );
423 drop_rest_line(file);
429 intvars = std::vector<int>(numvars, 0);
431 while(file.peek() ==
'*')
437 intvars[index - 1] = 1;
438 SCIPdebugMessage(
"Variable %d is integer.\n", index - 1);
439 drop_rest_line(file);
448 SCIP_CALL( SCIPcreateProb(scip, filename, 0, 0, 0, 0, 0, 0, 0) );
454 std::vector<SCIP_VAR*> VariablesX ( numvars );
456 for (
int i = 0; i < numvars; ++i)
459 char var_name[SCIP_MAXSTRLEN];
461 snprintfreturn = SCIPsnprintf(var_name, SCIP_MAXSTRLEN,
"X_%d", i);
462 assert( snprintfreturn < SCIP_MAXSTRLEN);
464 (void)SCIPsnprintf(var_name, SCIP_MAXSTRLEN,
"X_%d", i);
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 SCIPdebugMessage(
"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 (blockstruct[bindex].constvalues[k] > feastol || blockstruct[bindex].constvalues[k] < -feastol)
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 (blockstruct[bindex].values[k] > feastol || blockstruct[bindex].values[k] < -feastol)
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 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 SCIPdebugMessage(
"Construction of SDP constraint for block %d completed.\n", bindex);
638 if (!lp_block_already_done)
640 lp_block_already_done =
true;
641 SCIPdebugMessage(
"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 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;
657 for (
unsigned int var_i = 0; var_i < LPData.
rows[row_i].data.size(); ++var_i)
659 if (LPData.
rows[row_i].data[var_i].first == 0)
661 LPlhs = LPData.
rows[row_i].data[var_i].second;
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));
669 SCIP_CALL( SCIPaddCons(scip, LPcon) );
672 for (
unsigned int var_i = 0; var_i < LPData.
rows[row_i].data.size(); ++var_i)
674 if (LPData.
rows[row_i].data[var_i].first != 0)
676 SCIP_CALL( SCIPaddCoefLinear(scip, LPcon, VariablesX[LPData.
rows[row_i].data[var_i].first - 1], LPData.
rows[row_i].data[var_i].second) );
679 #ifdef SCIP_MORE_DEBUG
680 SCIP_CALL( SCIPprintCons(scip, LPcon, NULL) );
682 SCIP_CALL( SCIPreleaseCons(scip, &LPcon) );
688 *result = SCIP_SUCCESS;
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
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)
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)