65 #include "scip/cons_linear.h" 66 #include "scip/cons_quadratic.h" 67 #include "scip/scip_cons.h" 68 #include "scip/scip.h" 78 #define CONSHDLR_NAME "SDP" 79 #define CONSHDLR_DESC "SDP constraints of the form \\sum_{j} A_j y_j - A_0 psd" 81 #define CONSHDLRRANK1_NAME "SDPrank1" 82 #define CONSHDLRRANK1_DESC "rank 1 SDP constraints" 84 #define CONSHDLR_SEPAPRIORITY +1000000 85 #define CONSHDLR_ENFOPRIORITY -2000000 86 #define CONSHDLR_CHECKPRIORITY -2000000 87 #define CONSHDLR_SEPAFREQ 1 88 #define CONSHDLR_EAGERFREQ 100 90 #define CONSHDLR_MAXPREROUNDS -1 91 #define CONSHDLR_DELAYSEPA FALSE 92 #define CONSHDLR_NEEDSCONS TRUE 94 #define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_FAST 95 #define PARSE_STARTSIZE 1 96 #define PARSE_SIZEFACTOR 10 97 #define DEFAULT_DIAGGEZEROCUTS TRUE 98 #define DEFAULT_DIAGZEROIMPLCUTS TRUE 99 #define DEFAULT_TWOMINORLINCONSS FALSE 100 #define DEFAULT_TWOMINORPRODCONSS FALSE 101 #define DEFAULT_QUADCONSRANK1 TRUE 102 #define DEFAULT_UPGRADQUADCONSS FALSE 103 #define DEFAULT_UPGRADEKEEPQUAD FALSE 104 #define DEFAULT_MAXNVARSQUADUPGD 1000 105 #define DEFAULT_RANK1APPROXHEUR FALSE 107 #define DEFAULT_NTHREADS 1 126 SCIP_Real maxrhsentry;
129 SCIP_Bool addedquadcons;
133 struct SCIP_ConshdlrData
136 SCIP_Bool diaggezerocuts;
139 SCIP_Bool diagzeroimplcuts;
140 SCIP_Bool twominorlinconss;
141 SCIP_Bool twominorprodconss;
142 SCIP_Bool quadconsrank1;
143 SCIP_Bool upgradquadconss;
144 SCIP_Bool upgradekeepquad;
145 int maxnvarsquadupgd;
146 SCIP_Bool triedlinearconss;
147 SCIP_Bool rank1approxheur;
152 SCIP_VAR** quadconsvars;
157 SCIP_CONSHDLRDATA* sdpconshdlrdata;
167 SCIP_Real* rowmatrix,
178 assert( rowmatrix != NULL );
179 assert( colmatrix != NULL );
181 for (i = 0; i < rows; ++i)
183 for (j = 0; j < cols; ++j)
185 act = rowmatrix[i*cols + j];
186 colmatrix[j*rows + i] = act;
204 assert( blocksize >= 0 );
205 assert( matrix != NULL );
206 assert( scale != NULL );
208 for (r = 0; r < blocksize; r++)
210 for (c = 0; c < blocksize; c++)
213 matrix[r * blocksize + c] *= scale[r];
233 assert( symMat != NULL );
234 assert( fullMat != NULL );
237 for (i = 0; i < size; i++)
239 for (j = 0; j <= i; j++)
242 fullMat[i*size + j] = symMat[ind];
243 fullMat[j*size + i] = symMat[ind];
262 SCIP_CONSDATA* consdata;
269 assert( cons != NULL );
270 assert( matrix != NULL );
272 consdata = SCIPconsGetData(cons);
273 nvars = consdata->nvars;
274 blocksize = consdata->blocksize;
277 for (i = 0; i < (blocksize * (blocksize + 1))/2; i++)
281 for (i = 0; i < nvars; i++)
283 yval = SCIPgetSolVal(
scip, y, consdata->vars[i]);
284 for (ind = 0; ind < consdata->nvarnonz[i]; ind++)
289 for (ind = 0; ind < consdata->constnnonz; ind++)
304 SCIP_CONSDATA* consdata;
305 SCIP_Real* matrix = NULL;
306 SCIP_Real* fullmatrix = NULL;
307 SCIP_Real eigenvalue;
309 SCIP_RESULT resultSDPtest;
314 SCIP_Real submatrix[4];
315 SCIP_Real largestminev = 0.0;
317 assert( cons != NULL );
318 assert( result != NULL );
320 consdata = SCIPconsGetData(cons);
321 assert( consdata != NULL );
323 blocksize = consdata->blocksize;
325 resultSDPtest = SCIP_INFEASIBLE;
329 if ( resultSDPtest == SCIP_INFEASIBLE )
331 SCIPerrorMessage(
"Try to check for a matrix to be rank 1 even if the matrix is not psd.\n");
336 SCIP_CALL( SCIPallocBufferArray(
scip, &matrix, (blocksize * (blocksize+1))/2 ) );
337 SCIP_CALL( SCIPallocBufferArray(
scip, &fullmatrix, blocksize * blocksize ) );
353 if ( SCIPisFeasEQ(
scip, 0.1*eigenvalue, 0.0) )
360 for (i = 0; i < blocksize; ++i)
362 for (j = 0; j < i; ++j)
372 if ( eigenvalue > largestminev )
374 largestminev = eigenvalue;
381 assert( ind1 > 0 || ind2 > 0 );
382 assert( SCIPisFeasPositive(
scip, largestminev) );
385 consdata->maxevsubmat[0] = ind1;
386 consdata->maxevsubmat[1] = ind2;
389 SCIPfreeBufferArray(
scip, &fullmatrix);
390 SCIPfreeBufferArray(
scip, &matrix);
404 SCIP_CONSDATA* consdata;
407 assert( cons != NULL );
409 assert( vAv != NULL );
411 consdata = SCIPconsGetData(cons);
412 assert( consdata != NULL );
414 assert( j < consdata->nvars );
419 for (i = 0; i < consdata->nvarnonz[j]; i++)
421 if (consdata->col[j][i] == consdata->row[j][i])
422 *vAv += v[consdata->col[j][i]] * consdata->val[j][i] * v[consdata->row[j][i]];
426 *vAv += 2.0 * v[consdata->col[j][i]] * consdata->val[j][i] * v[consdata->row[j][i]];
441 SCIP_CONSDATA* consdata;
445 consdata = SCIPconsGetData(cons);
446 assert( consdata != NULL );
452 for (i = 0; i < consdata->constnnonz; i++)
454 if ( REALABS(consdata->constval[i]) > max )
455 max = REALABS(consdata->constval[i]);
458 consdata->maxrhsentry = max;
478 SCIP_CONSDATA* consdata;
479 SCIP_Real* eigenvalues = NULL;
480 SCIP_Real* matrix = NULL;
481 SCIP_Real* fullmatrix = NULL;
482 SCIP_Real* fullconstmatrix = NULL;
483 SCIP_Real* eigenvector = NULL;
484 SCIP_Real* output_vector = NULL;
488 assert( cons != NULL );
489 assert( lhs != NULL );
493 consdata = SCIPconsGetData(cons);
494 assert( consdata != NULL );
496 blocksize = consdata->blocksize;
498 SCIP_CALL( SCIPallocBufferArray(
scip, &eigenvalues, blocksize) );
499 SCIP_CALL( SCIPallocBufferArray(
scip, &matrix, (blocksize * (blocksize+1))/2 ) );
500 SCIP_CALL( SCIPallocBufferArray(
scip, &fullmatrix, blocksize * blocksize ) );
501 SCIP_CALL( SCIPallocBufferArray(
scip, &fullconstmatrix, blocksize * blocksize) );
502 SCIP_CALL( SCIPallocBufferArray(
scip, &eigenvector, blocksize) );
503 SCIP_CALL( SCIPallocBufferArray(
scip, &output_vector, blocksize) );
519 for (j = 0; j < blocksize; ++j)
520 *lhs += eigenvector[j] * output_vector[j];
523 for (j = 0; j < consdata->nvars; ++j)
528 SCIPfreeBufferArray(
scip, &output_vector);
529 SCIPfreeBufferArray(
scip, &eigenvector);
530 SCIPfreeBufferArray(
scip, &fullconstmatrix);
531 SCIPfreeBufferArray(
scip, &fullmatrix);
532 SCIPfreeBufferArray(
scip, &matrix);
533 SCIPfreeBufferArray(
scip, &eigenvalues);
543 SCIP_Bool printreason,
547 SCIP_CONSDATA* consdata;
549 SCIP_Real check_value;
550 SCIP_Real eigenvalue;
551 SCIP_Real* matrix = NULL;
552 SCIP_Real* fullmatrix = NULL;
554 assert(
scip != NULL );
555 assert( cons != NULL );
556 assert( result != NULL );
558 consdata = SCIPconsGetData(cons);
559 assert( consdata != NULL );
560 assert( consdata->rankone || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)),
CONSHDLR_NAME) == 0 );
561 assert( ! consdata->rankone || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)),
CONSHDLRRANK1_NAME) == 0 );
562 blocksize = consdata->blocksize;
564 SCIP_CALL( SCIPallocBufferArray(
scip, &matrix, (blocksize * (blocksize+1)) / 2) );
565 SCIP_CALL( SCIPallocBufferArray(
scip, &fullmatrix, blocksize * blocksize) );
574 check_value = (-eigenvalue) / (1.0 + consdata->maxrhsentry);
576 check_value = -eigenvalue;
579 if ( SCIPisFeasLE(
scip, check_value, 0.0) )
580 *result = SCIP_FEASIBLE;
583 *result = SCIP_INFEASIBLE;
586 SCIPinfoMessage(
scip, NULL,
"SDP-constraint <%s> violated: non psd matrix (eigenvalue %f, dimacs error norm = %f).\n", SCIPconsGetName(cons), eigenvalue, check_value);
587 SCIP_CALL( SCIPprintCons(
scip, cons, NULL) );
592 SCIPupdateSolConsViolation(
scip, sol, -eigenvalue, (-eigenvalue) / (1.0 + consdata->maxrhsentry));
594 SCIPfreeBufferArray(
scip, &fullmatrix);
595 SCIPfreeBufferArray(
scip, &matrix);
604 SCIP_CONSHDLR* conshdlr,
610 char cutname[SCIP_MAXSTRLEN];
611 SCIP_CONSDATA* consdata;
612 SCIP_CONSHDLRDATA* conshdlrdata;
614 SCIP_Real* coeff = NULL;
625 assert( cons != NULL );
627 consdata = SCIPconsGetData(cons);
628 assert( consdata != NULL );
630 nvars = consdata->nvars;
631 SCIP_CALL( SCIPallocBufferArray(
scip, &coeff, nvars ) );
635 SCIP_CALL( SCIPallocBufferArray(
scip, &cols, nvars ) );
636 SCIP_CALL( SCIPallocBufferArray(
scip, &vals, nvars ) );
639 for (j = 0; j < nvars; ++j)
641 if ( SCIPisZero(
scip, coeff[j]) )
644 cols[len] = SCIPvarGetCol(SCIPvarGetProbvar(consdata->vars[j]));
645 vals[len] = coeff[j];
649 conshdlrdata = SCIPconshdlrGetData(conshdlr);
650 assert( conshdlrdata != NULL );
653 snprintfreturn = SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"sepa_eig_sdp_%d", ++(conshdlrdata->neigveccuts));
654 assert( snprintfreturn < SCIP_MAXSTRLEN );
656 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"sepa_eig_sdp_%d", ++(conshdlrdata->neigveccuts));
659 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) ) 660 SCIP_CALL( SCIPcreateRowConshdlr(
scip, &row, conshdlr, cutname , len, cols, vals, lhs, SCIPinfinity(
scip), FALSE, FALSE, TRUE) );
662 SCIP_CALL( SCIPcreateRowCons(
scip, &row, conshdlr, cutname , len, cols, vals, lhs, SCIPinfinity(
scip), FALSE, FALSE, TRUE) );
665 if ( SCIPisCutEfficacious(
scip, sol, row) )
667 SCIP_Bool infeasible;
668 #ifdef SCIP_MORE_DEBUG 669 SCIPinfoMessage(
scip, NULL,
"Added cut %s: ", cutname);
670 SCIPinfoMessage(
scip, NULL,
"%f <= ", lhs);
671 for (j = 0; j < len; j++)
672 SCIPinfoMessage(
scip, NULL,
"+ (%f)*%s", vals[j], SCIPvarGetName(SCIPcolGetVar(cols[j])));
673 SCIPinfoMessage(
scip, NULL,
"\n");
676 SCIP_CALL( SCIPaddRow(
scip, row, FALSE, &infeasible) );
678 *result = SCIP_CUTOFF;
680 *result = SCIP_SEPARATED;
681 SCIP_CALL( SCIPresetConsAge(
scip, cons) );
684 SCIP_CALL( SCIPreleaseRow(
scip, &row) );
686 SCIPfreeBufferArray(
scip, &vals);
687 SCIPfreeBufferArray(
scip, &cols);
688 SCIPfreeBufferArray(
scip, &coeff);
699 SCIP_CONSHDLR* conshdlr,
707 char cutname[SCIP_MAXSTRLEN];
708 SCIP_CONSHDLRDATA* conshdlrdata;
709 SCIP_CONSDATA* consdata;
713 SCIP_Real* diagentries;
721 assert(
scip != NULL );
722 assert( naddconss != NULL );
723 assert( nchgbds != NULL );
724 assert( result != NULL );
725 assert( *result != SCIP_CUTOFF );
727 conshdlrdata = SCIPconshdlrGetData(conshdlr);
728 assert( conshdlrdata != NULL );
730 for (c = 0; c < nconss; ++c)
732 consdata = SCIPconsGetData(conss[c]);
733 assert( consdata != NULL );
734 assert( consdata->rankone || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])),
CONSHDLR_NAME) == 0 );
735 assert( ! consdata->rankone || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])),
CONSHDLRRANK1_NAME) == 0 );
737 blocksize = consdata->blocksize;
738 nvars = consdata->nvars;
740 SCIP_CALL( SCIPallocBufferArray(
scip, &consvars, nvars) );
741 SCIP_CALL( SCIPallocBufferArray(
scip, &consvals, nvars) );
743 SCIP_CALL( SCIPallocBufferArray(
scip, &matrix, (blocksize * (blocksize + 1)) / 2) );
747 SCIP_CALL( SCIPallocClearBufferArray(
scip, &diagentries, blocksize * nvars) );
750 for (j = 0; j < nvars; ++j)
753 for (i = 0; i < consdata->nvarnonz[j]; i++)
755 if ( consdata->col[j][i] == consdata->row[j][i] )
756 diagentries[consdata->col[j][i] * nvars + j] = consdata->val[j][i];
761 for (k = 0; k < blocksize && *result != SCIP_CUTOFF; ++k)
765 SCIP_Real activitylb = 0.0;
768 for ( j = 0; j < nvars; ++j)
773 val = diagentries[k * nvars + j];
774 if ( ! SCIPisZero(
scip, val) )
776 var = consdata->vars[j];
778 consvars[cnt++] = var;
781 activitylb += val * SCIPvarGetLbGlobal(var);
783 activitylb += val * SCIPvarGetUbGlobal(var);
793 if ( SCIPisPositive(
scip, lhs) )
794 *result = SCIP_CUTOFF;
798 SCIP_Bool infeasible = FALSE;
805 assert( var != NULL );
808 if ( SCIPisPositive(
scip, val) )
810 SCIP_CALL( SCIPtightenVarLb(
scip, var, lhs / val, FALSE, &infeasible, &tightened) );
813 SCIPdebugMsg(
scip,
"Tightend lower bound of <%s> to %g because of diagonal values of SDP-constraint %s!\n",
814 SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPconsGetName(conss[c]));
818 else if ( SCIPisNegative(
scip, val) )
820 SCIP_CALL( SCIPtightenVarUb(
scip, var, lhs / val, FALSE, &infeasible, &tightened) );
823 SCIPdebugMsg(
scip,
"Tightend upper bound of <%s> to %g because of diagonal values of SDP-constraint %s!\n",
824 SCIPvarGetName(var), SCIPvarGetUbGlobal(var), SCIPconsGetName(conss[c]));
830 *result = SCIP_CUTOFF;
833 else if ( SCIPisLT(
scip, activitylb, lhs) )
835 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"diag_ge_zero_%d", ++(conshdlrdata->ndiaggezerocuts));
837 SCIP_CALL( SCIPcreateConsLinear(
scip, &cons, cutname, cnt, consvars, consvals, lhs, SCIPinfinity(
scip),
838 TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE) );
840 SCIP_CALL( SCIPaddCons(
scip, cons) );
841 #ifdef SCIP_MORE_DEBUG 842 SCIPinfoMessage(
scip, NULL,
"Added diagonal lp-constraint: ");
843 SCIP_CALL( SCIPprintCons(
scip, cons, NULL) );
844 SCIPinfoMessage(
scip, NULL,
"\n");
846 SCIP_CALL( SCIPreleaseCons(
scip, &cons) );
851 SCIPfreeBufferArray(
scip, &diagentries);
852 SCIPfreeBufferArray(
scip, &matrix);
853 SCIPfreeBufferArray(
scip, &consvals);
854 SCIPfreeBufferArray(
scip, &consvars);
875 char cutname[SCIP_MAXSTRLEN];
880 int* nconstnonzeroentries;
881 int** constnonzeroentries;
882 SCIP_CONSDATA* consdata;
895 SCIP_Bool anycutvalid;
900 assert(
scip != NULL );
901 assert( naddconss != NULL );
903 for (i = 0; i < nconss; ++i)
905 assert( conss[i] != NULL );
906 consdata = SCIPconsGetData(conss[i]);
907 assert( consdata != NULL );
909 blocksize = consdata->blocksize;
910 nvars = consdata->nvars;
911 SCIP_CALL( SCIPallocBufferArray(
scip, &nconstnonzeroentries, blocksize) );
912 SCIP_CALL( SCIPallocBufferArray(
scip, &constnonzeroentries, blocksize) );
913 for (j = 0; j < blocksize; j++)
915 nconstnonzeroentries[j] = 0;
916 SCIP_CALL( SCIPallocBufferArray(
scip, &constnonzeroentries[j], blocksize) );
920 for (j = 0; j < consdata->constnnonz; j++)
924 if ( (consdata->constcol[j] != consdata->constrow[j]) )
926 assert( ! SCIPisZero(
scip, consdata->constval[j]) );
927 if ( nconstnonzeroentries[consdata->constcol[j]] >= 0 )
929 constnonzeroentries[consdata->constcol[j]][nconstnonzeroentries[consdata->constcol[j]]] = consdata->constrow[j];
930 nconstnonzeroentries[consdata->constcol[j]]++;
933 if ( nconstnonzeroentries[consdata->constrow[j]] >= 0 )
935 constnonzeroentries[consdata->constrow[j]][nconstnonzeroentries[consdata->constrow[j]]] = consdata->constcol[j];
936 nconstnonzeroentries[consdata->constrow[j]]++;
942 assert( ! SCIPisZero(
scip, consdata->constval[j]) );
943 nconstnonzeroentries[consdata->constcol[j]] = -1;
949 SCIP_CALL( SCIPallocBufferArray(
scip, &diagvars, blocksize) );
950 SCIP_CALL( SCIPallocBufferArray(
scip, &ndiagvars, blocksize) );
952 for (j = 0; j < blocksize; ++j)
955 if ( nconstnonzeroentries[j] > 0 )
957 SCIP_CALL( SCIPallocBufferArray(
scip, &(diagvars[j]), nvars) );
965 SCIPfreeBufferArray(
scip, &ndiagvars);
966 SCIPfreeBufferArray(
scip, &diagvars);
967 for (j = blocksize - 1; j >= 0; j--)
969 SCIPfreeBufferArray(
scip, &constnonzeroentries[j]);
971 SCIPfreeBufferArray(
scip, &constnonzeroentries);
972 SCIPfreeBufferArray(
scip, &nconstnonzeroentries);
978 for (v = 0; v < nvars; v++)
980 for (j = 0; j < consdata->nvarnonz[v]; j++)
984 if ( (consdata->col[v][j] == consdata->row[v][j]) && (nconstnonzeroentries[consdata->col[v][j]] > 0) )
986 if ( SCIPvarIsIntegral(consdata->vars[v]) )
988 assert( ! SCIPisEQ(
scip, consdata->val[v][j], 0.0) );
989 diagvars[consdata->col[v][j]][ndiagvars[consdata->col[v][j]]] = v;
990 ndiagvars[consdata->col[v][j]]++;
994 nconstnonzeroentries[consdata->col[v][j]] = -2;
999 else if ( consdata->col[v][j] != consdata->row[v][j] )
1001 if ( nconstnonzeroentries[consdata->col[v][j]] > 0 )
1004 for (k = 0; k < nconstnonzeroentries[consdata->col[v][j]]; k++)
1006 if ( constnonzeroentries[consdata->col[v][j]][k] == consdata->row[v][j] )
1009 if ( nconstnonzeroentries[consdata->col[v][j]] > k + 1 )
1011 for (l = k + 1; l < nconstnonzeroentries[consdata->col[v][j]]; l++)
1012 constnonzeroentries[consdata->col[v][j]][l - 1] = constnonzeroentries[consdata->col[v][j]][l];
1014 nconstnonzeroentries[consdata->col[v][j]]--;
1016 if ( nconstnonzeroentries[consdata->col[v][j]] == 0 )
1017 nconstnonzeroentries[consdata->col[v][j]] = -2;
1023 if ( nconstnonzeroentries[consdata->row[v][j]] > 0 )
1026 for (k = 0; k < nconstnonzeroentries[consdata->row[v][j]]; k++)
1028 if ( constnonzeroentries[consdata->row[v][j]][k] == consdata->col[v][j] )
1031 if ( nconstnonzeroentries[consdata->row[v][j]] > k + 1 )
1033 for (l = k + 1; l < nconstnonzeroentries[consdata->row[v][j]]; l++)
1034 constnonzeroentries[consdata->row[v][j]][l - 1] = constnonzeroentries[consdata->row[v][j]][l];
1036 nconstnonzeroentries[consdata->row[v][j]]--;
1038 if ( nconstnonzeroentries[consdata->row[v][j]] == 0 )
1039 nconstnonzeroentries[consdata->row[v][j]] = -2;
1048 for (j = 0; j < blocksize; ++j)
1050 if ( nconstnonzeroentries[j] > 0 )
1052 SCIP_CALL( SCIPallocBufferArray(
scip, &vals, ndiagvars[j]) );
1053 SCIP_CALL( SCIPallocBufferArray(
scip, &vars, ndiagvars[j]) );
1056 for (v = 0; v < ndiagvars[j]; ++v)
1058 vars[v] = consdata->vars[diagvars[j][v]];
1062 snprintfreturn = SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"diag_zero_impl_block_%d_row_%d", i, j);
1063 assert( snprintfreturn < SCIP_MAXSTRLEN );
1065 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"diag_zero_impl_block_%d_row_%d", i, j);
1069 SCIP_CALL( SCIPcreateConsLinear(
scip, &cons, cutname, ndiagvars[j], vars, vals, 1.0, SCIPinfinity(
scip), TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE) );
1070 SCIP_CALL( SCIPaddCons(
scip, cons) );
1071 #ifdef SCIP_MORE_DEBUG 1072 SCIPinfoMessage(
scip, NULL,
"Added lp-constraint: ");
1073 SCIP_CALL( SCIPprintCons(
scip, cons, NULL) );
1074 SCIPinfoMessage(
scip, NULL,
"\n");
1076 SCIP_CALL( SCIPreleaseCons(
scip, &cons) );
1079 SCIPfreeBufferArray(
scip, &vars);
1080 SCIPfreeBufferArray(
scip, &vals);
1082 if ( nconstnonzeroentries[j] == -2 || nconstnonzeroentries[j] > 0 )
1084 SCIPfreeBufferArray(
scip, &diagvars[j]);
1088 SCIPfreeBufferArray(
scip, &ndiagvars);
1089 SCIPfreeBufferArray(
scip, &diagvars);
1090 for (j = blocksize - 1; j >= 0; j--)
1092 SCIPfreeBufferArray(
scip, &constnonzeroentries[j]);
1094 SCIPfreeBufferArray(
scip, &constnonzeroentries);
1095 SCIPfreeBufferArray(
scip, &nconstnonzeroentries);
1123 char name[SCIP_MAXSTRLEN];
1124 SCIP_VAR** consvars;
1125 SCIP_Real* consvals;
1131 assert(
scip != NULL );
1132 assert( naddconss != NULL );
1134 for (c = 0; c < nconss; ++c)
1136 SCIP_CONSDATA* consdata;
1137 SCIP_Real** matrices = NULL;
1138 SCIP_Real* constmatrix;
1143 assert( conss[c] != NULL );
1144 consdata = SCIPconsGetData(conss[c]);
1145 assert( consdata != NULL );
1147 blocksize = consdata->blocksize;
1148 nvars = consdata->nvars;
1150 SCIP_CALL( SCIPallocBufferArray(
scip, &consvars, nvars) );
1151 SCIP_CALL( SCIPallocBufferArray(
scip, &consvals, nvars) );
1152 SCIP_CALL( SCIPallocBufferArray(
scip, &coef, nvars) );
1155 SCIP_CALL( SCIPallocBufferArray(
scip, &constmatrix, blocksize * blocksize) );
1158 SCIP_CALL( SCIPallocBufferArray(
scip, &matrices, nvars) );
1159 for (i = 0; i < nvars; ++i)
1161 SCIP_CALL( SCIPallocBufferArray(
scip, &matrices[i], blocksize * blocksize) );
1166 for (s = 0; s < blocksize; ++s)
1168 for (t = 0; t < s; ++t)
1173 SCIP_Real activitylb = 0.0;
1182 BMSclearMemoryArray(coef, nvars);
1183 for (i = 0; i < nvars; ++i)
1185 val = matrices[i][s * blocksize + t];
1186 if ( ! SCIPisZero(
scip, val) )
1188 coef[i] = -2.0 * val;
1198 for (i = 0; i < nvars; ++i)
1200 val = matrices[i][s * blocksize + s];
1201 if ( ! SCIPisZero(
scip, val) )
1206 for (i = 0; i < nvars; ++i)
1208 val = matrices[i][t * blocksize + t];
1209 if ( ! SCIPisZero(
scip, val) )
1214 for (i = 0; i < nvars; ++i)
1216 if ( ! SCIPisZero(
scip, coef[i]) )
1218 consvals[nconsvars] = coef[i];
1219 consvars[nconsvars] = consdata->vars[i];
1224 activitylb += coef[i] * SCIPvarGetLbGlobal(consdata->vars[i]);
1226 activitylb += coef[i] * SCIPvarGetUbGlobal(consdata->vars[i]);
1231 if ( nconsvars <= 0 )
1235 lhs = constmatrix[s * blocksize + s] + constmatrix[t * blocksize + t] - 2.0 * constmatrix[s * blocksize + t];
1238 if ( SCIPisGE(
scip, activitylb, lhs) )
1242 (void) SCIPsnprintf(
name, SCIP_MAXSTRLEN,
"2x2minorlin#%d#%d", s, t);
1243 SCIP_CALL( SCIPcreateConsLinear(
scip, &cons,
name, nconsvars, consvars, consvals, lhs, SCIPinfinity(
scip),
1244 TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE) );
1245 SCIP_CALL( SCIPaddCons(
scip, cons) );
1246 #ifdef SCIP_MORE_DEBUG 1247 SCIPinfoMessage(
scip, NULL,
"Added 2x2 minor linear constraint: ");
1248 SCIP_CALL( SCIPprintCons(
scip, cons, NULL) );
1249 SCIPinfoMessage(
scip, NULL,
"\n");
1251 SCIP_CALL( SCIPreleaseCons(
scip, &cons) );
1256 for (i = 0; i < nvars; ++i)
1257 SCIPfreeBufferArray(
scip, &matrices[i]);
1258 SCIPfreeBufferArray(
scip, &matrices);
1259 SCIPfreeBufferArray(
scip, &constmatrix);
1260 SCIPfreeBufferArray(
scip, &coef);
1261 SCIPfreeBufferArray(
scip, &consvals);
1262 SCIPfreeBufferArray(
scip, &consvars);
1281 char name[SCIP_MAXSTRLEN];
1282 SCIP_VAR** consvars;
1283 SCIP_Real* consvals;
1290 assert(
scip != NULL );
1291 assert( naddconss != NULL );
1293 for (c = 0; c < nconss; ++c)
1295 SCIP_CONSDATA* consdata;
1296 SCIP_Real** matrices = NULL;
1297 SCIP_Real* constmatrix;
1299 assert( conss[c] != NULL );
1300 consdata = SCIPconsGetData(conss[c]);
1301 assert( consdata != NULL );
1303 blocksize = consdata->blocksize;
1304 nvars = consdata->nvars;
1306 SCIP_CALL( SCIPallocBufferArray(
scip, &consvars, nvars) );
1307 SCIP_CALL( SCIPallocBufferArray(
scip, &consvals, nvars) );
1309 SCIP_CALL( SCIPallocBufferArray(
scip, &constmatrix, blocksize * blocksize) );
1313 for (j = 0; j < consdata->constnnonz; ++j)
1320 s = consdata->constrow[j];
1321 t = consdata->constcol[j];
1328 if ( matrices == NULL )
1330 SCIP_CALL( SCIPallocBufferArray(
scip, &matrices, nvars) );
1331 for (i = 0; i < nvars; ++i)
1333 SCIP_CALL( SCIPallocBufferArray(
scip, &matrices[i], blocksize * blocksize) );
1337 assert( matrices != NULL );
1340 for (i = 0; i < nvars; ++i)
1342 if ( ! SCIPisZero(
scip, matrices[i][s * blocksize + s]) )
1344 if ( ! SCIPisZero(
scip, matrices[i][t * blocksize + t]) )
1351 prod = constmatrix[s * blocksize + s] * constmatrix[t * blocksize + t];
1352 if ( SCIPisEfficacious(
scip, prod) )
1355 SCIP_Real activitylb = 0.0;
1360 for (i = 0; i < nvars; ++i)
1362 val = matrices[i][s * blocksize + t];
1363 if ( ! SCIPisZero(
scip, val) )
1365 consvals[nconsvars] = val;
1366 consvars[nconsvars] = consdata->vars[i];
1371 activitylb += val * SCIPvarGetLbGlobal(consdata->vars[i]);
1373 activitylb += val * SCIPvarGetUbGlobal(consdata->vars[i]);
1377 lhs = consdata->constval[j] - sqrt(prod);
1380 if ( SCIPisGE(
scip, activitylb, lhs) )
1384 (void) SCIPsnprintf(
name, SCIP_MAXSTRLEN,
"2x2minorprod#%d#%d", s, t);
1385 SCIP_CALL( SCIPcreateConsLinear(
scip, &cons,
name, nconsvars, consvars, consvals, lhs, SCIPinfinity(
scip),
1386 TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE) );
1387 SCIP_CALL( SCIPaddCons(
scip, cons) );
1388 #ifdef SCIP_MORE_DEBUG 1389 SCIPinfoMessage(
scip, NULL,
"Added 2x2 minor product constraint: ");
1390 SCIP_CALL( SCIPprintCons(
scip, cons, NULL) );
1391 SCIPinfoMessage(
scip, NULL,
"\n");
1393 SCIP_CALL( SCIPreleaseCons(
scip, &cons) );
1398 if ( matrices != NULL )
1400 for (i = 0; i < nvars; ++i)
1401 SCIPfreeBufferArray(
scip, &matrices[i]);
1402 SCIPfreeBufferArray(
scip, &matrices);
1404 SCIPfreeBufferArray(
scip, &constmatrix);
1405 SCIPfreeBufferArray(
scip, &consvals);
1406 SCIPfreeBufferArray(
scip, &consvars);
1416 SCIP_CONSHDLR* conshdlr,
1425 char cutname[SCIP_MAXSTRLEN];
1426 SCIP_CONSDATA* consdata;
1427 SCIP_CONSHDLRDATA* conshdlrdata;
1441 assert(
scip != NULL );
1442 assert( conshdlr != NULL );
1444 assert( result != NULL );
1446 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1447 assert( conshdlrdata != NULL );
1449 for (i = 0; i < nconss && *result != SCIP_CUTOFF; ++i)
1451 consdata = SCIPconsGetData(conss[i]);
1452 assert( consdata != NULL );
1455 if ( consdata->blocksize == 1 )
1459 nvars = consdata->nvars;
1460 nnonz = consdata->nnonz;
1461 SCIP_CALL( SCIPallocBufferArray(
scip, &vars, nvars) );
1462 SCIP_CALL( SCIPallocBufferArray(
scip, &coeffs, nnonz) );
1465 for (v = 0; v < nvars; v++)
1467 assert( consdata->nvarnonz[v] <= 1 );
1469 for (j = 0; j < consdata->nvarnonz[v]; j++)
1471 assert( consdata->col[v][j] == 0 && consdata->row[v][j] == 0 );
1472 if ( ! SCIPisZero(
scip, consdata->val[v][j]) )
1474 coeffs[cnt] = consdata->val[v][j];
1475 vars[cnt] = consdata->vars[v];
1482 assert( consdata->constnnonz <= 1 );
1484 rhs = (consdata->constnnonz == 1) ? consdata->constval[0] : 0.0;
1491 snprintfreturn = SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"1x1block_%d", ++(conshdlrdata->n1x1blocks));
1492 assert( snprintfreturn < SCIP_MAXSTRLEN );
1494 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"1x1block_%d", ++(conshdlrdata->n1x1blocks));
1497 SCIP_CALL( SCIPcreateConsLinear(
scip, &cons, cutname, cnt, vars, coeffs, rhs, SCIPinfinity(
scip),
1498 TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE) );
1500 SCIP_CALL( SCIPaddCons(
scip, cons) );
1501 #ifdef SCIP_MORE_DEBUG 1502 SCIPinfoMessage(
scip, NULL,
"Added lp-constraint: ");
1503 SCIP_CALL( SCIPprintCons(
scip, cons, NULL) );
1504 SCIPinfoMessage(
scip, NULL,
"\n");
1506 SCIP_CALL( SCIPreleaseCons(
scip, &cons) );
1510 else if ( cnt == 1 )
1512 SCIP_Bool infeasible = FALSE;
1513 SCIP_Bool tightened;
1516 if ( SCIPisPositive(
scip, coeffs[0]) )
1518 SCIP_CALL( SCIPtightenVarLb(
scip, vars[0], rhs / coeffs[0], FALSE, &infeasible, &tightened) );
1521 SCIPdebugMsg(
scip,
"Tightend lower bound of <%s> to %g because of diagonal values of SDP-constraint %s!\n",
1522 SCIPvarGetName(vars[0]), SCIPvarGetLbGlobal(vars[0]), SCIPconsGetName(conss[i]));
1528 assert( SCIPisNegative(
scip, coeffs[0]) );
1529 SCIP_CALL( SCIPtightenVarUb(
scip, vars[0], rhs / coeffs[0], FALSE, &infeasible, &tightened) );
1532 SCIPdebugMsg(
scip,
"Tightend upper bound of <%s> to %g because of diagonal values of SDP-constraint %s!\n",
1533 SCIPvarGetName(vars[0]), SCIPvarGetUbGlobal(vars[0]), SCIPconsGetName(conss[i]));
1539 *result = SCIP_CUTOFF;
1544 SCIPdebugMsg(
scip,
"Detected 1x1 SDP-block without any nonzero coefficients \n");
1545 if ( SCIPisFeasGT(
scip, rhs, 0.0) )
1547 SCIPdebugMsg(
scip,
"Detected infeasibility in 1x1 SDP-block without any nonzero coefficients but with strictly positive rhs\n");
1548 *result = SCIP_CUTOFF;
1553 SCIP_CALL( SCIPdelCons(
scip, conss[i]) );
1556 SCIPfreeBufferArray(
scip, &coeffs);
1557 SCIPfreeBufferArray(
scip, &vars);
1567 SCIP_CONSDATA* consdata,
1571 assert(
scip != NULL );
1572 assert( consdata != NULL );
1573 assert( 0 <= v && v < consdata->nvars );
1575 if ( consdata->locks != NULL )
1577 assert( consdata->locks[v] == -2 || consdata->locks[v] == -1 || consdata->locks[v] == 0 || consdata->locks[v] == 1 );
1579 if ( consdata->locks[v] == 1 )
1581 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], SCIP_LOCKTYPE_MODEL, 0, -1) );
1583 else if ( consdata->locks[v] == - 1 )
1585 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], SCIP_LOCKTYPE_MODEL, -1, 0) );
1587 else if ( consdata->locks[v] == 0 )
1589 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], SCIP_LOCKTYPE_MODEL, -1, -1) );
1604 SCIP_CONSDATA* consdata;
1605 SCIP_Real eigenvalue;
1610 assert(
scip != NULL );
1611 assert( cons != NULL );
1613 consdata = SCIPconsGetData(cons);
1614 assert( consdata != NULL );
1615 assert( consdata->locks != NULL );
1616 assert( 0 <= v && v < consdata->nvars );
1619 if ( consdata->rankone )
1622 consdata->locks[v] = 0;
1623 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], SCIP_LOCKTYPE_MODEL, 1, 1) );
1627 blocksize = consdata->blocksize;
1628 SCIP_CALL( SCIPallocBufferArray(
scip, &Aj, blocksize * blocksize) );
1634 if ( SCIPisNegative(
scip, eigenvalue) )
1637 if ( SCIPisPositive(
scip, eigenvalue) )
1642 if ( SCIPisPositive(
scip, eigenvalue) )
1651 SCIPfreeBufferArray(
scip, &Aj);
1654 if ( newlock != consdata->locks[v] )
1659 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], SCIP_LOCKTYPE_MODEL, 0, 1) );
1661 else if ( newlock == -1 )
1663 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], SCIP_LOCKTYPE_MODEL, 1, 0) );
1665 else if ( newlock == 0 )
1667 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], SCIP_LOCKTYPE_MODEL, 1, 1) );
1670 assert( newlock == -2 );
1672 consdata->locks[v] = newlock;
1686 SCIP_CONSDATA* consdata;
1691 assert(
scip != NULL );
1692 assert( cons != NULL );
1694 consdata = SCIPconsGetData(cons);
1695 assert( consdata != NULL );
1696 assert( consdata->locks != NULL );
1699 if ( consdata->rankone )
1701 for (v = 0; v < consdata->nvars; ++v)
1702 assert( consdata->locks[v] == 0 );
1706 blocksize = consdata->blocksize;
1707 SCIP_CALL( SCIPallocBufferArray(
scip, &Aj, blocksize * blocksize) );
1709 for (v = 0; v < consdata->nvars; ++v)
1711 SCIP_Real eigenvalue;
1718 if ( SCIPisNegative(
scip, eigenvalue) )
1721 if ( SCIPisPositive(
scip, eigenvalue) )
1726 if ( SCIPisPositive(
scip, eigenvalue) )
1735 assert( newlock == consdata->locks[v] );
1738 SCIPfreeBufferArray(
scip, &Aj);
1750 SCIP_VAR** aggrvars,
1756 SCIP_Real* savedval,
1761 SCIP_CONSDATA* consdata;
1764 int aggrtargetlength;
1769 assert(
scip != NULL );
1770 assert( cons != NULL );
1771 assert( scalars != NULL );
1772 assert( naggrvars > 0 );
1773 assert( savedcol != NULL );
1774 assert( savedrow != NULL );
1775 assert( savedval != NULL );
1776 assert( nfixednonz != NULL );
1778 consdata = SCIPconsGetData(cons);
1779 assert( consdata != NULL );
1780 assert( consdata->locks != NULL );
1781 assert( 0 <= v && v < consdata->nvars );
1784 startind = *nfixednonz;
1786 if ( SCIPisEQ(
scip, constant, 0.0) )
1792 for (i = 0; i < consdata->nvarnonz[v]; i++)
1794 savedcol[*nfixednonz] = consdata->col[v][i];
1795 savedrow[*nfixednonz] = consdata->row[v][i];
1796 savedval[*nfixednonz] = consdata->val[v][i];
1802 for (i = 0; i < consdata->nvarnonz[v]; i++)
1804 savedcol[*nfixednonz] = consdata->col[v][i];
1805 savedrow[*nfixednonz] = consdata->row[v][i];
1806 savedval[*nfixednonz] = consdata->val[v][i] * constant;
1810 assert( *nfixednonz - startind == consdata->nvarnonz[v] );
1818 SCIPfreeBlockMemoryArray(
scip, &(consdata->val[v]), consdata->nvarnonz[v]);
1819 SCIPfreeBlockMemoryArray(
scip, &(consdata->row[v]), consdata->nvarnonz[v]);
1820 SCIPfreeBlockMemoryArray(
scip, &(consdata->col[v]), consdata->nvarnonz[v]);
1826 SCIP_CALL( SCIPreleaseVar(
scip, &consdata->vars[v]) );
1827 consdata->col[v] = consdata->col[consdata->nvars - 1];
1828 consdata->row[v] = consdata->row[consdata->nvars - 1];
1829 consdata->val[v] = consdata->val[consdata->nvars - 1];
1830 consdata->nvarnonz[v] = consdata->nvarnonz[consdata->nvars - 1];
1831 consdata->vars[v] = consdata->vars[consdata->nvars - 1];
1832 consdata->locks[v] = consdata->locks[consdata->nvars - 1];
1833 (consdata->nvars)--;
1836 for (aggrind = 0; aggrind < naggrvars; aggrind++)
1840 for (i = 0; i < consdata->nvars; i++)
1842 if ( consdata->vars[i] == aggrvars[aggrind] )
1849 if ( aggrconsind > -1 )
1854 aggrtargetlength = consdata->nvarnonz[aggrconsind] + *nfixednonz - startind;
1855 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->row[aggrconsind]), consdata->nvarnonz[aggrconsind], aggrtargetlength) );
1856 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->col[aggrconsind]), consdata->nvarnonz[aggrconsind], aggrtargetlength) );
1857 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->val[aggrconsind]), consdata->nvarnonz[aggrconsind], aggrtargetlength) );
1859 if ( SCIPisEQ(
scip, constant, 0.0) )
1864 *nfixednonz - startind, TRUE, scalars[aggrind], consdata->row[aggrconsind], consdata->col[aggrconsind],
1865 consdata->val[aggrconsind], &(consdata->nvarnonz[aggrconsind]), aggrtargetlength) );
1872 *nfixednonz - startind, TRUE, scalars[aggrind] / constant, consdata->row[aggrconsind], consdata->col[aggrconsind],
1873 consdata->val[aggrconsind], &(consdata->nvarnonz[aggrconsind]), aggrtargetlength) );
1877 assert( consdata->nvarnonz[aggrconsind] <= aggrtargetlength );
1878 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->row[aggrconsind]), aggrtargetlength, consdata->nvarnonz[aggrconsind]) );
1879 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->col[aggrconsind]), aggrtargetlength, consdata->nvarnonz[aggrconsind]) );
1880 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->val[aggrconsind]), aggrtargetlength, consdata->nvarnonz[aggrconsind]) );
1887 SCIPdebugMsg(
scip,
"adding variable %s to SDP constraint %s because of (multi-)aggregation\n", SCIPvarGetName(aggrvars[aggrind]), SCIPconsGetName(cons));
1890 if ( consdata->nvars == *vararraylength )
1892 globalnvars = SCIPgetNVars(
scip);
1895 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->col, *vararraylength, globalnvars) );
1896 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->row, *vararraylength, globalnvars) );
1897 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->val, *vararraylength, globalnvars) );
1898 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->nvarnonz, *vararraylength, globalnvars) );
1899 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->vars, *vararraylength, globalnvars) );
1900 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->locks, *vararraylength, globalnvars) );
1901 *vararraylength = globalnvars;
1905 SCIP_CALL( SCIPcaptureVar(
scip, aggrvars[aggrind]) );
1906 consdata->vars[consdata->nvars] = aggrvars[aggrind];
1909 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(consdata->col[consdata->nvars]), savedcol + startind, *nfixednonz - startind) );
1910 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(consdata->row[consdata->nvars]), savedrow + startind, *nfixednonz - startind) );
1916 if ( SCIPisEQ(
scip, scalars[aggrind], constant) || SCIPisEQ(
scip, constant, 0.0) )
1918 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(consdata->val[consdata->nvars]), savedval + startind, *nfixednonz - startind) );
1919 consdata->nvarnonz[consdata->nvars] = *nfixednonz - startind;
1924 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &(consdata->val[consdata->nvars]), *nfixednonz - startind) );
1926 consdata->nvarnonz[consdata->nvars] = 0;
1928 for (i = 0; i < *nfixednonz - startind; i++)
1931 if ( SCIPisPositive(
scip, (scalars[i] / constant) * savedval[startind + i]) )
1933 consdata->val[consdata->nvars][consdata->nvarnonz[consdata->nvars]] = (scalars[i] / constant) * savedval[startind + i];
1934 consdata->nvarnonz[consdata->nvars]++;
1939 consdata->locks[consdata->nvars] = -2;
1940 if ( consdata->nvarnonz[consdata->nvars] > 0 )
1952 if ( SCIPisEQ(
scip, constant, 0.0) )
1953 *nfixednonz = startind;
1972 SCIP_CONSDATA* consdata;
1976 SCIP_Real* savedval;
1981 SCIP_VAR** aggrvars;
1995 assert(
scip != NULL );
1996 assert( conss != NULL );
1997 assert( nconss >= 0 );
1999 SCIPdebugMsg(
scip,
"Calling fixAndAggrVars with aggregate = %u.\n", aggregate);
2001 for (c = 0; c < nconss; ++c)
2005 assert( conss[c] != NULL );
2007 consdata = SCIPconsGetData(conss[c]);
2008 assert( consdata != NULL );
2009 assert( consdata->locks != NULL );
2010 assert( consdata->rankone || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])),
CONSHDLR_NAME) == 0 );
2011 assert( ! consdata->rankone || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[c])),
CONSHDLRRANK1_NAME) == 0 );
2014 SCIP_CALL( SCIPallocBufferArray(
scip, &savedcol, consdata->nnonz) );
2015 SCIP_CALL( SCIPallocBufferArray(
scip, &savedrow, consdata->nnonz) );
2016 SCIP_CALL( SCIPallocBufferArray(
scip, &savedval, consdata->nnonz) );
2018 vararraylength = consdata->nvars;
2019 globalnvars = SCIPgetNVars(
scip);
2021 for (v = 0; v < consdata->nvars; v++)
2023 SCIP_Bool negated = FALSE;
2026 if ( SCIPvarIsBinary(consdata->vars[v]) && SCIPvarIsNegated(consdata->vars[v]) )
2029 var = SCIPvarGetNegationVar(consdata->vars[v]);
2032 var = consdata->vars[v];
2035 if ( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED || SCIPisEQ(
scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
2037 assert( SCIPisEQ(
scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) );
2039 SCIPdebugMsg(
scip,
"Treating globally fixed variable %s with value %f!\n", SCIPvarGetName(var), SCIPvarGetLbGlobal(var));
2041 if ( (! negated && ! SCIPisEQ(
scip, SCIPvarGetLbGlobal(var), 0.0)) || (negated && SCIPisEQ(
scip, SCIPvarGetLbGlobal(var), 0.0)) )
2046 for (i = 0; i < consdata->nvarnonz[v]; i++)
2048 savedcol[nfixednonz] = consdata->col[v][i];
2049 savedrow[nfixednonz] = consdata->row[v][i];
2053 savedval[nfixednonz] = consdata->val[v][i] * SCIPvarGetLbGlobal(var);
2055 savedval[nfixednonz] = consdata->val[v][i];
2064 consdata->nnonz -= consdata->nvarnonz[v];
2068 SCIPfreeBlockMemoryArrayNull(
scip, &(consdata->val[v]), consdata->nvarnonz[v]);
2069 SCIPfreeBlockMemoryArrayNull(
scip, &(consdata->row[v]), consdata->nvarnonz[v]);
2070 SCIPfreeBlockMemoryArrayNull(
scip, &(consdata->col[v]), consdata->nvarnonz[v]);
2076 SCIP_CALL( SCIPreleaseVar(
scip, &(consdata->vars[v])) );
2077 consdata->col[v] = consdata->col[consdata->nvars - 1];
2078 consdata->row[v] = consdata->row[consdata->nvars - 1];
2079 consdata->val[v] = consdata->val[consdata->nvars - 1];
2080 consdata->nvarnonz[v] = consdata->nvarnonz[consdata->nvars - 1];
2081 consdata->vars[v] = consdata->vars[consdata->nvars - 1];
2082 consdata->locks[v] = consdata->locks[consdata->nvars - 1];
2086 else if ( aggregate && (SCIPvarGetStatus(var) == SCIP_VARSTATUS_AGGREGATED || SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR) )
2088 SCIP_CALL( SCIPallocBufferArray(
scip, &aggrvars, globalnvars) );
2089 SCIP_CALL( SCIPallocBufferArray(
scip, &scalars, globalnvars) );
2094 aggrvars[0] = consdata->vars[v];
2102 aggrvars[0] = consdata->vars[v];
2109 SCIP_CALL( SCIPgetProbvarLinearSum(
scip, aggrvars, scalars, &naggrvars, globalnvars, &constant, &requiredsize, TRUE) );
2110 assert( requiredsize <= globalnvars );
2115 if ( SCIPvarGetStatus(consdata->vars[v]) == SCIP_VARSTATUS_AGGREGATED )
2116 SCIPdebugMsg(
scip,
"aggregating variable %s to ", SCIPvarGetName(var));
2118 SCIPdebugMsg(
scip,
"multiaggregating variable %s to ", SCIPvarGetName(var));
2119 for (i = 0; i < naggrvars; i++)
2120 SCIPdebugMessagePrint(
scip,
"+ %g %s ", scalars[i], SCIPvarGetName(aggrvars[i]));
2121 SCIPdebugMessagePrint(
scip,
"+ %g.\n", constant);
2126 SCIP_CALL(
multiaggrVar(
scip, conss[c], v, aggrvars, scalars, naggrvars, constant, savedcol, savedrow, savedval, &nfixednonz, &vararraylength) );
2129 SCIPfreeBufferArray(
scip, &aggrvars);
2130 SCIPfreeBufferArray(
scip, &scalars);
2132 else if ( negated && (SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN) && aggregate )
2136 SCIPdebugMsg(
scip,
"Changing variable %s to negation of variable <%s>!\n", SCIPvarGetName(consdata->vars[v]), SCIPvarGetName(var));
2140 SCIP_CALL(
multiaggrVar(
scip, conss[c], v, &var, &scalar, 1, 1.0, savedcol, savedrow, savedval, &nfixednonz, &vararraylength) );
2146 assert( consdata->nvars <= vararraylength );
2147 if ( consdata->nvars < vararraylength )
2149 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->col, vararraylength, consdata->nvars) );
2150 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->row, vararraylength, consdata->nvars) );
2151 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->val, vararraylength, consdata->nvars) );
2152 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->nvarnonz, vararraylength, consdata->nvars) );
2153 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->vars, vararraylength, consdata->nvars) );
2154 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->locks, vararraylength, consdata->nvars) );
2158 arraylength = consdata->constnnonz + nfixednonz;
2159 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->constcol), consdata->constnnonz, arraylength) );
2160 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->constrow), consdata->constnnonz, arraylength) );
2161 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->constval), consdata->constnnonz, arraylength) );
2165 consdata->constcol, consdata->constval, &(consdata->constnnonz), arraylength) );
2167 assert( consdata->constnnonz <= arraylength );
2170 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->constcol), arraylength, consdata->constnnonz) );
2171 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->constrow), arraylength, consdata->constnnonz) );
2172 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &(consdata->constval), arraylength, consdata->constnnonz) );
2175 SCIPfreeBufferArray(
scip, &savedval);
2176 SCIPfreeBufferArray(
scip, &savedrow);
2177 SCIPfreeBufferArray(
scip, &savedcol);
2180 consdata->nnonz = 0;
2181 for (v = 0; v < consdata->nvars; v++)
2182 consdata->nnonz += consdata->nvarnonz[v];
2192 SCIP_CONSHDLR* conshdlr,
2199 char cutname[SCIP_MAXSTRLEN];
2200 SCIP_CONSDATA* consdata;
2201 SCIP_CONSHDLRDATA* conshdlrdata;
2202 SCIP_Bool separated = FALSE;
2204 SCIP_Bool infeasible;
2215 *result = SCIP_FEASIBLE;
2217 for (i = 0; i < nconss; ++i)
2219 consdata = SCIPconsGetData(conss[i]);
2221 if ( *result == SCIP_FEASIBLE )
2224 nvars = consdata->nvars;
2229 *result = SCIP_CUTOFF;
2236 SCIP_CALL( SCIPallocBufferArray(
scip, &coeff, nvars) );
2239 rhs = SCIPinfinity(
scip);
2240 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2243 snprintfreturn = SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"sepa_eig_sdp_%d", ++(conshdlrdata->neigveccuts));
2244 assert( snprintfreturn < SCIP_MAXSTRLEN );
2246 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN,
"sepa_eig_sdp_%d", ++(conshdlrdata->neigveccuts));
2249 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) ) 2250 SCIP_CALL( SCIPcreateEmptyRowConshdlr(
scip, &row, conshdlr, cutname , lhs, rhs, FALSE, FALSE, TRUE) );
2252 SCIP_CALL( SCIPcreateEmptyRowCons(
scip, &row, conshdlr, cutname , lhs, rhs, FALSE, FALSE, TRUE) );
2254 SCIP_CALL( SCIPcacheRowExtensions(
scip, row) );
2256 for (j = 0; j < nvars; ++j)
2258 SCIP_CALL( SCIPaddVarToRow(
scip, row, consdata->vars[j], coeff[j]) );
2261 SCIP_CALL( SCIPflushRowExtensions(
scip, row) );
2263 #ifdef SCIP_MORE_DEBUG 2264 SCIPinfoMessage(
scip, NULL,
"Added cut %s: ", cutname);
2265 SCIPinfoMessage(
scip, NULL,
"%f <= ", lhs);
2266 for (j = 0; j < nvars; j++)
2267 SCIPinfoMessage(
scip, NULL,
"+ (%f)*%s", coeff[j], SCIPvarGetName(consdata->vars[j]));
2268 SCIPinfoMessage(
scip, NULL,
"\n");
2271 SCIP_CALL( SCIPaddRow(
scip, row, FALSE, &infeasible) );
2275 *result = SCIP_CUTOFF;
2277 SCIP_CALL( SCIPreleaseRow(
scip, &row) );
2278 SCIPfreeBufferArray(
scip, &coeff);
2284 SCIP_CALL( SCIPaddPoolCut(
scip, row) );
2286 SCIP_CALL( SCIPresetConsAge(
scip, conss[i]) );
2287 *result = SCIP_SEPARATED;
2290 SCIP_CALL( SCIPreleaseRow(
scip, &row) );
2291 SCIPfreeBufferArray(
scip, &coeff);
2295 *result = SCIP_SEPARATED;
2305 char name[SCIP_MAXSTRLEN];
2306 SCIP_CONSHDLR* conshdlr;
2307 SCIP_CONSHDLRDATA* conshdlrdata;
2309 SCIP_VAR** linconsvars;
2310 SCIP_Real* linconsvals;
2311 SCIP_VAR** linvarsterms;
2312 SCIP_Real* linvalsterms;
2313 SCIP_QUADVARTERM* quadvarterms;
2314 SCIP_BILINTERM* bilinterms;
2321 assert(
scip != NULL );
2322 assert( cons != NULL );
2323 assert( nupgdconss != NULL );
2324 assert( upgdconss != NULL );
2329 if ( SCIPconsIsModifiable(cons) || SCIPconsIsStickingAtNode(cons) )
2333 if ( SCIPgetSubscipDepth(
scip) > 0 )
2337 if ( upgdconsssize < 1 )
2344 if ( conshdlr == NULL )
2346 SCIPerrorMessage(
"rank 1 SDP constraint handler not found\n");
2347 return SCIP_PLUGINNOTFOUND;
2349 assert( conshdlr != NULL );
2351 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2352 assert( conshdlrdata != NULL );
2355 if ( ! conshdlrdata->sdpconshdlrdata->upgradquadconss )
2359 if ( conshdlrdata->sdpconshdlrdata->quadconsvars == NULL )
2361 SCIP_CONSHDLR* quadconshdlr;
2378 SCIP_Real constval = -1.0;
2382 nvars = SCIPgetNTotalVars(
scip);
2383 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->quadconsidx, nvars) );
2384 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->quadconsvars, nvars) );
2385 conshdlrdata->sdpconshdlrdata->nquadconsidx = nvars;
2386 for (j = 0; j < nvars; ++j)
2387 conshdlrdata->sdpconshdlrdata->quadconsidx[j] = -1;
2389 quadconshdlr = SCIPfindConshdlr(
scip,
"quadratic");
2390 if ( quadconshdlr == NULL )
2392 SCIPerrorMessage(
"Quadratic constraint handler not found\n");
2393 return SCIP_PLUGINNOTFOUND;
2395 assert( quadconshdlr != NULL );
2397 conss = SCIPconshdlrGetConss(quadconshdlr);
2398 nconss = SCIPconshdlrGetNConss(quadconshdlr);
2401 if ( nconss > conshdlrdata->sdpconshdlrdata->maxnvarsquadupgd )
2403 SCIPdebugMsg(
scip,
"There are %d many quadratic constraints present in the problem, thus do not upgrade quadratic constraints to an SDPrank1 constraint\n", nconss);
2404 SCIPfreeBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->quadconsvars, nvars);
2405 SCIPfreeBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->quadconsidx, nvars);
2409 for (c = 0; c < nconss; ++c)
2411 assert( conss[c] != NULL );
2412 #ifdef SCIP_MORE_DEBUG 2413 SCIPinfoMessage(
scip, NULL,
"Found quadratic constraint to upgrade:\n");
2414 SCIP_CALL( SCIPprintCons(
scip, conss[c], NULL) );
2415 SCIPinfoMessage(
scip, NULL,
"\n");
2417 nquadvarterms = SCIPgetNQuadVarTermsQuadratic(
scip, conss[c]);
2418 quadvarterms = SCIPgetQuadVarTermsQuadratic(
scip, conss[c]);
2420 for (i = 0; i < nquadvarterms; ++i)
2425 assert( quadvarterms != NULL );
2426 var = quadvarterms[i].var;
2427 idx = SCIPvarGetIndex(var);
2428 assert( 0 <= idx && idx < nvars );
2429 if ( conshdlrdata->sdpconshdlrdata->quadconsidx[idx] < 0 )
2431 conshdlrdata->sdpconshdlrdata->quadconsvars[nsdpvars] = var;
2432 conshdlrdata->sdpconshdlrdata->quadconsidx[idx] = nsdpvars++;
2436 nbilinterms = SCIPgetNBilinTermsQuadratic(
scip, conss[c]);
2437 bilinterms = SCIPgetBilinTermsQuadratic(
scip, conss[c]);
2439 for (i = 0; i < nbilinterms; ++i)
2444 assert( bilinterms != NULL );
2445 var = bilinterms[i].var1;
2446 idx = SCIPvarGetIndex(var);
2447 assert( 0 <= idx && idx < nvars );
2448 if ( conshdlrdata->sdpconshdlrdata->quadconsidx[idx] < 0 )
2450 conshdlrdata->sdpconshdlrdata->quadconsvars[nsdpvars] = var;
2451 conshdlrdata->sdpconshdlrdata->quadconsidx[idx] = nsdpvars++;
2454 var = bilinterms[i].var2;
2455 idx = SCIPvarGetIndex(var);
2456 assert( 0 <= idx && idx < nvars );
2457 if ( conshdlrdata->sdpconshdlrdata->quadconsidx[idx] < 0 )
2459 conshdlrdata->sdpconshdlrdata->quadconsvars[nsdpvars] = var;
2460 conshdlrdata->sdpconshdlrdata->quadconsidx[idx] = nsdpvars++;
2467 if ( nsdpvars > conshdlrdata->sdpconshdlrdata->maxnvarsquadupgd )
2469 SCIPdebugMsg(
scip,
"There are %d many variables present in the quadratic constraints, thus do not upgrade quadratic constraints to an SDPrank1 constraint\n", nsdpvars);
2470 SCIPfreeBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->quadconsvars, nvars);
2471 SCIPfreeBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->quadconsidx, nvars);
2476 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->X, nsdpvars) );
2477 conshdlrdata->sdpconshdlrdata->nsdpvars = nsdpvars;
2479 for (i = 0; i < nsdpvars; ++i)
2485 var1 = conshdlrdata->sdpconshdlrdata->quadconsvars[i];
2486 assert( var1 != NULL );
2487 lb1 = SCIPvarGetLbGlobal(var1);
2488 ub1 = SCIPvarGetUbGlobal(var1);
2490 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->X[i], nsdpvars) );
2492 for (j = 0; j <= i; ++j)
2494 SCIP_VARTYPE vartype;
2501 var2 = conshdlrdata->sdpconshdlrdata->quadconsvars[j];
2502 assert( var2 != NULL );
2503 lb2 = SCIPvarGetLbGlobal(var2);
2504 ub2 = SCIPvarGetUbGlobal(var2);
2506 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN,
"X%d#%d", i, j);
2508 lb = MIN3(lb1 * lb2, lb1 * ub2, ub1 * lb2);
2509 lb = MIN(lb, ub1 * ub2);
2510 ub = MAX3(lb1 * lb2, lb1 * ub2, ub1 * lb2);
2511 ub = MAX(ub, ub1 * ub2);
2513 if ( SCIPvarIsBinary(var1) && SCIPvarIsBinary(var2) )
2514 vartype = SCIP_VARTYPE_BINARY;
2515 else if ( SCIPvarIsIntegral(var1) && SCIPvarIsIntegral(var2) )
2516 vartype = SCIP_VARTYPE_INTEGER;
2518 vartype = SCIP_VARTYPE_CONTINUOUS;
2520 SCIP_CALL( SCIPcreateVarBasic(
scip, &(conshdlrdata->sdpconshdlrdata->X[i][j]), name, lb, ub, 0.0, vartype) );
2521 SCIP_CALL( SCIPaddVar(
scip, conshdlrdata->sdpconshdlrdata->X[i][j]) );
2526 nnonz = nsdpvars + nsdpvars * (nsdpvars + 1) / 2;
2527 SCIP_CALL( SCIPallocBufferArray(
scip, &cols, nnonz) );
2528 SCIP_CALL( SCIPallocBufferArray(
scip, &rows, nnonz) );
2529 SCIP_CALL( SCIPallocBufferArray(
scip, &vals, nnonz) );
2530 SCIP_CALL( SCIPallocBufferArray(
scip, &vars, nnonz) );
2531 SCIP_CALL( SCIPallocBufferArray(
scip, &nvarnonz, nnonz) );
2534 for (j = 0; j < nsdpvars; ++j)
2536 SCIP_CALL( SCIPallocBufferArray(
scip, &cols[j], 1) );
2537 SCIP_CALL( SCIPallocBufferArray(
scip, &rows[j], 1) );
2538 SCIP_CALL( SCIPallocBufferArray(
scip, &vals[j], 1) );
2543 vars[j] = conshdlrdata->sdpconshdlrdata->quadconsvars[j];
2547 nvarscnt = nsdpvars;
2548 for (i = 0; i < nsdpvars; ++i)
2550 for (j = 0; j <= i; ++j)
2552 SCIP_CALL( SCIPallocBufferArray(
scip, &cols[nvarscnt], 1) );
2553 SCIP_CALL( SCIPallocBufferArray(
scip, &rows[nvarscnt], 1) );
2554 SCIP_CALL( SCIPallocBufferArray(
scip, &vals[nvarscnt], 1) );
2555 nvarnonz[nvarscnt] = 1;
2556 cols[nvarscnt][0] = 1 + j;
2557 rows[nvarscnt][0] = 1 + i;
2558 vals[nvarscnt][0] = 1.0;
2559 vars[nvarscnt] = conshdlrdata->sdpconshdlrdata->X[i][j];
2563 assert( nvarscnt == nsdpvars + nsdpvars * (nsdpvars + 1)/2 );
2566 if ( conshdlrdata->sdpconshdlrdata->upgradekeepquad )
2568 SCIP_CALL(
SCIPcreateConsSdp(
scip, &conshdlrdata->sdpconshdlrdata->sdpcons,
"QuadraticSDPcons", nvarscnt, nvarscnt, 1 + nsdpvars, nvarnonz,
2569 cols, rows, vals, vars, 1, &constcol, &constrow, &constval) );
2570 SCIP_CALL( SCIPaddCons(
scip, conshdlrdata->sdpconshdlrdata->sdpcons) );
2574 SCIP_CALL(
SCIPcreateConsSdpRank1(
scip, &conshdlrdata->sdpconshdlrdata->sdpcons,
"QuadraticSDPrank1cons", nvarscnt, nvarscnt, 1 + nsdpvars, nvarnonz,
2575 cols, rows, vals, vars, 1, &constcol, &constrow, &constval) );
2576 SCIP_CALL( SCIPaddCons(
scip, conshdlrdata->sdpconshdlrdata->sdpcons) );
2579 #ifdef SCIP_MORE_DEBUG 2580 SCIPinfoMessage(
scip, NULL,
"In upgrade of quadratic constraint the following SDPrank1 constraint has been added:\n");
2581 SCIP_CALL( SCIPprintCons(
scip, conshdlrdata->sdpconshdlrdata->sdpcons, NULL) );
2582 SCIPinfoMessage(
scip, NULL,
"\n");
2586 for (j = nvarscnt - 1; j >= 0; --j)
2588 SCIPfreeBufferArray(
scip, &vals[j]);
2589 SCIPfreeBufferArray(
scip, &rows[j]);
2590 SCIPfreeBufferArray(
scip, &cols[j]);
2592 SCIPfreeBufferArray(
scip, &nvarnonz);
2593 SCIPfreeBufferArray(
scip, &vars);
2594 SCIPfreeBufferArray(
scip, &vals);
2595 SCIPfreeBufferArray(
scip, &rows);
2596 SCIPfreeBufferArray(
scip, &cols);
2599 if ( ! conshdlrdata->sdpconshdlrdata->upgradekeepquad )
2604 nlinvarterms = SCIPgetNLinearVarsQuadratic(
scip, cons);
2605 linvarsterms = SCIPgetLinearVarsQuadratic(
scip, cons);
2606 linvalsterms = SCIPgetCoefsLinearVarsQuadratic(
scip, cons);
2607 nquadvarterms = SCIPgetNQuadVarTermsQuadratic(
scip, cons);
2608 quadvarterms = SCIPgetQuadVarTermsQuadratic(
scip, cons);
2609 nbilinterms = SCIPgetNBilinTermsQuadratic(
scip, cons);
2610 bilinterms = SCIPgetBilinTermsQuadratic(
scip, cons);
2614 nlinconsterms = nlinvarterms + 2 * nquadvarterms + nbilinterms;
2615 SCIP_CALL( SCIPallocBufferArray(
scip, &linconsvars, nlinconsterms) );
2616 SCIP_CALL( SCIPallocBufferArray(
scip, &linconsvals, nlinconsterms) );
2619 for (j = 0; j < nlinvarterms; ++j)
2621 linconsvals[cnt] = linvalsterms[j];
2622 linconsvars[cnt] = linvarsterms[j];
2623 assert( linconsvars[cnt] != NULL );
2626 assert( cnt == nlinvarterms );
2627 for (j = 0; j < nquadvarterms; ++j)
2631 idx = SCIPvarGetIndex(quadvarterms[j].var);
2632 idx = conshdlrdata->sdpconshdlrdata->quadconsidx[idx];
2633 assert( 0 <= idx && idx < conshdlrdata->sdpconshdlrdata->nsdpvars );
2636 if ( ! SCIPisZero(
scip, quadvarterms[j].lincoef) )
2638 linconsvals[cnt] = quadvarterms[j].lincoef;
2639 linconsvars[cnt] = quadvarterms[j].var;
2640 assert( linconsvars[cnt] != NULL );
2645 if ( ! SCIPisZero(
scip, quadvarterms[j].sqrcoef) )
2647 linconsvals[cnt] = quadvarterms[j].sqrcoef;
2648 linconsvars[cnt] = conshdlrdata->sdpconshdlrdata->X[idx][idx];
2649 assert( linconsvars[cnt] != NULL );
2653 SCIPdebugMsg(
scip,
"New variable %s corresponds to squared original variable %s\n", SCIPvarGetName(conshdlrdata->sdpconshdlrdata->X[idx][idx]), SCIPvarGetName(quadvarterms[j].var));
2655 assert( cnt <= nlinvarterms + 2 * nquadvarterms );
2657 for (j = 0; j < nbilinterms; ++j)
2662 idx1 = SCIPvarGetIndex(bilinterms[j].var1);
2663 idx1 = conshdlrdata->sdpconshdlrdata->quadconsidx[idx1];
2664 assert( 0 <= idx1 && idx1 < conshdlrdata->sdpconshdlrdata->nsdpvars );
2666 idx2 = SCIPvarGetIndex(bilinterms[j].var2);
2667 idx2 = conshdlrdata->sdpconshdlrdata->quadconsidx[idx2];
2668 assert( 0 <= idx2 && idx2 < conshdlrdata->sdpconshdlrdata->nsdpvars );
2671 SCIPswapInts(&idx1, &idx2);
2673 linconsvals[cnt] = bilinterms[j].coef;
2674 linconsvars[cnt] = conshdlrdata->sdpconshdlrdata->X[idx1][idx2];
2675 assert( linconsvars[cnt] != NULL );
2678 SCIPdebugMsg(
scip,
"New variable %s corresponds to product of original variables %s and %s\n", SCIPvarGetName(conshdlrdata->sdpconshdlrdata->X[idx1][idx2]), SCIPvarGetName(bilinterms[j].var1), SCIPvarGetName(bilinterms[j].var2));
2680 assert( cnt <= nlinvarterms + 2 * nquadvarterms + nbilinterms );
2682 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN,
"lin_%s", SCIPconsGetName(cons));
2683 SCIP_CALL( SCIPcreateConsLinear(
scip, &lincons, name, cnt, linconsvars, linconsvals, SCIPgetLhsQuadratic(
scip, cons), SCIPgetRhsQuadratic(
scip, cons),
2684 SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons), SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons),
2685 FALSE, SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), FALSE) );
2687 #ifdef SCIP_MORE_DEBUG 2688 SCIPinfoMessage(
scip, NULL,
"In upgrade of quadratic constraint the following linear constraint has been added:\n");
2689 SCIP_CALL( SCIPprintCons(
scip, lincons, NULL) );
2690 SCIPinfoMessage(
scip, NULL,
"\n");
2694 upgdconss[0] = lincons;
2697 SCIPfreeBufferArray(
scip, &linconsvals);
2698 SCIPfreeBufferArray(
scip, &linconsvars);
2718 SCIP_CONSHDLRDATA* conshdlrdata;
2720 assert( conshdlr != NULL );
2722 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2723 assert( conshdlrdata != NULL );
2725 conshdlrdata->neigveccuts = 0;
2726 conshdlrdata->ndiaggezerocuts = 0;
2727 conshdlrdata->n1x1blocks = 0;
2737 SCIP_CONSDATA* consdata;
2741 consdata = SCIPconsGetData(cons);
2742 assert( consdata != NULL );
2743 nvars = consdata->nvars;
2745 SCIPdebugMsg(
scip,
"locking method of <%s>.\n", SCIPconsGetName(cons));
2748 if ( consdata->rankone )
2750 if ( consdata->locks == NULL )
2751 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->locks, nvars) );
2753 for (v = 0; v < consdata->nvars; ++v)
2755 consdata->locks[v] = 0;
2756 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
2762 if ( consdata->locks == NULL )
2764 SCIP_Real eigenvalue;
2767 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->locks, nvars) );
2769 blocksize = consdata->blocksize;
2771 SCIP_CALL( SCIPallocBufferArray(
scip, &Aj, blocksize * blocksize) );
2773 for (v = 0; v < nvars; v++)
2776 consdata->locks[v] = -2;
2780 if ( SCIPisNegative(
scip, eigenvalue) )
2784 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], locktype, nlocksneg, nlockspos) );
2785 consdata->locks[v] = 1;
2789 if ( SCIPisPositive(
scip, eigenvalue) )
2793 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], locktype, nlockspos, nlocksneg) );
2794 consdata->locks[v] = -1;
2800 if ( SCIPisPositive(
scip, eigenvalue) )
2804 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], locktype, nlockspos, nlocksneg) );
2805 if ( consdata->locks[v] == 1 )
2807 consdata->locks[v] = 0;
2810 consdata->locks[v] = -1;
2815 SCIPfreeBufferArray(
scip, &Aj);
2822 for (v = 0; v < nvars; v++)
2824 if ( consdata->locks[v] == 1 )
2826 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], locktype, nlocksneg, nlockspos) );
2828 else if ( consdata->locks[v] == -1 )
2830 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], locktype, nlockspos, nlocksneg) );
2832 else if ( consdata->locks[v] == 0 )
2834 SCIP_CALL( SCIPaddVarLocksType(
scip, consdata->vars[v], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
2837 assert( consdata->locks[v] == -2 );
2851 SCIP_CONSHDLRDATA* conshdlrdata;
2853 assert(
scip != NULL);
2855 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2856 assert(conshdlrdata != NULL);
2859 conshdlrdata->sdpconshdlrdata->triedlinearconss = FALSE;
2868 SCIP_CONSHDLRDATA* conshdlrdata;
2872 assert(
scip != NULL );
2873 assert( conshdlr != NULL );
2875 SCIPdebugMsg(
scip,
"Exitpre method of conshdlr <%s>.\n", SCIPconshdlrGetName(conshdlr));
2877 if ( conss == NULL )
2882 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2883 assert( conshdlrdata != NULL );
2885 SCIPfreeBlockMemoryArrayNull(
scip, &conshdlrdata->sdpconshdlrdata->quadconsidx, conshdlrdata->sdpconshdlrdata->nquadconsidx);
2886 SCIPfreeBlockMemoryArrayNull(
scip, &conshdlrdata->sdpconshdlrdata->quadconsvars, conshdlrdata->sdpconshdlrdata->nquadconsidx);
2887 if ( conshdlrdata->sdpconshdlrdata->X != NULL )
2889 SCIPdebugMsg(
scip,
"Releasing additional variables from upgrading method\n");
2890 for (i = 0; i < conshdlrdata->sdpconshdlrdata->nsdpvars; ++i)
2892 for (j = 0; j <= i; ++j)
2894 SCIP_CALL( SCIPreleaseVar(
scip, &(conshdlrdata->sdpconshdlrdata->X[i][j])) );
2896 SCIPfreeBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->X[i], conshdlrdata->sdpconshdlrdata->nsdpvars);
2898 SCIPfreeBlockMemoryArray(
scip, &conshdlrdata->sdpconshdlrdata->X, conshdlrdata->sdpconshdlrdata->nsdpvars);
2900 if ( conshdlrdata->sdpconshdlrdata->sdpcons != NULL )
2902 SCIPdebugMsg(
scip,
"Releasing constraint %s from upgrading method\n", SCIPconsGetName(conshdlrdata->sdpconshdlrdata->sdpcons) );
2903 SCIP_CALL( SCIPreleaseCons(
scip, &conshdlrdata->sdpconshdlrdata->sdpcons) );
2918 SCIP_CONSHDLRDATA* conshdlrdata;
2922 assert(
scip != NULL );
2923 assert( conshdlr != NULL );
2925 if ( conss == NULL )
2928 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2929 assert( conshdlrdata != NULL );
2931 if ( SCIPgetSubscipDepth(
scip) > 0 || ! conshdlrdata->sdpconshdlrdata->quadconsrank1 )
2934 for (c = 0; c < nconss; ++c)
2936 SCIP_CONSDATA* consdata;
2938 consdata = SCIPconsGetData(conss[c]);
2939 assert( consdata != NULL );
2941 consdata->maxevsubmat[0] = -1;
2942 consdata->maxevsubmat[1] = -1;
2946 if ( consdata->rankone && ! consdata->addedquadcons )
2948 SCIP_VAR** quadvars1;
2949 SCIP_VAR** quadvars2;
2951 SCIP_CONS* quadcons;
2952 SCIP_Real* lincoefs;
2953 SCIP_Real* quadcoefs;
2954 SCIP_Real* constmatrix;
2955 SCIP_Real** matrixAk;
2966 char name[SCIP_MAXSTRLEN];
2976 blocksize = consdata->blocksize;
2978 SCIP_CALL( SCIPallocBufferArray(
scip, &constmatrix, (blocksize * (blocksize + 1)) / 2) );
2981 SCIP_CALL( SCIPallocBufferArray(
scip, &quadvars1, consdata->nvars * consdata->nvars) );
2982 SCIP_CALL( SCIPallocBufferArray(
scip, &quadvars2, consdata->nvars * consdata->nvars) );
2983 SCIP_CALL( SCIPallocBufferArray(
scip, &linvars, consdata->nvars) );
2984 SCIP_CALL( SCIPallocBufferArray(
scip, &quadcoefs, consdata->nvars * consdata->nvars) );
2985 SCIP_CALL( SCIPallocBufferArray(
scip, &lincoefs, consdata->nvars) );
2986 SCIP_CALL( SCIPallocBufferArray(
scip, &matrixAk, consdata->nvars) );
2988 for (i = 0; i < consdata->nvars; ++i)
2990 SCIP_CALL( SCIPallocBufferArray(
scip, &matrixAk[i], blocksize * blocksize) );
2994 SCIP_CALL( SCIPallocBufferArray(
scip, &nnonzvars, (blocksize * (blocksize + 1)) / 2) );
2995 SCIP_CALL( SCIPallocBufferArray(
scip, &nonzvars, (blocksize * (blocksize + 1)) / 2) );
2997 for (i = 0; i < blocksize; ++i)
2999 for (j = 0; j <= i; ++j)
3005 for (k = 0; k < consdata->nvars; ++k)
3007 if ( ! SCIPisZero(
scip, matrixAk[k][i * blocksize + j]) || ! SCIPisZero(
scip, matrixAk[k][i * blocksize + i]) || ! SCIPisZero(
scip, matrixAk[k][j * blocksize + j]) )
3017 for (i = 0; i < blocksize; ++i)
3019 for (j = 0; j < i; ++j)
3031 ajjk = matrixAk[varind1][j * consdata->blocksize + j];
3032 aiik = matrixAk[varind1][i * consdata->blocksize + i];
3033 aijk = matrixAk[varind1][j * consdata->blocksize + i];
3035 if ( ! SCIPisZero(
scip, -cii * ajjk - cjj * aiik + cij * aijk) )
3037 linvars[lincnt] = consdata->vars[varind1];
3038 lincoefs[lincnt] = -cii * ajjk - cjj * aiik + cij * aijk;
3042 for (l = 0; l < k; ++l)
3045 ajjl = matrixAk[varind2][j * consdata->blocksize + j];
3046 aiil = matrixAk[varind2][i * consdata->blocksize + i];
3047 aijl = matrixAk[varind2][j * consdata->blocksize + i];
3049 if ( ! SCIPisZero(
scip, aiik * ajjl + ajjk * aiil - 2 * aijk * aijl) )
3051 quadvars1[quadcnt] = consdata->vars[varind1];
3052 quadvars2[quadcnt] = consdata->vars[varind2];
3053 quadcoefs[quadcnt] = aiik * ajjl + ajjk * aiil - 2 * aijk * aijl;
3059 if ( ! SCIPisZero(
scip, aiik * ajjk - aijk * aijk) )
3061 quadvars1[quadcnt] = consdata->vars[varind1];
3062 quadvars2[quadcnt] = consdata->vars[varind1];
3063 quadcoefs[quadcnt] = aiik * ajjk - aijk * aijk;
3067 assert( quadcnt <= consdata->nvars * consdata->nvars );
3068 assert( lincnt <= consdata->nvars );
3070 lhs = cij * cij - cii * cjj;
3072 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN,
"quadcons#%d#%d#%d", i, j, c);
3075 SCIP_CALL( SCIPcreateConsQuadratic(
scip, &quadcons, name, lincnt, linvars, lincoefs, quadcnt, quadvars1, quadvars2, quadcoefs, lhs, lhs,
3086 #ifdef SCIP_MORE_DEBUG 3087 SCIP_CALL( SCIPprintCons(
scip, quadcons, NULL) );
3088 SCIPinfoMessage(
scip, NULL,
"\n");
3091 SCIP_CALL( SCIPaddCons(
scip, quadcons) );
3092 SCIP_CALL( SCIPreleaseCons(
scip, &quadcons) );
3096 for (i = 0; i < blocksize; ++i)
3098 for (j = 0; j <= i; ++j)
3102 SCIPfreeBufferArray(
scip, &nonzvars);
3103 SCIPfreeBufferArray(
scip, &nnonzvars);
3105 for (i = 0; i < consdata->nvars; ++i)
3106 SCIPfreeBufferArray(
scip, &matrixAk[i]);
3108 SCIPfreeBufferArray(
scip, &matrixAk);
3109 SCIPfreeBufferArray(
scip, &lincoefs);
3110 SCIPfreeBufferArray(
scip, &quadcoefs);
3111 SCIPfreeBufferArray(
scip, &linvars);
3112 SCIPfreeBufferArray(
scip, &quadvars2);
3113 SCIPfreeBufferArray(
scip, &quadvars1);
3114 SCIPfreeBufferArray(
scip, &constmatrix);
3116 consdata->addedquadcons = TRUE;
3125 SCIP_CONSHDLRDATA* conshdlrdata;
3127 assert( conshdlr != NULL );
3128 assert( result != NULL );
3130 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3131 assert( conshdlrdata != NULL );
3133 *result = SCIP_DIDNOTRUN;
3141 *result = SCIP_DIDNOTFIND;
3143 noldaddconss = *naddconss;
3144 nolddelconss = *ndelconss;
3145 noldchgbds = *nchgbds;
3147 if ( *result != SCIP_CUTOFF && (noldaddconss != *naddconss || nolddelconss != *ndelconss || noldchgbds != *nchgbds) )
3148 *result = SCIP_SUCCESS;
3152 if ( SCIPgetSubscipDepth(
scip) == 0 && ! conshdlrdata->sdpconshdlrdata->triedlinearconss )
3154 conshdlrdata->sdpconshdlrdata->triedlinearconss = TRUE;
3155 if ( *result != SCIP_CUTOFF && conshdlrdata->sdpconshdlrdata->diaggezerocuts )
3157 noldaddconss = *naddconss;
3158 noldchgbds = *nchgbds;
3159 SCIP_CALL(
diagGEzero(
scip, conshdlr, conss, nconss, naddconss, nchgbds, result) );
3160 SCIPdebugMsg(
scip,
"Diagonal entries: added %d cuts and changed %d bounds.\n", *naddconss - noldaddconss, *nchgbds - noldchgbds);
3161 if ( *result != SCIP_CUTOFF && ( noldaddconss != *naddconss || noldchgbds != *nchgbds ) )
3162 *result = SCIP_SUCCESS;
3165 if ( *result != SCIP_CUTOFF && conshdlrdata->sdpconshdlrdata->diagzeroimplcuts )
3167 noldaddconss = *naddconss;
3169 SCIPdebugMsg(
scip,
"Added %d cuts for implication from 0 diagonal.\n", *naddconss - noldaddconss);
3170 if ( noldaddconss != *naddconss )
3171 *result = SCIP_SUCCESS;
3174 if ( *result != SCIP_CUTOFF && conshdlrdata->sdpconshdlrdata->twominorlinconss )
3176 noldaddconss = *naddconss;
3178 SCIPdebugMsg(
scip,
"Added %d linear constraints for 2 by 2 minors.\n", *naddconss - noldaddconss);
3179 if ( noldaddconss != *naddconss )
3180 *result = SCIP_SUCCESS;
3183 if ( *result != SCIP_CUTOFF && conshdlrdata->sdpconshdlrdata->twominorprodconss )
3185 noldaddconss = *naddconss;
3187 SCIPdebugMsg(
scip,
"Added %d linear constraints for products of 2 by 2 minors.\n", *naddconss - noldaddconss);
3188 if ( noldaddconss != *naddconss )
3189 *result = SCIP_SUCCESS;
3201 SCIP_CONSDATA* sourcedata;
3202 SCIP_CONSDATA* targetdata;
3204 SCIP_CONSHDLRDATA* conshdlrdata;
3210 char transname[SCIP_MAXSTRLEN];
3212 sourcedata = SCIPconsGetData(sourcecons);
3213 assert( sourcedata != NULL );
3215 SCIPdebugMsg(
scip,
"Transforming constraint <%s>\n", SCIPconsGetName(sourcecons));
3218 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3219 SCIPdebugMsg(
scip,
"Setting number of threads to %d via OpenMP in Openblas.\n", conshdlrdata->nthreads);
3220 omp_set_num_threads(conshdlrdata->nthreads);
3223 SCIP_CALL( SCIPallocBlockMemory(
scip, &targetdata) );
3226 targetdata->nvars = sourcedata->nvars;
3227 targetdata->nnonz = sourcedata->nnonz;
3228 targetdata->blocksize = sourcedata->blocksize;
3230 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->nvarnonz), sourcedata->nvarnonz, sourcedata->nvars) );
3233 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &(targetdata->col), sourcedata->nvars) );
3234 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &(targetdata->row), sourcedata->nvars) );
3235 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &(targetdata->val), sourcedata->nvars) );
3237 for (i = 0; i < sourcedata->nvars; i++)
3239 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->col[i]), sourcedata->col[i], sourcedata->nvarnonz[i]) );
3240 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->row[i]), sourcedata->row[i], sourcedata->nvarnonz[i]) );
3241 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->val[i]), sourcedata->val[i], sourcedata->nvarnonz[i]) );
3243 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &(targetdata->vars), sourcedata->nvars) );
3244 if ( sourcedata->locks )
3246 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->locks), sourcedata->locks, sourcedata->nvars) );
3249 targetdata->locks = NULL;
3252 for (i = 0; i < sourcedata->nvars; i++)
3254 targetdata->vars[i] = SCIPvarGetTransVar(sourcedata->vars[i]);
3255 SCIP_CALL( SCIPcaptureVar(
scip, targetdata->vars[i]) );
3259 targetdata->constnnonz = sourcedata->constnnonz;
3261 if ( sourcedata->constnnonz > 0 )
3263 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->constcol), sourcedata->constcol, sourcedata->constnnonz));
3264 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->constrow), sourcedata->constrow, sourcedata->constnnonz));
3265 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->constval), sourcedata->constval, sourcedata->constnnonz));
3269 targetdata->constcol = NULL;
3270 targetdata->constrow = NULL;
3271 targetdata->constval = NULL;
3275 targetdata->maxrhsentry = sourcedata->maxrhsentry;
3278 targetdata->rankone = sourcedata->rankone;
3281 SCIP_CALL( SCIPduplicateBlockMemoryArray(
scip, &(targetdata->maxevsubmat), sourcedata->maxevsubmat, 2) );
3284 targetdata->addedquadcons = sourcedata->addedquadcons;
3288 snprintfreturn = SCIPsnprintf(transname, SCIP_MAXSTRLEN,
"t_%s", SCIPconsGetName(sourcecons));
3289 assert( snprintfreturn < SCIP_MAXSTRLEN );
3291 (void) SCIPsnprintf(transname, SCIP_MAXSTRLEN,
"t_%s", SCIPconsGetName(sourcecons));
3295 SCIP_CALL( SCIPcreateCons(
scip, targetcons, transname, conshdlr, targetdata,
3296 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
3297 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons), SCIPconsIsLocal(sourcecons),
3298 SCIPconsIsModifiable(sourcecons), SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons),
3299 SCIPconsIsStickingAtNode(sourcecons)) );
3308 SCIP_CONS* violcons;
3309 SCIP_CONSDATA* consdata;
3310 SCIP_CONSHDLRDATA* conshdlrdata;
3313 SCIP_SOL* bestrank1approx;
3315 SCIP_Real* fullmatrix;
3316 SCIP_Real* eigenvalues;
3317 SCIP_Real* eigenvectors;
3318 SCIP_Real* scaledeigenvectors;
3320 SCIP_Real* matrixAj;
3321 SCIP_Real* linmatrix;
3322 SCIP_Real* rhsmatrix;
3325 SCIP_Real* colmatrix;
3326 SCIP_Bool rank1result;
3334 #ifdef PRINTMATRICES 3348 int* indviolrank1conss;
3350 SCIP_VAR** rank1consvars;
3353 assert(
scip != NULL );
3354 assert( result != NULL );
3355 assert( conss != NULL );
3357 *result = SCIP_FEASIBLE;
3359 #ifdef PRINTMATRICES 3360 SCIP_CALL( SCIPprintSol(
scip, sol, NULL, FALSE) );
3364 for (i = 0; i < nconss; ++i)
3367 #ifdef PRINTMATRICES 3368 SCIPinfoMessage(
scip, NULL,
"Solution is %d for constraint %s.\n", *result, SCIPconsGetName(conss[i]) );
3370 if ( *result == SCIP_INFEASIBLE )
3375 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3376 assert( conshdlrdata != NULL );
3377 if ( ! conshdlrdata->sdpconshdlrdata->rank1approxheur )
3383 if ( SCIPgetSubscipDepth(
scip) > 0 )
3386 SCIP_CALL( SCIPallocBufferArray(
scip, &indviolrank1conss, nconss) );
3389 SCIPdebugMsg(
scip,
"Check rank-1 constraints if there are any.\n");
3390 for (i = 0; i < nconss; ++i)
3392 consdata = SCIPconsGetData(conss[i]);
3393 assert( consdata != NULL );
3395 if ( consdata->rankone )
3398 if ( ! rank1result )
3401 indviolrank1conss[nviolrank1] = i;
3410 if ( nviolrank1 == 0 )
3412 SCIPdebugMsg(
scip,
"Found no violated rank-1 constraints.\n");
3413 SCIPfreeBufferArray(
scip, &indviolrank1conss);
3417 SCIPdebugMsg(
scip,
"Found %d violated rank-1 constraints, thus apply rank-1 approximation heuristic!\n", nviolrank1);
3420 nvars = SCIPgetNVars(
scip);
3421 SCIP_CALL( SCIPallocBufferArray(
scip, &rank1considx, nvars) );
3422 SCIP_CALL( SCIPallocBufferArray(
scip, &rank1consvars, nvars) );
3424 for (j = 0; j < nvars; ++j)
3425 rank1considx[j] = -1;
3427 for (c = 0; c < nviolrank1; ++c)
3429 assert( conss[indviolrank1conss[c]] != NULL );
3432 consdata = SCIPconsGetData(conss[indviolrank1conss[c]]);
3433 assert( consdata != NULL );
3435 nsdpvars = consdata->nvars;
3436 linrows += consdata->blocksize * (consdata->blocksize + 1) / 2;
3438 for (i = 0; i < nsdpvars; ++i)
3440 var = consdata->vars[i];
3441 idx = SCIPvarGetProbindex(var);
3442 assert( 0 <= idx && idx < nvars );
3443 if ( rank1considx[idx] < 0 )
3445 rank1consvars[nrank1vars] = var;
3446 rank1considx[idx] = nrank1vars++;
3452 SCIP_CALL( SCIPallocClearBufferArray(
scip, &linmatrix, linrows * nrank1vars) );
3453 SCIP_CALL( SCIPallocClearBufferArray(
scip, &rhsmatrix, MAX(linrows,nrank1vars)) );
3455 for (i = 0; i < nviolrank1; ++i)
3458 violcons = conss[indviolrank1conss[i]];
3459 consdata = SCIPconsGetData(violcons);
3461 assert( consdata != NULL );
3463 blocksize = consdata->blocksize;
3465 SCIPdebugMsg(
scip,
"\n Start with violated rank-1 constraint %s, is %d out of %d violated rank-1 constraints.\n\n", SCIPconsGetName(violcons), i + 1, nviolrank1);
3468 SCIP_CALL( SCIPallocBufferArray(
scip, &matrix, (blocksize * (blocksize+1))/2 ) );
3469 SCIP_CALL( SCIPallocBufferArray(
scip, &fullmatrix, blocksize * blocksize ) );
3470 SCIP_CALL( SCIPallocBufferArray(
scip, &eigenvalues, blocksize) );
3471 SCIP_CALL( SCIPallocBufferArray(
scip, &eigenvectors, blocksize * blocksize) );
3472 SCIP_CALL( SCIPallocBufferArray(
scip, &matrixC, blocksize * blocksize) );
3473 SCIP_CALL( SCIPallocBufferArray(
scip, &matrixAj, blocksize * blocksize) );
3474 SCIP_CALL( SCIPallocBufferArray(
scip, &linvars, consdata->nvars) );
3475 SCIP_CALL( SCIPallocBufferArray(
scip, &linvals, consdata->nvars) );
3483 #ifdef PRINTMATRICES 3485 printf(
"Full SDP-constraint matrix Z: \n");
3486 for (j = 0; j < blocksize; ++j)
3488 for (k = 0; k < blocksize; ++k)
3489 printf(
"%.5f ", fullmatrix[j*blocksize + k]);
3494 printf(
"Full SDP-constraint matrix Z in row-first format: \n");
3495 for (j = 0; j < blocksize * blocksize; ++j)
3496 printf(
"%.5f ", fullmatrix[j]);
3503 #ifdef PRINTMATRICES 3505 printf(
"Eigenvectors of Z: \n");
3506 for (j = 0; j < blocksize; ++j)
3508 for (k = 0; k < blocksize; ++k)
3509 printf(
"%.5f ", eigenvectors[k*blocksize + j]);
3514 printf(
"Eigenvectors of Z in column-first format: \n");
3515 for (j = 0; j < blocksize * blocksize; ++j)
3516 printf(
"%.5f ", eigenvectors[j]);
3519 printf(
"Eigenvalues of Z: \n");
3520 for (j = 0; j < blocksize; ++j)
3521 printf(
"%.5f ", eigenvalues[j]);
3526 SCIP_CALL( SCIPduplicateBufferArray(
scip, &scaledeigenvectors, eigenvectors, blocksize*blocksize) );
3530 for (j = 0; j < blocksize-1; ++j)
3532 assert( ! SCIPisFeasNegative(
scip, eigenvalues[j]) );
3533 eigenvalues[j] = 0.0;
3539 SCIP_CALL(
scaleRowsMatrix(blocksize, scaledeigenvectors, eigenvalues) );
3541 #ifdef PRINTMATRICES 3542 printf(
"Scaled eigenvectors of Z (only keep largest eigenvalue and corresponding eigenvector) : \n");
3543 for (j = 0; j < blocksize; ++j)
3545 for (k = 0; k < blocksize; ++k)
3547 printf(
"%.5f ", scaledeigenvectors[j*blocksize + k]);
3553 printf(
"Scaled eigenvectors of Z in row-first format: \n");
3554 for (j = 0; j < blocksize * blocksize; ++j)
3555 printf(
"%.5f ", scaledeigenvectors[j]);
3564 TRUE, fullmatrix) );
3566 #ifdef PRINTMATRICES 3567 printf(
"Best rank-1 approximation of Z: \n");
3568 for (j = 0; j < blocksize; ++j)
3570 for (k = 0; k < blocksize; ++k)
3571 printf(
"%.5f ", fullmatrix[j*blocksize + k]);
3576 printf(
"Best rank-1 approximation of Z in row-first format: \n");
3577 for (j = 0; j < blocksize * blocksize; ++j)
3578 printf(
"%.5f ", fullmatrix[j]);
3587 #ifdef PRINTMATRICES 3588 printf(
"Constant matrix A_0 of SDP-constraint: \n");
3589 for (j = 0; j < blocksize; ++j)
3591 for (k = 0; k < blocksize; ++k)
3592 printf(
"%.5f ", matrixC[j*blocksize + k]);
3597 printf(
"Constant matrix A_0 of SDP-constraint in row-first format: \n");
3598 for (j = 0; j < blocksize * blocksize; ++j)
3599 printf(
"%.5f ", matrixC[j]);
3603 for (j = 0; j < blocksize; ++j)
3605 for (k = 0; k <= j; ++k)
3607 for (l = 0; l < consdata->nvars; ++l)
3612 #ifdef PRINTMATRICES 3613 printf(
"Coefficient matrix A_%d of SDP-constraint: \n", l+1);
3614 for (r = 0; r < blocksize; ++r)
3616 for (s = 0; s < blocksize; ++s)
3617 printf(
"%.5f ", matrixAj[r*blocksize + s]);
3622 printf(
"Constant matrix A_0 of SDP-constraint in row-first format: \n");
3623 for (r = 0; r < blocksize * blocksize; ++r)
3624 printf(
"%.5f ", matrixAj[r]);
3628 idx = SCIPvarGetProbindex(consdata->vars[l]);
3629 idx = rank1considx[idx];
3630 assert( 0 <= idx && idx < nrank1vars );
3631 assert( lincnt <= linrows );
3632 linmatrix[lincnt * nrank1vars + idx] = matrixAj[j * blocksize + k];
3634 rhsmatrix[lincnt] = matrixC[j * blocksize + k] + fullmatrix[j * blocksize + k];
3640 SCIPfreeBufferArray(
scip, &linvals);
3641 SCIPfreeBufferArray(
scip, &linvars);
3642 SCIPfreeBufferArray(
scip, &matrixAj);
3643 SCIPfreeBufferArray(
scip, &matrixC);
3644 SCIPfreeBufferArray(
scip, &scaledeigenvectors);
3645 SCIPfreeBufferArray(
scip, &eigenvectors);
3646 SCIPfreeBufferArray(
scip, &eigenvalues);
3647 SCIPfreeBufferArray(
scip, &fullmatrix);
3648 SCIPfreeBufferArray(
scip, &matrix);
3651 assert( lincnt == linrows );
3653 #ifdef PRINTMATRICES 3654 printf(
"Matrix for linear equation system, in row-first format:\n");
3655 for (j = 0; j < linrows; ++j)
3657 for (k = 0; k < nrank1vars; ++k)
3659 printf(
"%.5f ", linmatrix[j * nrank1vars + k]);
3665 printf(
"Matrix for linear equation system in row-first format: \n");
3666 for (r = 0; r < linrows * nrank1vars; ++r)
3667 printf(
"%.5f ", linmatrix[r]);
3670 printf(
"Right-hand for linear equation system:\n");
3671 for (j = 0; j < nrank1vars; ++j)
3673 printf(
"%.5f ", rhsmatrix[j]);
3679 SCIP_CALL( SCIPallocBufferArray(
scip, &lssolu, nrank1vars) );
3682 SCIP_CALL( SCIPallocBufferArray(
scip, &colmatrix, linrows * nrank1vars ) );
3686 #ifdef PRINTMATRICES 3687 printf(
"Matrix for linear equation system, in col-first format:\n");
3688 for (j = 0; j < linrows; ++j)
3690 for (l = 0; l < nrank1vars; ++l)
3692 printf(
"%.5f ", colmatrix[l * linrows + j]);
3698 printf(
"Matrix for linear equation system in col-first format: \n");
3699 for (r = 0; r < linrows * nrank1vars; ++r)
3700 printf(
"%.5f ", colmatrix[r]);
3707 SCIP_CALL( SCIPcreateSolCopy(
scip, &bestrank1approx, sol) );
3710 for (i = 0; i < nrank1vars; ++i)
3712 var = rank1consvars[i];
3713 SCIP_CALL( SCIPsetSolVal(
scip, bestrank1approx, var, lssolu[i]) );
3716 SCIP_CALL( SCIPtrySolFree(
scip, &bestrank1approx, FALSE, TRUE, TRUE, TRUE, TRUE, &stored) );
3718 SCIPdebugMsg(
scip,
"Best Rank-1 Approximation Heuristic found feasible primal solution\n");
3720 SCIPdebugMsg(
scip,
"Primal solution found by Best Rank-1 Approximation Heuristic is not feasible!\n");
3722 SCIPfreeBufferArray(
scip, &colmatrix);
3723 SCIPfreeBufferArray(
scip, &lssolu);
3724 SCIPfreeBufferArray(
scip, &rhsmatrix);
3725 SCIPfreeBufferArray(
scip, &linmatrix);
3726 SCIPfreeBufferArray(
scip, &rank1consvars);
3727 SCIPfreeBufferArray(
scip, &rank1considx);
3728 SCIPfreeBufferArray(
scip, &indviolrank1conss);
3742 assert(
scip != NULL );
3743 assert( result != NULL );
3744 assert( conss != NULL );
3746 *result = SCIP_DIDNOTRUN;
3748 if ( objinfeasible )
3750 SCIPdebugMsg(
scip,
"-> pseudo solution is objective infeasible, return.\n");
3754 for (i = 0; i < nconss; ++i)
3758 if (*result == SCIP_INFEASIBLE)
3761 SCIPdebugMsg(
scip,
"-> pseudo solution infeasible for SDP-constraint %s, return.\n", SCIPconsGetName(conss[i]));
3766 *result = SCIP_FEASIBLE;
3768 SCIPdebugMsg(
scip,
"-> pseudo solution feasible for all SDP-constraints.\n");
3779 assert(
scip != NULL );
3780 assert( conshdlr != NULL );
3781 assert( conss != NULL );
3782 assert( result != NULL );
3792 assert(
scip != NULL );
3793 assert( conshdlr != NULL );
3794 assert( conss != NULL );
3795 assert( result != NULL );
3806 assert( result != NULL );
3807 *result = SCIP_DIDNOTFIND;
3809 for (i = 0; i < nusefulconss; ++i)
3823 assert( result != NULL );
3824 *result = SCIP_DIDNOTFIND;
3826 for (i = 0; i < nusefulconss; ++i)
3840 assert( cons != NULL );
3841 assert( consdata != NULL );
3843 SCIPdebugMsg(
scip,
"deleting SDP constraint <%s>.\n", SCIPconsGetName(cons));
3846 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->maxevsubmat, 2);
3848 for (i = 0; i < (*consdata)->nvars; i++)
3850 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->val[i], (*consdata)->nvarnonz[i]);
3851 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->row[i], (*consdata)->nvarnonz[i]);
3852 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->col[i], (*consdata)->nvarnonz[i]);
3856 for (i = 0; i < (*consdata)->nvars; i++)
3858 SCIP_CALL( SCIPreleaseVar(
scip, &((*consdata)->vars[i])) );
3861 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->vars, (*consdata)->nvars);
3862 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->locks, (*consdata)->nvars);
3863 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->constval, (*consdata)->constnnonz);
3864 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->constrow, (*consdata)->constnnonz);
3865 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->constcol, (*consdata)->constnnonz);
3866 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->val, (*consdata)->nvars);
3867 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->row, (*consdata)->nvars);
3868 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->col, (*consdata)->nvars);
3869 SCIPfreeBlockMemoryArrayNull(
scip, &(*consdata)->nvarnonz, (*consdata)->nvars);
3870 SCIPfreeBlockMemory(
scip, consdata);
3879 SCIP_CONSHDLRDATA* conshdlrdata;
3881 SCIPdebugMsg(
scip,
"Freeing constraint handler <%s>.\n", SCIPconshdlrGetName(conshdlr));
3883 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3884 assert( conshdlrdata != NULL );
3886 SCIPfreeMemory(
scip, &conshdlrdata);
3887 SCIPconshdlrSetData(conshdlr, NULL);
3896 assert(
scip != NULL);
3897 assert(conshdlr != NULL);
3898 assert(strcmp(SCIPconshdlrGetName(conshdlr),
CONSHDLR_NAME) == 0);
3911 assert(
scip != NULL);
3912 assert(conshdlr != NULL);
3926 char copyname[SCIP_MAXSTRLEN];
3927 SCIP_CONSDATA* sourcedata;
3929 SCIP_VAR** targetvars;
3936 assert(
scip != NULL );
3937 assert( sourcescip != NULL );
3938 assert( sourcecons != NULL );
3939 assert( valid != NULL );
3941 SCIPdebugMsg(
scip,
"Copying SDP constraint <%s>\n", SCIPconsGetName(sourcecons));
3947 if ( SCIPgetStage(sourcescip) <= SCIP_STAGE_EXITPRESOLVE )
3952 sourcedata = SCIPconsGetData(sourcecons);
3953 assert( sourcedata != NULL );
3954 assert( sourcedata->rankone || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(sourcecons)),
CONSHDLR_NAME) == 0 );
3955 assert( ! sourcedata->rankone || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(sourcecons)),
CONSHDLRRANK1_NAME) == 0 );
3957 SCIP_CALL( SCIPallocBufferArray(
scip, &targetvars, sourcedata->nvars) );
3960 for (i = 0; i < sourcedata->nvars; i++)
3962 SCIP_CALL( SCIPgetVarCopy(sourcescip,
scip, sourcedata->vars[i], &var, varmap, consmap, global, &success) );
3964 targetvars[i] = var;
3971 snprintfreturn = SCIPsnprintf(copyname, SCIP_MAXSTRLEN,
"c_%s",
name == NULL ? SCIPconsGetName(sourcecons) :
name);
3972 assert( snprintfreturn < SCIP_MAXSTRLEN );
3974 (void) SCIPsnprintf(copyname, SCIP_MAXSTRLEN,
"c_%s", name == NULL ? SCIPconsGetName(sourcecons) :
name);
3978 if ( ! sourcedata->rankone )
3980 SCIP_CALL(
SCIPcreateConsSdp(
scip, cons, copyname, sourcedata->nvars, sourcedata->nnonz, sourcedata->blocksize, sourcedata->nvarnonz,
3981 sourcedata->col, sourcedata->row, sourcedata->val, targetvars, sourcedata->constnnonz,
3982 sourcedata->constcol, sourcedata->constrow, sourcedata->constval) );
3986 SCIP_CALL(
SCIPcreateConsSdpRank1(
scip, cons, copyname, sourcedata->nvars, sourcedata->nnonz, sourcedata->blocksize, sourcedata->nvarnonz,
3987 sourcedata->col, sourcedata->row, sourcedata->val, targetvars, sourcedata->constnnonz,
3988 sourcedata->constcol, sourcedata->constrow, sourcedata->constval) );
3991 SCIPfreeBufferArray(
scip, &targetvars);
4000 #ifdef PRINT_HUMAN_READABLE 4001 SCIP_CONSDATA* consdata;
4002 SCIP_Real* fullmatrix;
4007 assert(
scip != NULL );
4008 assert( cons != NULL );
4010 consdata = SCIPconsGetData(cons);
4011 assert( consdata != NULL );
4013 SCIP_CALL( SCIPallocBufferArray(
scip, &fullmatrix, consdata->blocksize * consdata->blocksize) );
4016 SCIPinfoMessage(
scip, file,
"rank-1? %d\n", consdata->rankone);
4019 for (v = 0; v < consdata->nvars; v++)
4024 for (i = 0; i < consdata->blocksize; i++)
4026 for (j = 0; j < consdata->blocksize; j++)
4027 fullmatrix[i * consdata->blocksize + j] = 0.0;
4031 for (i = 0; i < consdata->nvarnonz[v]; i++)
4033 fullmatrix[consdata->row[v][i] * consdata->blocksize + consdata->col[v][i]] = consdata->val[v][i];
4034 fullmatrix[consdata->col[v][i] * consdata->blocksize + consdata->row[v][i]] = consdata->val[v][i];
4038 SCIPinfoMessage(
scip, file,
"+\n");
4039 for (i = 0; i < consdata->blocksize; i++)
4041 SCIPinfoMessage(
scip, file,
"( ");
4042 for (j = 0; j < consdata->blocksize; j++)
4043 SCIPinfoMessage(
scip, file,
"%g ", fullmatrix[i * consdata->blocksize + j]);
4044 SCIPinfoMessage(
scip, file,
")\n");
4046 SCIPinfoMessage(
scip, file,
"* %s\n", SCIPvarGetName(consdata->vars[v]));
4054 for (i = 0; i < consdata->blocksize; i++)
4056 for (j = 0; j < consdata->blocksize; j++)
4057 fullmatrix[i * consdata->blocksize + j] = 0.0;
4061 for (i = 0; i < consdata->constnnonz; i++)
4063 fullmatrix[consdata->constrow[i] * consdata->blocksize + consdata->constcol[i]] = consdata->constval[i];
4064 fullmatrix[consdata->constcol[i] * consdata->blocksize + consdata->constrow[i]] = consdata->constval[i];
4068 SCIPinfoMessage(
scip, file,
"-\n");
4069 for (i = 0; i < consdata->blocksize; i++)
4071 SCIPinfoMessage(
scip, file,
"( ");
4072 for (j = 0; j < consdata->blocksize; j++)
4073 SCIPinfoMessage(
scip, file,
"%g ", fullmatrix[i * consdata->blocksize + j]);
4074 SCIPinfoMessage(
scip, file,
")\n");
4076 SCIPinfoMessage(
scip, file,
">= 0\n");
4079 SCIPinfoMessage(
scip, file,
"rank-1? %d\n", consdata->rankone);
4081 SCIPfreeBufferArray(
scip, &fullmatrix);
4085 SCIP_CONSDATA* consdata;
4089 assert(
scip != NULL );
4090 assert( cons != NULL );
4092 consdata = SCIPconsGetData(cons);
4095 SCIPinfoMessage(
scip, file,
"%d\n", consdata->blocksize);
4098 SCIPinfoMessage(
scip, file,
" rank-1? %d\n", consdata->rankone);
4101 if ( consdata->constnnonz > 0 )
4103 SCIPinfoMessage(
scip, file,
" A_0: ");
4105 for (i = 0; i < consdata->constnnonz; i++)
4107 if ( i < consdata->constnnonz - 1 )
4108 SCIPinfoMessage(
scip, file,
"(%d,%d):%.15g, ", consdata->constrow[i], consdata->constcol[i], consdata->constval[i]);
4110 SCIPinfoMessage(
scip, file,
"(%d,%d):%.15g", consdata->constrow[i], consdata->constcol[i], consdata->constval[i]);
4112 SCIPinfoMessage(
scip, file,
"\n");
4116 for (v = 0; v < consdata->nvars; v++)
4118 SCIPinfoMessage(
scip, file,
" <%s>: ", SCIPvarGetName(consdata->vars[v]));
4119 for (i = 0; i < consdata->nvarnonz[v]; i++)
4121 if ( i < consdata->nvarnonz[v] - 1 || v < consdata->nvars - 1 )
4122 SCIPinfoMessage(
scip, file,
"(%d,%d):%.15g, ", consdata->row[v][i], consdata->col[v][i], consdata->val[v][i]);
4124 SCIPinfoMessage(
scip, file,
"(%d,%d):%.15g", consdata->row[v][i], consdata->col[v][i], consdata->val[v][i]);
4127 if (v < consdata->nvars - 1)
4129 SCIPinfoMessage(
scip, file,
"\n");
4141 SCIP_Bool parsesuccess;
4142 SCIP_CONSDATA* consdata = NULL;
4150 assert(
scip != NULL );
4151 assert( str != NULL );
4153 nvars = SCIPgetNVars(
scip);
4155 assert( success != NULL );
4159 SCIP_CALL( SCIPallocBlockMemory(
scip, &consdata) );
4160 consdata->nvars = 0;
4161 consdata->nnonz = 0;
4162 consdata->constnnonz = 0;
4163 consdata->rankone = 0;
4164 consdata->addedquadcons = FALSE;
4165 consdata->locks = NULL;
4167 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->nvarnonz, nvars) );
4168 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->col, nvars) );
4169 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->row, nvars) );
4170 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->val, nvars) );
4171 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->vars, nvars));
4173 consdata->constcol = NULL;
4174 consdata->constrow = NULL;
4175 consdata->constval = NULL;
4178 parsesuccess = SCIPstrToIntValue(str, &(consdata->blocksize), &pos);
4179 *success = *success && parsesuccess;
4182 while ( isspace((
unsigned char)*pos) )
4186 if ( pos[0] ==
'r' && pos[1] ==
'a' && pos[2] ==
'n' && pos[3] ==
'k' && pos[4] ==
'-' && pos[5] ==
'1' && pos[6] ==
'?' )
4189 parsesuccess = SCIPstrToIntValue(pos, &rankoneint, &pos);
4190 consdata->rankone = (SCIP_Bool) rankoneint;
4191 *success = *success && parsesuccess;
4193 printf(
"rank-1? %d\n", rankoneint);
4197 while( isspace((
unsigned char)*pos) )
4201 if ( pos[0] ==
'A' && pos[1] ==
'_' && pos[2] ==
'0' )
4212 while (pos[0] ==
'(')
4217 if ( consdata->constnnonz == currentsize )
4219 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->constcol, currentsize,
PARSE_SIZEFACTOR * currentsize) );
4220 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->constrow, currentsize,
PARSE_SIZEFACTOR * currentsize) );
4221 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->constval, currentsize,
PARSE_SIZEFACTOR * currentsize) );
4225 parsesuccess = SCIPstrToIntValue(pos, &(consdata->constrow[consdata->constnnonz]), &pos);
4226 *success = *success && parsesuccess;
4227 assert( consdata->constrow[consdata->constnnonz] < consdata->blocksize );
4229 parsesuccess = SCIPstrToIntValue(pos, &(consdata->constcol[consdata->constnnonz]), &pos);
4230 *success = *success && parsesuccess;
4231 assert( consdata->constcol[consdata->constnnonz] < consdata->blocksize );
4233 parsesuccess = SCIPstrToRealValue(pos, &(consdata->constval[consdata->constnnonz]), &pos);
4234 *success = *success && parsesuccess;
4238 if ( consdata->constcol[consdata->constnnonz] > consdata->constrow[consdata->constnnonz] )
4240 i = consdata->constcol[consdata->constnnonz];
4241 consdata->constcol[consdata->constnnonz] = consdata->constrow[consdata->constnnonz];
4242 consdata->constrow[consdata->constnnonz] = i;
4245 consdata->constnnonz++;
4248 while( isspace((
unsigned char)*pos) )
4253 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->constcol, currentsize, consdata->constnnonz) );
4254 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->constrow, currentsize, consdata->constnnonz) );
4255 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->constval, currentsize, consdata->constnnonz) );
4259 while( isspace((
unsigned char)*pos) )
4265 while ( pos[0] ==
'<' )
4268 SCIP_CALL( SCIPparseVarName(
scip, pos, &(consdata->vars[consdata->nvars]), &pos) );
4269 SCIP_CALL( SCIPcaptureVar(
scip, consdata->vars[consdata->nvars]) );
4271 consdata->nvarnonz[consdata->nvars] = 0;
4272 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &(consdata->col[consdata->nvars]),
PARSE_STARTSIZE));
4273 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &(consdata->row[consdata->nvars]),
PARSE_STARTSIZE));
4274 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &(consdata->val[consdata->nvars]),
PARSE_STARTSIZE));
4281 while (pos[0] ==
'(')
4286 if ( consdata->nvarnonz[consdata->nvars - 1] == currentsize )
4288 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->col[consdata->nvars - 1], currentsize,
PARSE_SIZEFACTOR * currentsize) );
4289 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->row[consdata->nvars - 1], currentsize,
PARSE_SIZEFACTOR * currentsize) );
4290 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->val[consdata->nvars - 1], currentsize,
PARSE_SIZEFACTOR * currentsize) );
4294 parsesuccess = SCIPstrToIntValue(pos, &(consdata->row[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]]), &pos);
4295 *success = *success && parsesuccess;
4296 assert( consdata->row[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]] < consdata->blocksize );
4298 parsesuccess = SCIPstrToIntValue(pos, &(consdata->col[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]]), &pos);
4299 *success = *success && parsesuccess;
4300 assert( consdata->col[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]] < consdata->blocksize );
4302 parsesuccess = SCIPstrToRealValue(pos, &(consdata->val[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]]), &pos);
4303 *success = *success && parsesuccess;
4308 if ( consdata->col[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]] >
4309 consdata->row[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]] )
4311 i = consdata->col[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]];
4312 consdata->col[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]] =
4313 consdata->row[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]];
4314 consdata->row[consdata->nvars - 1][consdata->nvarnonz[consdata->nvars - 1]] = i;
4317 consdata->nvarnonz[consdata->nvars - 1]++;
4320 while( isspace((
unsigned char)*pos) )
4325 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->col[consdata->nvars - 1], currentsize, consdata->nvarnonz[consdata->nvars - 1]) );
4326 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->row[consdata->nvars - 1], currentsize, consdata->nvarnonz[consdata->nvars - 1]) );
4327 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->val[consdata->nvars - 1], currentsize, consdata->nvarnonz[consdata->nvars - 1]) );
4330 while ( isspace((
unsigned char)*pos) )
4335 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->nvarnonz, nvars, consdata->nvars) );
4336 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->col, nvars, consdata->nvars) );
4337 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->row, nvars, consdata->nvars) );
4338 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->val, nvars, consdata->nvars) );
4339 SCIP_CALL( SCIPreallocBlockMemoryArray(
scip, &consdata->vars, nvars, consdata->nvars));
4342 for (v = 0; v < consdata->nvars; v++)
4343 consdata->nnonz += consdata->nvarnonz[v];
4346 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->maxevsubmat, 2) );
4347 consdata->maxevsubmat[0] = -1;
4348 consdata->maxevsubmat[1] = -1;
4351 SCIP_CALL( SCIPcreateCons(
scip, cons,
name, conshdlr, consdata, initial, separate, enforce, check, propagate, local, modifiable,
4352 dynamic, removable, stickingatnode) );
4357 #ifdef SCIP_MORE_DEBUG 4358 SCIP_CALL( SCIPprintCons(
scip, *cons, NULL) );
4368 SCIP_CONSDATA* consdata;
4372 assert(
scip != NULL );
4373 assert( cons != NULL );
4374 assert( vars != NULL );
4375 assert( success != NULL );
4376 assert( varssize >= 0 );
4378 consdata = SCIPconsGetData(cons);
4379 assert( consdata != NULL );
4381 nvars = consdata->nvars;
4383 if ( nvars > varssize )
4385 SCIPdebugMsg(
scip,
"consGetVarsIndicator called for array of size %d, needed size %d.\n", varssize, nvars);
4390 for (i = 0; i < nvars; i++)
4391 vars[i] = consdata->vars[i];
4402 SCIP_CONSDATA* consdata;
4404 assert(
scip != NULL );
4405 assert( cons != NULL );
4406 assert( nvars != NULL );
4407 assert( success != NULL );
4409 consdata = SCIPconsGetData(cons);
4410 assert( consdata != NULL );
4412 *nvars = consdata->nvars;
4423 SCIP_CONSHDLR* conshdlr = NULL;
4424 SCIP_CONSHDLRDATA* conshdlrdata = NULL;
4426 assert(
scip != NULL );
4429 SCIP_CALL( SCIPallocMemory(
scip, &conshdlrdata) );
4430 conshdlrdata->quadconsrank1 = FALSE;
4431 conshdlrdata->upgradquadconss = FALSE;
4432 conshdlrdata->upgradekeepquad = FALSE;
4433 conshdlrdata->quadconsidx = NULL;
4434 conshdlrdata->quadconsvars = NULL;
4435 conshdlrdata->nquadconsidx = 0;
4436 conshdlrdata->X = NULL;
4437 conshdlrdata->nsdpvars = 0;
4438 conshdlrdata->sdpcons = NULL;
4439 conshdlrdata->triedlinearconss = FALSE;
4440 conshdlrdata->sdpconshdlrdata = conshdlrdata;
4445 consEnfolpSdp, consEnfopsSdp, consCheckSdp, consLockSdp, conshdlrdata) );
4447 assert( conshdlr != NULL );
4450 SCIP_CALL( SCIPsetConshdlrDelete(
scip, conshdlr, consDeleteSdp) );
4451 SCIP_CALL( SCIPsetConshdlrFree(
scip, conshdlr, consFreeSdp) );
4452 SCIP_CALL( SCIPsetConshdlrCopy(
scip, conshdlr, conshdlrCopySdp, consCopySdp) );
4453 SCIP_CALL( SCIPsetConshdlrInitpre(
scip, conshdlr,consInitpreSdp) );
4454 SCIP_CALL( SCIPsetConshdlrExit(
scip, conshdlr, consExitSdp) );
4455 SCIP_CALL( SCIPsetConshdlrExitpre(
scip, conshdlr, consExitpreSdp) );
4456 SCIP_CALL( SCIPsetConshdlrInitsol(
scip, conshdlr, consInitsolSdp) );
4460 SCIP_CALL( SCIPsetConshdlrEnforelax(
scip, conshdlr, consEnforelaxSdp) );
4461 SCIP_CALL( SCIPsetConshdlrTrans(
scip, conshdlr, consTransSdp) );
4462 SCIP_CALL( SCIPsetConshdlrPrint(
scip, conshdlr, consPrintSdp) );
4463 SCIP_CALL( SCIPsetConshdlrParse(
scip, conshdlr, consParseSdp) );
4464 SCIP_CALL( SCIPsetConshdlrGetVars(
scip, conshdlr, consGetVarsSdp) );
4465 SCIP_CALL( SCIPsetConshdlrGetNVars(
scip, conshdlr, consGetNVarsSdp) );
4469 SCIP_CALL( SCIPaddIntParam(
scip,
"constraints/SDP/threads",
"number of threads used for OpenBLAS",
4470 &(conshdlrdata->nthreads), TRUE, DEFAULT_NTHREADS, 1, INT_MAX, NULL, NULL) );
4472 SCIP_CALL( SCIPaddBoolParam(
scip,
"constraints/SDP/diaggezerocuts",
4473 "Should linear cuts enforcing the non-negativity of diagonal entries of SDP-matrices be added?",
4476 SCIP_CALL( SCIPaddBoolParam(
scip,
"constraints/SDP/diagzeroimplcuts",
4477 "Should linear cuts enforcing the implications of diagonal entries of zero in SDP-matrices be added?",
4480 SCIP_CALL( SCIPaddBoolParam(
scip,
"constraints/SDP/twominorlinconss",
4481 "Should linear cuts corresponding to 2 by 2 minors be added?",
4484 SCIP_CALL( SCIPaddBoolParam(
scip,
"constraints/SDP/twominorprodconss",
4485 "Should linear cuts corresponding to products of 2 by 2 minors be added?",
4488 SCIP_CALL( SCIPaddBoolParam(
scip,
"constraints/SDP/quadconsrank1",
4489 "Should quadratic cons for 2x2 minors be added in the rank-1 case?",
4492 SCIP_CALL( SCIPaddBoolParam(
scip,
"constraints/SDP/upgradquadconss",
4493 "Should quadratic constraints be upgraded to a rank 1 SDP?",
4496 SCIP_CALL( SCIPaddBoolParam(
scip,
"constraints/SDP/upgradekeepquad",
4497 "Should the quadratic constraints be kept in the problem after upgrading and the corresponding SDP constraint be added without the rank 1 constraint?",
4500 SCIP_CALL( SCIPaddIntParam(
scip,
"constraints/SDP/maxnvarsquadupgd",
4501 "maximal number of quadratic constraints and appearing variables so that the QUADCONSUPGD is performed",
4504 SCIP_CALL( SCIPaddBoolParam(
scip,
"constraints/SDP/rank1approxheur",
4505 "Should the heuristic that computes the best rank-1 approximation for a given solution be executed?",
4516 SCIP_CONSHDLR* conshdlr = NULL;
4517 SCIP_CONSHDLR* sdpconshdlr;
4518 SCIP_CONSHDLRDATA* conshdlrdata = NULL;
4520 assert(
scip != NULL );
4523 SCIP_CALL( SCIPallocMemory(
scip, &conshdlrdata) );
4526 conshdlrdata->diaggezerocuts = FALSE;
4527 conshdlrdata->diagzeroimplcuts = FALSE;
4528 conshdlrdata->triedlinearconss = FALSE;
4529 conshdlrdata->quadconsrank1 = FALSE;
4530 conshdlrdata->rank1approxheur = FALSE;
4531 conshdlrdata->maxnvarsquadupgd = 0;
4535 if ( sdpconshdlr == NULL )
4537 SCIPerrorMessage(
"Needs constraint handler <%s> to work.\n",
CONSHDLR_NAME);
4538 return SCIP_PLUGINNOTFOUND;
4540 conshdlrdata->sdpconshdlrdata = SCIPconshdlrGetData(sdpconshdlr);
4541 assert( conshdlrdata->sdpconshdlrdata != NULL );
4543 conshdlrdata->quadconsidx = NULL;
4544 conshdlrdata->quadconsvars = NULL;
4545 conshdlrdata->nquadconsidx = 0;
4546 conshdlrdata->X = NULL;
4547 conshdlrdata->nsdpvars = 0;
4548 conshdlrdata->sdpcons = NULL;
4553 consEnfolpSdp, consEnfopsSdp, consCheckSdp, consLockSdp, conshdlrdata) );
4555 assert( conshdlr != NULL );
4558 SCIP_CALL( SCIPsetConshdlrDelete(
scip, conshdlr, consDeleteSdp) );
4559 SCIP_CALL( SCIPsetConshdlrFree(
scip, conshdlr, consFreeSdp) );
4560 SCIP_CALL( SCIPsetConshdlrCopy(
scip, conshdlr, conshdlrCopySdpRank1, consCopySdp) );
4561 SCIP_CALL( SCIPsetConshdlrInitpre(
scip, conshdlr,consInitpreSdp) );
4562 SCIP_CALL( SCIPsetConshdlrExit(
scip, conshdlr, consExitSdp) );
4563 SCIP_CALL( SCIPsetConshdlrExitpre(
scip, conshdlr, consExitpreSdp) );
4564 SCIP_CALL( SCIPsetConshdlrInitsol(
scip, conshdlr, consInitsolSdp) );
4568 SCIP_CALL( SCIPsetConshdlrEnforelax(
scip, conshdlr, consEnforelaxSdp) );
4569 SCIP_CALL( SCIPsetConshdlrTrans(
scip, conshdlr, consTransSdp) );
4570 SCIP_CALL( SCIPsetConshdlrPrint(
scip, conshdlr, consPrintSdp) );
4571 SCIP_CALL( SCIPsetConshdlrParse(
scip, conshdlr, consParseSdp) );
4572 SCIP_CALL( SCIPsetConshdlrGetVars(
scip, conshdlr, consGetVarsSdp) );
4573 SCIP_CALL( SCIPsetConshdlrGetNVars(
scip, conshdlr, consGetNVarsSdp) );
4592 return i*(i+1)/2 + j;
4619 SCIP_Real* constval,
4622 SCIP_Bool* addedquadcons
4625 SCIP_CONSDATA* consdata;
4628 assert(
scip != NULL );
4629 assert( cons != NULL );
4630 assert( nvars != NULL );
4631 assert( nnonz != NULL );
4632 assert( blocksize != NULL );
4633 assert( arraylength != NULL );
4634 assert( nvarnonz != NULL );
4635 assert( col != NULL );
4636 assert( row != NULL );
4637 assert( val != NULL );
4638 assert( vars != NULL );
4639 assert( constnnonz != NULL );
4641 consdata = SCIPconsGetData(cons);
4643 assert( consdata->constnnonz == 0 || ( constcol != NULL && constrow != NULL && constval != NULL ) );
4645 *nvars = consdata->nvars;
4646 *nnonz = consdata->nnonz;
4647 *blocksize = consdata->blocksize;
4649 for (i = 0; i < consdata->nvars; i++)
4650 vars[i] = consdata->vars[i];
4653 if ( *arraylength < consdata->nvars )
4655 SCIPdebugMsg(
scip,
"nvarnonz, col, row and val arrays were not long enough to store the information for cons %s, they need to be at least" 4656 "size %d, given was only length %d! \n", SCIPconsGetName(cons), consdata->nvars, *arraylength);
4657 *arraylength = consdata->nvars;
4661 for (i = 0; i < consdata->nvars; i++)
4663 nvarnonz[i] = consdata->nvarnonz[i];
4665 col[i] = consdata->col[i];
4666 row[i] = consdata->row[i];
4667 val[i] = consdata->val[i];
4672 if ( consdata->constnnonz > 0 )
4674 if ( consdata->constnnonz > *constnnonz )
4676 SCIPdebugMsg(
scip,
"The constant nonzeros arrays were not long enough to store the information for cons %s, they need to be at least" 4677 "size %d, given was only length %d! \n", SCIPconsGetName(cons), consdata->constnnonz, *constnnonz);
4681 for (i = 0; i < consdata->constnnonz; i++)
4683 constcol[i] = consdata->constcol[i];
4684 constrow[i] = consdata->constrow[i];
4685 constval[i] = consdata->constval[i];
4690 *constnnonz = consdata->constnnonz;
4694 if ( rankone != NULL && maxevsubmat != NULL )
4696 *rankone = consdata->rankone;
4697 *maxevsubmat[0] = consdata->maxevsubmat[0];
4698 *maxevsubmat[1] = consdata->maxevsubmat[1];
4699 *addedquadcons = consdata->addedquadcons;
4716 SCIP_CONSDATA* consdata;
4718 assert(
scip != NULL );
4719 assert( cons != NULL );
4721 consdata = SCIPconsGetData(cons);
4722 assert( consdata != NULL );
4724 if ( nnonz != NULL )
4725 *nnonz = consdata->nnonz;
4727 if ( constnnonz != NULL )
4728 *constnnonz = consdata->constnnonz;
4739 SCIP_CONSDATA* consdata;
4741 assert(
scip != NULL );
4742 assert( cons != NULL );
4744 consdata = SCIPconsGetData(cons);
4745 assert( consdata != NULL );
4747 return consdata->blocksize;
4758 SCIP_CONSDATA* consdata;
4762 assert(
scip != NULL );
4763 assert( cons != NULL );
4765 assert( Aj != NULL );
4767 consdata = SCIPconsGetData(cons);
4768 assert( consdata != NULL );
4769 blocksize = consdata->blocksize;
4771 assert( j < consdata->nvars );
4773 for (i = 0; i < blocksize * blocksize; i++)
4776 for (i = 0; i < consdata->nvarnonz[j]; i++)
4778 Aj[consdata->col[j][i] * blocksize + consdata->row[j][i]] = consdata->val[j][i];
4779 Aj[consdata->row[j][i] * blocksize + consdata->col[j][i]] = consdata->val[j][i];
4792 SCIP_CONSDATA* consdata;
4797 assert(
scip != NULL );
4798 assert( cons != NULL );
4799 assert( mat != NULL );
4801 consdata = SCIPconsGetData(cons);
4802 blocksize = consdata->blocksize;
4804 for (i = 0; i < blocksize; i++)
4806 for (j = 0; j < blocksize; j++)
4807 mat[i * blocksize + j] = 0.0;
4810 for (i = 0; i < consdata->constnnonz; i++)
4812 mat[consdata->constcol[i] * blocksize + consdata->constrow[i]] = consdata->constval[i];
4813 mat[consdata->constrow[i] * blocksize + consdata->constcol[i]] = consdata->constval[i];
4826 SCIP_CONSDATA* consdata;
4830 assert(
scip != NULL );
4831 assert( cons != NULL );
4832 assert( mat != NULL );
4834 consdata = SCIPconsGetData(cons);
4835 assert( consdata != NULL );
4837 blocksize = consdata->blocksize;
4840 for (i = 0; i < (blocksize * (blocksize + 1)) / 2; i++)
4843 for (i = 0; i < consdata->constnnonz; i++)
4862 SCIP_Real* lambdastar
4865 SCIP_CONSDATA* consdata;
4867 SCIP_Real maxinfnorm;
4869 SCIP_Real mininfnorm;
4872 SCIP_Real primalguess;
4873 SCIP_Real dualguess;
4879 assert(
scip != NULL );
4880 assert( cons != NULL );
4881 assert( lambdastar != NULL );
4882 assert( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)),
CONSHDLR_NAME) == 0 || strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)),
CONSHDLRRANK1_NAME) == 0 );
4884 consdata = SCIPconsGetData(cons);
4885 assert( consdata != NULL );
4891 if ( consdata->nnonz == 0 )
4893 *lambdastar = 100.0;
4897 blocksize = consdata->blocksize;
4899 sparsity = consdata->nnonz / (0.5 * blocksize * (blocksize + 1));
4903 mininfnorm = SCIPinfinity(
scip);
4904 for (v = 0; v < consdata->nvars; v++)
4906 for (i = 0; i < consdata->nvarnonz[v]; i++)
4908 if ( SCIPisGT(
scip, REALABS(consdata->val[v][i]), maxinfnorm ) )
4909 maxinfnorm = REALABS(consdata->val[v][i]);
4910 if ( SCIPisLT(
scip, REALABS(consdata->val[v][i]), mininfnorm) )
4911 mininfnorm = REALABS(consdata->val[v][i]);
4915 for (i = 0; i < consdata->constnnonz; i++)
4917 if ( SCIPisGT(
scip, REALABS(consdata->constval[i]), maxconst ) )
4918 maxconst = REALABS(consdata->constval[i]);
4921 assert( SCIPisGT(
scip, mininfnorm, 0.0) );
4926 for (v = 0; v < consdata->nvars; v++)
4928 if ( SCIPisGT(
scip, REALABS(SCIPvarGetObj(consdata->vars[v])), maxobj) )
4929 maxobj = REALABS(SCIPvarGetObj(consdata->vars[v]));
4930 compval = SCIPisInfinity(
scip, REALABS(SCIPvarGetUbGlobal(consdata->vars[v]))) ? 1e+6 : REALABS(SCIPvarGetUbGlobal(consdata->vars[v]));
4931 if ( SCIPisGT(
scip, compval, maxbound) )
4933 compval = SCIPisInfinity(
scip, REALABS(SCIPvarGetLbGlobal(consdata->vars[v]))) ? 1e+6 : REALABS(SCIPvarGetUbGlobal(consdata->vars[v]));
4934 if ( SCIPisGT(
scip, compval, maxbound) )
4939 if ( SCIPisEQ(
scip, maxbound, 0.0) )
4943 primalguess = maxobj / (sparsity * mininfnorm);
4944 dualguess = sparsity * maxinfnorm * maxbound + maxconst;
4946 if ( SCIPisGT(
scip, primalguess, dualguess) )
4947 *lambdastar = primalguess;
4949 *lambdastar = dualguess;
4960 SCIP_CONSDATA* consdata;
4962 assert(
scip != NULL );
4963 assert( cons != NULL );
4965 consdata = SCIPconsGetData(cons);
4967 return consdata->maxrhsentry;
4976 SCIP_CONSDATA* consdata;
4981 assert(
scip != NULL );
4982 assert( cons != NULL );
4984 consdata = SCIPconsGetData(cons);
4988 for (v = 0; v < consdata->nvars; v++)
4990 for (i = 0; i < consdata->nvarnonz[v]; i++)
4992 if ( SCIPisGT(
scip, REALABS(consdata->val[v][i]), maxcoef) )
4993 maxcoef = REALABS(consdata->val[v][i]);
5009 SCIP_CONSDATA* consdata;
5014 assert( cons != NULL );
5016 consdata = SCIPconsGetData(cons);
5017 assert( consdata != NULL );
5019 ub = consdata->constnnonz;
5021 for (v = 0; v < consdata->nvars; v++)
5022 ub += consdata->nvarnonz[v];
5024 denselength = consdata->blocksize * (consdata->blocksize + 1) / 2;
5026 return (ub <= denselength ? ub : denselength);
5044 SCIP_CONSDATA* consdata;
5049 assert(
scip != NULL );
5050 assert( cons != NULL );
5051 assert( sol != NULL );
5052 assert( length != NULL );
5053 assert( row != NULL );
5054 assert( col != NULL );
5055 assert( val != NULL );
5057 consdata = SCIPconsGetData(cons);
5058 assert( consdata != NULL );
5061 nnonz = consdata->constnnonz;
5062 if ( *length < nnonz )
5065 SCIPerrorMessage(
"Arrays not long enough in SCIPconsSdpComputeSparseSdpMatrix, length %d given, need at least %d (probably more)\n",
5070 for (i = 0; i < consdata->constnnonz; i++)
5072 row[i] = consdata->constrow[i];
5073 col[i] = consdata->constcol[i];
5074 val[i] = -1 * consdata->constval[i];
5078 for (v = 0; v < consdata->nvars; v++)
5081 FALSE, SCIPgetSolVal(
scip, sol, consdata->vars[v]), row, col, val, &nnonz, *length) );
5082 if ( nnonz > *length )
5085 SCIPerrorMessage(
"Arrays not long enough in SCIPconsSdpComputeSparseSdpMatrix, length %d given, need at least %d (probably more)\n",
5102 SCIP_CONSDATA* consdata;
5104 assert( cons != NULL );
5106 consdata = SCIPconsGetData(cons);
5107 assert( consdata != NULL );
5109 return consdata->rankone;
5119 SCIP_CONSDATA* consdata;
5121 assert( cons != NULL );
5123 consdata = SCIPconsGetData(cons);
5124 assert( consdata != NULL );
5125 assert( maxevsubmat != NULL );
5127 *maxevsubmat[0] = consdata->maxevsubmat[0];
5128 *maxevsubmat[1] = consdata->maxevsubmat[1];
5138 SCIP_CONSDATA* consdata;
5140 assert( cons != NULL );
5142 consdata = SCIPconsGetData(cons);
5143 assert( consdata != NULL );
5145 return consdata->addedquadcons;
5167 SCIP_CONSHDLR* conshdlr;
5168 SCIP_CONSDATA* consdata = NULL;
5172 assert(
scip != NULL );
5173 assert( cons != NULL );
5174 assert(
name != NULL );
5175 assert( nvars >= 0 );
5176 assert( nnonz >= 0 );
5177 assert( blocksize >= 0 );
5178 assert( constnnonz >= 0 );
5179 assert( nvars == 0 || vars != NULL );
5180 assert( nnonz == 0 || (nvarnonz != NULL && col != NULL && row != NULL && val != NULL ));
5181 assert( constnnonz == 0 || (constcol != NULL && constrow != NULL && constval != NULL ));
5183 conshdlr = SCIPfindConshdlr(
scip,
"SDP");
5184 if ( conshdlr == NULL )
5186 SCIPerrorMessage(
"SDP constraint handler not found\n");
5187 return SCIP_PLUGINNOTFOUND;
5191 SCIP_CALL( SCIPallocBlockMemory(
scip, &consdata) );
5192 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->nvarnonz, nvars) );
5193 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->col, nvars) );
5194 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->row, nvars) );
5195 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->val, nvars) );
5196 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->constcol, constnnonz) );
5197 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->constrow, constnnonz) );
5198 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->constval, constnnonz) );
5199 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->vars, nvars) );
5201 for (i = 0; i < nvars; i++)
5203 assert( nvarnonz[i] >= 0 );
5205 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->col[i], nvarnonz[i]));
5206 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->row[i], nvarnonz[i]));
5207 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->val[i], nvarnonz[i]));
5210 consdata->nvars = nvars;
5211 consdata->nnonz = nnonz;
5212 consdata->constnnonz = constnnonz;
5213 consdata->blocksize = blocksize;
5214 consdata->locks = NULL;
5216 for (i = 0; i < nvars; i++)
5218 consdata->nvarnonz[i] = nvarnonz[i];
5220 for (j = 0; j < nvarnonz[i]; j++)
5222 assert( col[i][j] >= 0 );
5223 assert( col[i][j] < blocksize );
5224 assert( row[i][j] >= 0 );
5225 assert( row[i][j] < blocksize );
5227 consdata->col[i][j] = col[i][j];
5228 consdata->row[i][j] = row[i][j];
5229 consdata->val[i][j] = val[i][j];
5233 for (i = 0; i < constnnonz; i++)
5235 consdata->constcol[i] = constcol[i];
5236 consdata->constrow[i] = constrow[i];
5237 consdata->constval[i] = constval[i];
5240 for (i = 0; i < nvars; i++)
5242 consdata->vars[i] = vars[i];
5243 SCIP_CALL( SCIPcaptureVar(
scip, consdata->vars[i]) );
5245 SCIPdebugMsg(
scip,
"creating cons %s.\n",
name);
5247 consdata->rankone = FALSE;
5250 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->maxevsubmat, 2) );
5251 consdata->maxevsubmat[0] = -1;
5252 consdata->maxevsubmat[1] = -1;
5255 consdata->addedquadcons = FALSE;
5258 SCIP_CALL( SCIPcreateCons(
scip, cons,
name, conshdlr, consdata, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
5286 SCIP_CONSHDLR* conshdlr;
5287 SCIP_CONSDATA* consdata = NULL;
5291 assert(
scip != NULL );
5292 assert( cons != NULL );
5293 assert(
name != NULL );
5294 assert( nvars >= 0 );
5295 assert( nnonz >= 0 );
5296 assert( blocksize >= 0 );
5297 assert( constnnonz >= 0 );
5298 assert( nvars == 0 || vars != NULL );
5299 assert( nnonz == 0 || (nvarnonz != NULL && col != NULL && row != NULL && val != NULL ));
5300 assert( constnnonz == 0 || (constcol != NULL && constrow != NULL && constval != NULL ));
5303 if ( conshdlr == NULL )
5305 SCIPerrorMessage(
"Rank 1 SDP constraint handler not found\n");
5306 return SCIP_PLUGINNOTFOUND;
5310 SCIP_CALL( SCIPallocBlockMemory(
scip, &consdata) );
5311 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->nvarnonz, nvars) );
5312 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->col, nvars) );
5313 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->row, nvars) );
5314 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->val, nvars) );
5315 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->constcol, constnnonz) );
5316 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->constrow, constnnonz) );
5317 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->constval, constnnonz) );
5318 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->vars, nvars) );
5320 for (i = 0; i < nvars; i++)
5322 assert( nvarnonz[i] >= 0 );
5324 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->col[i], nvarnonz[i]));
5325 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->row[i], nvarnonz[i]));
5326 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->val[i], nvarnonz[i]));
5329 consdata->nvars = nvars;
5330 consdata->nnonz = nnonz;
5331 consdata->constnnonz = constnnonz;
5332 consdata->blocksize = blocksize;
5333 consdata->locks = NULL;
5335 for (i = 0; i < nvars; i++)
5337 consdata->nvarnonz[i] = nvarnonz[i];
5339 for (j = 0; j < nvarnonz[i]; j++)
5341 assert( col[i][j] >= 0 );
5342 assert( col[i][j] < blocksize );
5343 assert( row[i][j] >= 0 );
5344 assert( row[i][j] < blocksize );
5346 consdata->col[i][j] = col[i][j];
5347 consdata->row[i][j] = row[i][j];
5348 consdata->val[i][j] = val[i][j];
5352 for (i = 0; i < constnnonz; i++)
5354 consdata->constcol[i] = constcol[i];
5355 consdata->constrow[i] = constrow[i];
5356 consdata->constval[i] = constval[i];
5359 for (i = 0; i < nvars; i++)
5361 consdata->vars[i] = vars[i];
5362 SCIP_CALL( SCIPcaptureVar(
scip, consdata->vars[i]) );
5364 SCIPdebugMsg(
scip,
"creating cons %s (rank 1).\n",
name);
5365 consdata->rankone = TRUE;
5368 SCIP_CALL( SCIPallocBlockMemoryArray(
scip, &consdata->maxevsubmat, 2) );
5369 consdata->maxevsubmat[0] = -1;
5370 consdata->maxevsubmat[1] = -1;
5373 consdata->addedquadcons = FALSE;
5376 SCIP_CALL( SCIPcreateCons(
scip, cons,
name, conshdlr, consdata, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
SCIP_Real SCIPconsSdpGetMaxConstEntry(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_CONSTRANS(consTransSdp)
static SCIP_RETCODE addTwoMinorProdConstraints(SCIP *scip, SCIP_CONS **conss, int nconss, int *naddconss)
int SCIPconsSdpComputeUbSparseSdpMatrixLength(SCIP_CONS *cons)
static SCIP_RETCODE separateSol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RESULT *result)
#define DEFAULT_QUADCONSRANK1
SCIP_RETCODE SCIPconsSdpGetFullAj(SCIP *scip, SCIP_CONS *cons, int j, SCIP_Real *Aj)
SCIP_RETCODE SCIPcreateConsSdpRank1(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 SCIPsdpVarfixerSortRowCol(int *row, int *col, SCIP_Real *val, int length)
static SCIP_RETCODE convertRowToColFormatFullMatrix(int rows, int cols, SCIP_Real *rowmatrix, SCIP_Real *colmatrix)
#define CONSHDLR_PRESOLTIMING
SCIP_RETCODE SCIPincludeConshdlrSdp(SCIP *scip)
static SCIP_RETCODE multiplyConstraintMatrix(SCIP_CONS *cons, int j, SCIP_Real *v, SCIP_Real *vAv)
static SCIP_DECL_CONSENFORELAX(consEnforelaxSdp)
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, SCIP_SOL *sol, SCIP_RESULT *result)
#define CONSHDLR_NEEDSCONS
#define DEFAULT_TWOMINORPRODCONSS
static SCIP_DECL_CONSDELETE(consDeleteSdp)
SCIP_Bool SCIPconsSdpAddedQuadCons(SCIP_CONS *cons)
#define CONSHDLR_SEPAFREQ
static SCIP_DECL_CONSEXIT(consExitSdp)
#define CONSHDLR_DELAYSEPA
static SCIP_RETCODE computeSdpMatrix(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *y, SCIP_Real *matrix)
static SCIP_RETCODE checkVarsLocks(SCIP *scip, SCIP_CONS *cons)
#define CONSHDLR_EAGERFREQ
#define DEFAULT_MAXNVARSQUADUPGD
#define DEFAULT_DIAGGEZEROCUTS
SCIP_RETCODE SCIPconsSdpComputeSparseSdpMatrix(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, int *length, int *row, int *col, SCIP_Real *val)
SCIP_RETCODE SCIPconsSdpGetLowerTriangConstMatrix(SCIP *scip, SCIP_CONS *cons, SCIP_Real *mat)
static SCIP_DECL_CONSSEPALP(consSepalpSdp)
static SCIP_RETCODE setMaxRhsEntry(SCIP_CONS *cons)
static SCIP_RETCODE move_1x1_blocks_to_lp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int *naddconss, int *ndelconss, int *nchgbds, SCIP_RESULT *result)
SCIP_RETCODE SCIPlapackMatrixMatrixMult(int nrowsA, int ncolsA, SCIP_Real *matrixA, SCIP_Bool transposeA, int nrowsB, int ncolsB, SCIP_Real *matrixB, SCIP_Bool transposeB, SCIP_Real *result)
#define DEFAULT_RANK1APPROXHEUR
static SCIP_DECL_CONSCHECK(consCheckSdp)
Constraint handler for SDP-constraints.
static SCIP_RETCODE expandSymMatrix(int size, SCIP_Real *symMat, SCIP_Real *fullMat)
maps SCIP variables to SDP indices (the SCIP variables are given SDP indices in the order in which th...
SCIP_RETCODE SCIPconsSdpGetFullConstMatrix(SCIP *scip, SCIP_CONS *cons, SCIP_Real *mat)
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)
SCIP_Real SCIPconsSdpGetMaxSdpCoef(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE scaleRowsMatrix(int blocksize, SCIP_Real *matrix, SCIP_Real *scale)
static SCIP_RETCODE addTwoMinorLinConstraints(SCIP *scip, SCIP_CONS **conss, int nconss, int *naddconss)
int SCIPconsSdpCompLowerTriangPos(int i, int j)
SCIP_RETCODE SCIPconsSdpGetMaxEVSubmat(SCIP_CONS *cons, int **maxevsubmat)
SCIP_RETCODE SCIPlapackMatrixVectorMult(int nrows, int ncols, SCIP_Real *matrix, SCIP_Real *vector, SCIP_Real *result)
SCIP_EXPORT SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)
SCIP_RETCODE SCIPconsSdpGetData(SCIP *scip, SCIP_CONS *cons, int *nvars, int *nnonz, int *blocksize, int *arraylength, int *nvarnonz, int **col, int **row, SCIP_Real **val, SCIP_VAR **vars, int *constnnonz, int *constcol, int *constrow, SCIP_Real *constval, SCIP_Bool *rankone, int **maxevsubmat, SCIP_Bool *addedquadcons)
#define CONSHDLR_CHECKPRIORITY
static SCIP_DECL_CONSENFOPS(consEnfopsSdp)
SCIP_Bool SCIPconsSdpShouldBeRankOne(SCIP_CONS *cons)
#define DEFAULT_DIAGZEROIMPLCUTS
SCIP_RETCODE SCIPconsSdpCheckSdpCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_RESULT *result)
adds the main functionality to fix/unfix/(multi-)aggregate variables by merging two three-tuple-array...
static SCIP_RETCODE isMatrixRankOne(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *result)
#define CONSHDLR_ENFOPRIORITY
static SCIP_DECL_CONSFREE(consFreeSdp)
static SCIP_DECL_CONSPRESOL(consPresolSdp)
SCIP_RETCODE SCIPincludeConshdlrSdpRank1(SCIP *scip)
static SCIP_DECL_CONSEXITPRE(consExitpreSdp)
static SCIP_DECL_CONSPRINT(consPrintSdp)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopySdp)
static SCIP_RETCODE updateVarLocks(SCIP *scip, SCIP_CONS *cons, int v)
#define CONSHDLR_MAXPREROUNDS
#define CONSHDLRRANK1_NAME
#define DEFAULT_UPGRADQUADCONSS
static SCIP_DECL_CONSINITPRE(consInitpreSdp)
static SCIP_DECL_CONSINITSOL(consInitsolSdp)
static SCIP_DECL_CONSPARSE(consParseSdp)
#define CONSHDLRRANK1_DESC
static SCIP_RETCODE diagZeroImpl(SCIP *scip, SCIP_CONS **conss, int nconss, int *naddconss)
int SCIPconsSdpGetBlocksize(SCIP *scip, SCIP_CONS *cons)
#define DEFAULT_UPGRADEKEEPQUAD
static SCIP_DECL_CONSSEPASOL(consSepasolSdp)
SCIP_RETCODE SCIPsdpVarfixerMergeArrays(BMS_BLKMEM *blkmem, SCIP_Real epsilon, int *originrow, int *origincol, SCIP_Real *originval, int originlength, SCIP_Bool originsorted, SCIP_Real scalar, int *targetrow, int *targetcol, SCIP_Real *targetval, int *targetlength, int targetmemory)
static SCIP_RETCODE diagGEzero(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int *naddconss, int *nchgbds, SCIP_RESULT *result)
static SCIP_DECL_CONSGETVARS(consGetVarsSdp)
#define CONSHDLR_SEPAPRIORITY
SCIP_RETCODE SCIPlapackLinearSolve(BMS_BUFMEM *bufmem, int m, int n, SCIP_Real *A, SCIP_Real *b, SCIP_Real *x)
SCIP_RETCODE SCIPconsSdpGetNNonz(SCIP *scip, SCIP_CONS *cons, int *nnonz, int *constnnonz)
interface methods for eigenvector computation and matrix multiplication using openblas ...
static SCIP_RETCODE fixAndAggrVars(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool aggregate)
static SCIP_DECL_CONSLOCK(consLockSdp)
SCIP_RETCODE SCIPlapackComputeEigenvectorDecomposition(BMS_BUFMEM *bufmem, int n, SCIP_Real *A, SCIP_Real *eigenvalues, SCIP_Real *eigenvectors)
char name[SCIP_MAXSTRLEN]
static SCIP_DECL_CONSGETNVARS(consGetNVarsSdp)
static SCIP_DECL_CONSCOPY(consCopySdp)
#define DEFAULT_TWOMINORLINCONSS
SCIP_RETCODE SCIPconsSdpGuessInitialPoint(SCIP *scip, SCIP_CONS *cons, SCIP_Real *lambdastar)
static SCIP_DECL_QUADCONSUPGD(consQuadConsUpgdSdp)
static SCIP_RETCODE multiaggrVar(SCIP *scip, SCIP_CONS *cons, int v, SCIP_VAR **aggrvars, SCIP_Real *scalars, int naggrvars, SCIP_Real constant, int *savedcol, int *savedrow, SCIP_Real *savedval, int *nfixednonz, int *vararraylength)
static SCIP_RETCODE unlockVar(SCIP *scip, SCIP_CONSDATA *consdata, int v)
static SCIP_RETCODE cutUsingEigenvector(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Real *coeff, SCIP_Real *lhs)
static SCIP_DECL_CONSENFOLP(consEnfolpSdp)