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, got character '%c', but only numerals allowed in SDP/LP-block rows, see data_format.txt\n", (*file).peek());
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;
209 std::vector<int, BlockMemoryAllocator<int> > blockpattern =
211 std::vector<SCIP_Real> object;
212 std::vector<SDPBlock> blockstruct;
214 std::vector<bool> blockislp;
215 std::vector<int> intvars;
216 std::vector <int> lp_block_num;
217 std::vector <int> lp_block_size;
219 bool lp_block_already_done;
221 SCIP_FILE* scip_file = SCIPfopen(filename,
"r");
223 return SCIP_READERROR;
229 std::istream file(&scip_buffer);
232 return SCIP_READERROR;
240 drop_rest_line(file);
248 drop_rest_line(file);
258 blockislp = std::vector<bool>(numblocks,
false);
259 lp_block_num = std::vector<int>(numblocks, 0);
260 lp_block_size = std::vector<int>(numblocks, 0);
262 for (
int j = 0; j < numblocks; ++j)
265 file >> blockpattern[j];
266 if (blockpattern[j] > 0)
269 blockstruct.push_back(
SDPBlock(blockpattern[j]));
272 else if (blockpattern[j] < 0)
276 alllpblocksize += abs(blockpattern[j]);
279 lp_block_num[j] = numlpblocks;
280 lp_block_size[numlpblocks - 1] = abs(blockpattern[j]);
284 printf(
"Blocklength 0 seems a bit odd, don't you think!\n");
287 assert(numblocks == numsdpblocks + numlpblocks);
289 drop_rest_line(file);
295 object = std::vector<SCIP_Real>(numvars, 0.0);
296 for (
int i = 0; i < numvars; ++i)
302 SCIPdebugMessage(
"Number of variables: %d \n", numvars);
303 SCIPdebugMessage(
"Number of blocks: %d \n", numblocks);
304 SCIPdebugMessage(
"Number of SDP- and LP-cones: %d, %d \n", numsdpblocks, numlpblocks);
310 LPData.
rows = std::vector<LProw>(alllpblocksize);
311 LPData.
numrows = alllpblocksize;
312 SCIPdebugMessage(
"Number of LP constraints: %d\n", alllpblocksize);
314 std::string commentline;
319 if(file.peek() ==
'*')
321 std::getline(file, commentline);
322 if (commentline.find(
"*INT") == 0)
334 int var_index, block_index;
335 int row_index, col_index;
341 SCIP_CALL(
checkIndex(
"variable", var_index, numvars) );
346 SCIP_CALL(
checkIndex(
"block", block_index, numblocks) );
351 SCIP_CALL(
checkIndex(
"row", row_index, (blockislp[block_index - 1] ? LPData.
numrows : blockstruct[block_index - 1].blocksize)) );
356 SCIP_CALL(
checkIndex(
"column", col_index, (blockislp[block_index - 1] ? LPData.
numrows : blockstruct[block_index - 1].blocksize)) );
363 if (SCIPisEQ(scip, val, 0.0))
365 drop_rest_line(file);
371 if (!blockislp[block_index - 1])
373 if (row_index < col_index)
375 int save_row = row_index;
376 row_index = col_index;
377 col_index = save_row;
382 blockstruct[block_index - 1].constcolumns.push_back(col_index);
383 blockstruct[block_index - 1].constrows.push_back(row_index);
384 blockstruct[block_index - 1].constvalues.push_back(val);
385 blockstruct[block_index - 1].constnum_nonzeros++;
389 blockstruct[block_index - 1].columns.push_back(col_index);
390 blockstruct[block_index - 1].rows.push_back(row_index);
391 blockstruct[block_index - 1].values.push_back(val);
392 blockstruct[block_index - 1].variables.push_back(var_index);
393 blockstruct[block_index - 1].num_nonzeros++;
395 SCIPdebugMessage(
"SDP entry: block_index: %d, row: %d, col: %d, var: %d, val: %g\n", block_index, row_index, col_index, var_index,val );
398 else if (blockislp[block_index - 1])
400 assert(row_index == col_index);
401 if ( lp_block_num[block_index - 1] == 1 )
402 new_row_index = row_index - 1;
410 for ( 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 SCIPdebugMessage(
"LP entry: row: %d, var: %d, val: %g\n", new_row_index, var_index,val );
419 drop_rest_line(file);
425 intvars = std::vector<int>(numvars, 0);
427 while(file.peek() ==
'*')
433 intvars[index - 1] = 1;
434 SCIPdebugMessage(
"Variable %d is integer.\n", index - 1);
435 drop_rest_line(file);
444 SCIP_CALL( SCIPcreateProb(scip, filename, 0, 0, 0, 0, 0, 0, 0) );
450 std::vector<SCIP_VAR*> VariablesX ( numvars );
452 for (
int i = 0; i < numvars; ++i)
455 char var_name[SCIP_MAXSTRLEN];
457 snprintfreturn = SCIPsnprintf(var_name, SCIP_MAXSTRLEN,
"X_%d", i);
458 assert( snprintfreturn < SCIP_MAXSTRLEN);
460 (void)SCIPsnprintf(var_name, SCIP_MAXSTRLEN,
"X_%d", i);
466 SCIP_CALL( SCIPcreateVar(scip, &var, var_name, -SCIPinfinity(scip), SCIPinfinity(scip),
object[i], SCIP_VARTYPE_INTEGER, TRUE, FALSE, 0, 0, 0, 0, 0));
470 SCIP_CALL( SCIPcreateVar(scip, &var, var_name, -SCIPinfinity(scip), SCIPinfinity(scip),
object[i],
471 SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, 0, 0, 0, 0, 0));
474 SCIP_CALL( SCIPaddVar(scip, var) );
478 SCIP_CALL( SCIPreleaseVar(scip, &var) );
486 lp_block_already_done =
false;
487 for (
int bindex = 0; bindex < numblocks; ++bindex)
489 if (!blockislp[bindex])
500 SCIP_Real** valpointer;
512 SCIPdebugMessage(
"Begin construction of SDP constraint for block %d.\n", bindex);
514 blocksize = blockpattern[bindex];
515 nnonz = blockstruct[bindex].num_nonzeros;
519 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &varind, blockstruct[bindex].num_nonzeros) );
520 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &col, blockstruct[bindex].num_nonzeros) );
521 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &row, blockstruct[bindex].num_nonzeros) );
522 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &val, blockstruct[bindex].num_nonzeros) );
523 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &colpointer, numvars) );
524 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &rowpointer, numvars) );
525 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &valpointer, numvars) );
526 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &vars, numvars) );
528 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constcol, blockstruct[bindex].constnum_nonzeros) );
529 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constrow, blockstruct[bindex].constnum_nonzeros) );
530 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &constval, blockstruct[bindex].constnum_nonzeros) );
533 SCIP_CALL(SCIPallocBlockMemoryArray(scip, &nvarnonz, numvars));
534 for (
int i = 0; i < numvars; i++)
538 for (k = 0; k < blockstruct[bindex].constnum_nonzeros; ++k)
540 if ( ! SCIPisZero(scip, blockstruct[bindex].constvalues[k]) )
542 constcol[ind] = blockstruct[bindex].constcolumns[k] - 1;
543 constrow[ind] = blockstruct[bindex].constrows[k] - 1;
544 constval[ind] = blockstruct[bindex].constvalues[k];
552 for (k = 0; k < nnonz; ++k)
554 if ( ! SCIPisZero(scip, blockstruct[bindex].values[k]) )
556 varind[ind] = blockstruct[bindex].variables[k] - 1;
557 col[ind] = blockstruct[bindex].columns[k] - 1;
558 row[ind] = blockstruct[bindex].rows[k] - 1;
559 val[ind] = blockstruct[bindex].values[k];
565 SCIPsortIntIntIntReal(varind, col, row, val, nnonz);
570 for (k = 0; k < numvars; k++)
573 firstindforvar = nextindaftervar;
574 while (nextindaftervar < nnonz && varind[nextindaftervar] == k)
582 vars[ind] = VariablesX[k];
583 colpointer[ind] = &col[firstindforvar];
584 rowpointer[ind] = &row[firstindforvar];
585 valpointer[ind] = &val[firstindforvar];
590 assert (nextindaftervar == nnonz);
593 SCIPfreeBlockMemoryArray(scip, &varind, blockstruct[bindex].num_nonzeros);
598 char sdpcon_name[SCIP_MAXSTRLEN];
600 snprintfreturn = SCIPsnprintf(sdpcon_name, SCIP_MAXSTRLEN,
"SDP-Constraint-%d", bindex);
601 assert( snprintfreturn < SCIP_MAXSTRLEN);
603 (void) SCIPsnprintf(sdpcon_name, SCIP_MAXSTRLEN,
"SDP-Constraint-%d", bindex);
605 SCIP_CALL(
SCIPcreateConsSdp(scip, &sdpcon, sdpcon_name, nvars, nnonz, blocksize, nvarnonz, colpointer,
606 rowpointer, valpointer, vars, constnnonz, constcol, constrow, constval) );
608 #ifdef SCIP_MORE_DEBUG
609 SCIP_CALL( SCIPprintCons(scip, sdpcon, NULL) );
612 SCIP_CALL( SCIPaddCons(scip, sdpcon) );
614 SCIP_CALL( SCIPreleaseCons(scip, &sdpcon) );
617 SCIPfreeBlockMemoryArray(scip, &nvarnonz, numvars);
618 SCIPfreeBlockMemoryArray(scip, &constval, blockstruct[bindex].constnum_nonzeros);
619 SCIPfreeBlockMemoryArray(scip, &constrow, blockstruct[bindex].constnum_nonzeros);
620 SCIPfreeBlockMemoryArray(scip, &constcol, blockstruct[bindex].constnum_nonzeros);
621 SCIPfreeBlockMemoryArray(scip, &vars, numvars);
622 SCIPfreeBlockMemoryArray(scip, &valpointer, numvars);
623 SCIPfreeBlockMemoryArray(scip, &rowpointer, numvars);
624 SCIPfreeBlockMemoryArray(scip, &colpointer, numvars);
625 SCIPfreeBlockMemoryArray(scip, &val, blockstruct[bindex].num_nonzeros);
626 SCIPfreeBlockMemoryArray(scip, &row, blockstruct[bindex].num_nonzeros);
627 SCIPfreeBlockMemoryArray(scip, &col, blockstruct[bindex].num_nonzeros);
629 SCIPdebugMessage(
"Construction of SDP constraint for block %d completed.\n", bindex);
634 if (!lp_block_already_done)
636 lp_block_already_done =
true;
637 SCIPdebugMessage(
"Begin construction of LP (block %d).\n", bindex);
639 for (
int row_i = 0; row_i < LPData.
numrows; ++row_i)
642 char LPcon_name[SCIP_MAXSTRLEN];
644 snprintfreturn = SCIPsnprintf(LPcon_name, SCIP_MAXSTRLEN,
"LP-Con-%d", row_i);
645 assert( snprintfreturn < SCIP_MAXSTRLEN );
647 (void) SCIPsnprintf(LPcon_name, SCIP_MAXSTRLEN,
"LP-Con-%d", row_i);
651 SCIP_Real LPlhs = 0.0;
653 for (
unsigned int var_i = 0; var_i < LPData.
rows[row_i].data.size(); ++var_i)
655 if (LPData.
rows[row_i].data[var_i].first == 0)
657 LPlhs = LPData.
rows[row_i].data[var_i].second;
662 SCIP_CALL( SCIPcreateConsLinear(scip, &LPcon, LPcon_name, 0, 0, 0, LPlhs, SCIPinfinity(scip), TRUE, TRUE,
663 TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE));
665 SCIP_CALL( SCIPaddCons(scip, LPcon) );
668 for (
unsigned int var_i = 0; var_i < LPData.
rows[row_i].data.size(); ++var_i)
670 if (LPData.
rows[row_i].data[var_i].first != 0)
672 SCIP_CALL( SCIPaddCoefLinear(scip, LPcon, VariablesX[LPData.
rows[row_i].data[var_i].first - 1], LPData.
rows[row_i].data[var_i].second) );
675 #ifdef SCIP_MORE_DEBUG
676 SCIP_CALL( SCIPprintCons(scip, LPcon, NULL) );
678 SCIP_CALL( SCIPreleaseCons(scip, &LPcon) );
684 *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)