57 #include "scip/cons_linear.h"
58 #include "scip/scip.h"
64 inline void drop_space(std::istream& line)
66 while(std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',')
73 inline void drop_rest_line (std::istream& s)
92 fst_col = (*file).peek();
93 while (fst_col ==
'"' || fst_col ==
'*')
95 drop_rest_line(*file);
96 fst_col = (*file).peek();
105 if ( line.peek() ==
'\n' )
107 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
110 while(std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',')
113 if ( line.peek() ==
'\n' )
115 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
126 if ( line.peek() ==
'\n' || line.peek() ==
'"' || line.peek() ==
'*' || line.peek() == EOF )
130 while(std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',')
133 if ( line.peek() ==
'\n' || line.peek() ==
'"' || line.peek() ==
'*' || line.peek() == EOF )
137 else if (std::isspace(line.peek()) || line.peek() ==
'(' || line.peek() ==
'{' || line.peek() ==
')' || line.peek() ==
'}' || line.peek() ==
',')
141 SCIPerrorMessage(
"Input File invalid, SDP/LP-block rows need to consist of five entries each, see data_format.txt\n");
154 if ( (! isdigit((*file).peek())) && (! ((*file).peek() ==
'-')) )
156 SCIPerrorMessage(
"Input File invalid, only numerals allowed in SDP/LP-block rows, see data_format.txt\n");
166 const char* indexname,
173 SCIPerrorMessage(
"In an SDP/LP-block-line %s index %d was larger than given number of %ss %d.\n", indexname, value, indexname, ub);
190 const char* filename,
194 *result = SCIP_DIDNOTRUN;
204 std::vector<int, BlockMemoryAllocator<int> > blockpattern =
206 std::vector<double> object;
207 std::vector<SDPBlock> blockstruct;
209 std::vector<bool> blockislp;
210 std::vector<int> intvars;
211 std::vector <int> lp_block_num;
212 std::vector <int> lp_block_size;
214 bool lp_block_already_done;
216 SCIP_FILE* scip_file = SCIPfopen(filename,
"r");
218 return SCIP_READERROR;
224 std::istream file(&scip_buffer);
227 SCIP_CALL( SCIPgetRealParam(scip,
"numerics/feastol", &feastol) );
230 return SCIP_READERROR;
238 drop_rest_line(file);
246 drop_rest_line(file);
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);
260 for (
int j = 0; j < numblocks; ++j)
263 file >> blockpattern[j];
264 if (blockpattern[j] > 0)
267 blockstruct.push_back(
SDPBlock(blockpattern[j]));
270 else if (blockpattern[j] < 0)
274 alllpblocksize += abs(blockpattern[j]);
277 lp_block_num[j] = numlpblocks;
278 lp_block_size[numlpblocks] = abs(blockpattern[j]);
282 printf(
"Blocklength 0 seems a bit odd, don't you think!\n");
285 assert(numblocks == numsdpblocks + numlpblocks);
287 drop_rest_line(file);
293 object = std::vector<double>(numvars, 0.0);
294 for (
int i = 0; i < numvars; ++i)
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);
308 LPData.
rows = std::vector<LProw>(alllpblocksize);
309 LPData.
numrows = alllpblocksize;
311 std::vector<int> for_indices;
312 std::string commentline;
317 if(file.peek() ==
'*')
319 std::getline(file, commentline);
320 if (commentline.find(
"*INT") == 0)
332 int var_index, block_index;
333 int row_index, col_index;
339 SCIP_CALL(
checkIndex(
"variable", var_index, numvars) );
344 SCIP_CALL(
checkIndex(
"block", block_index, numblocks) );
349 SCIP_CALL(
checkIndex(
"row", row_index, (blockislp[block_index - 1] ? LPData.
numrows : blockstruct[block_index - 1].blocksize)) );
354 SCIP_CALL(
checkIndex(
"column", col_index, (blockislp[block_index - 1] ? LPData.
numrows : blockstruct[block_index - 1].blocksize)) );
361 if (SCIPisEQ(scip, val, 0.0))
363 drop_rest_line(file);
369 if (!blockislp[block_index - 1])
371 if (row_index < col_index)
373 int save_row = row_index;
374 row_index = col_index;
375 col_index = save_row;
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++;
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++;
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 );
396 else if (blockislp[block_index - 1])
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 );
404 drop_rest_line(file);
410 intvars = std::vector<int>(numvars, 0);
412 while(file.peek() ==
'*')
418 intvars[index - 1] = 1;
419 SCIPdebugMessage(
"Variable %d is integer.\n", index - 1);
420 drop_rest_line(file);
429 SCIP_CALL( SCIPcreateProb(scip, filename, 0, 0, 0, 0, 0, 0, 0) );
435 std::vector<SCIP_VAR*> VariablesX ( numvars );
437 for (
int i = 0; i < numvars; ++i)
441 SCIPsnprintf(var_name, 255,
"X_%d", i);
446 SCIP_CALL( SCIPcreateVar(scip, &var, var_name, -SCIPinfinity(scip), SCIPinfinity(scip),
object[i], SCIP_VARTYPE_INTEGER, TRUE, FALSE, 0, 0, 0, 0, 0));
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));
454 SCIP_CALL( SCIPaddVar(scip, var) );
458 SCIP_CALL( SCIPreleaseVar(scip, &var) );
466 lp_block_already_done =
false;
467 for (
int bindex = 0; bindex < numblocks; ++bindex)
469 if (!blockislp[bindex])
480 SCIP_Real** valpointer;
492 SCIPdebugMessage(
"Begin construction of SDP constraint for block %d.\n", bindex);
494 blocksize = blockpattern[bindex];
495 nnonz = blockstruct[bindex].num_nonzeros;
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) );
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) );
513 SCIP_CALL(SCIPallocBlockMemoryArray(scip, &nvarnonz, numvars));
514 for (
int i = 0; i < numvars; i++)
518 for (k = 0; k < blockstruct[bindex].constnum_nonzeros; ++k)
520 if (blockstruct[bindex].constvalues[k] > feastol || blockstruct[bindex].constvalues[k] < -feastol)
522 constcol[ind] = blockstruct[bindex].constcolumns[k] - 1;
523 constrow[ind] = blockstruct[bindex].constrows[k] - 1;
524 constval[ind] = blockstruct[bindex].constvalues[k];
532 for (k = 0; k < nnonz; ++k)
534 if (blockstruct[bindex].values[k] > feastol || blockstruct[bindex].values[k] < -feastol)
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];
545 SCIPsortIntIntIntReal(varind, col, row, val, nnonz);
550 for (k = 0; k < numvars; k++)
553 firstindforvar = nextindaftervar;
554 while (nextindaftervar < nnonz && varind[nextindaftervar] == k)
562 vars[ind] = VariablesX[k];
563 colpointer[ind] = &col[firstindforvar];
564 rowpointer[ind] = &row[firstindforvar];
565 valpointer[ind] = &val[firstindforvar];
570 assert (nextindaftervar == nnonz);
573 SCIPfreeBlockMemoryArray(scip, &varind, blockstruct[bindex].num_nonzeros);
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) );
583 #ifdef SCIP_MORE_DEBUG
584 SCIP_CALL( SCIPprintCons(scip, sdpcon, NULL) );
587 SCIP_CALL( SCIPaddCons(scip, sdpcon) );
589 SCIP_CALL( SCIPreleaseCons(scip, &sdpcon) );
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);
604 SCIPdebugMessage(
"Construction of SDP constraint for block %d completed.\n", bindex);
609 if (!lp_block_already_done)
611 lp_block_already_done =
true;
612 SCIPdebugMessage(
"Begin construction of LP (block %d).\n", bindex);
614 for (
int row_i = 0; row_i < LPData.
numrows; ++row_i)
617 char LPcon_name[255];
618 SCIPsnprintf(LPcon_name, 255,
"LP-Con-%d", row_i);
623 for (
unsigned int var_i = 0; var_i < LPData.
rows[row_i].data.size(); ++var_i)
625 if (LPData.
rows[row_i].data[var_i].first == 0)
627 LPlhs = LPData.
rows[row_i].data[var_i].second;
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));
635 SCIP_CALL( SCIPaddCons(scip, LPcon) );
638 for (
unsigned int var_i = 0; var_i < LPData.
rows[row_i].data.size(); ++var_i)
640 if (LPData.
rows[row_i].data[var_i].first != 0)
642 SCIP_CALL( SCIPaddCoefLinear(scip, LPcon, VariablesX[LPData.
rows[row_i].data[var_i].first - 1], LPData.
rows[row_i].data[var_i].second) );
645 #ifdef SCIP_MORE_DEBUG
646 SCIP_CALL( SCIPprintCons(scip, LPcon, NULL) );
648 SCIP_CALL( SCIPreleaseCons(scip, &LPcon) );
654 *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)