10 #include "IpOptionsList.hpp"
22 #include "CoinTime.hpp"
26 using namespace Couenne;
39 options -> GetIntegerValue (
"sdp_cuts_num_ev",
numEigVec_,
"couenne.");
40 options -> GetStringValue (
"sdp_cuts_neg_ev", s,
"couenne.");
onlyNegEV_ = (s ==
"yes");
41 options -> GetStringValue (
"sdp_cuts_sparsify", s,
"couenne.");
useSparsity_ = (s ==
"yes");
42 options -> GetStringValue (
"sdp_cuts_fillmissing", s,
"couenne.");
fillMissingTerms_ = (s ==
"yes");
48 for (std::vector <exprVar *>::iterator
52 if ((*i) -> Type () ==
AUX) {
58 (image -> ArgList () [0] -> Type () !=
CONST) &&
59 (image -> ArgList () [1] -> Type () !=
CONST)) {
62 index0 = image -> ArgList () [0] -> Index (),
63 index1 = image -> ArgList () [1] -> Index ();
67 ((*i) -> Index () >= 0))
72 cauldron -> add_element (index0, index1, (*i));
73 cauldron -> add_element (index1, index0, (*i));
78 (image -> ArgList () [0] -> Type () !=
CONST) &&
79 (image -> ArgList () [1] -> Value () == 2.)) {
81 int index0 = image -> ArgList () [0] -> Index ();
84 ((*i) -> Index () >= 0))
86 cauldron -> add_element (index0, index0, (*i));
91 printf (
"Cauldron so far\n");
100 minors_ . push_back (cauldron);
106 for (std::vector <CouenneExprMatrix *>::iterator
115 std::set <int> varNumIndices;
118 rowIt = (*i) -> getRows (). begin ();
119 rowIt != (*i) -> getRows ().
end (); ++rowIt) {
121 varNumIndices. insert (rowIt -> first);
123 for (std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
124 elemIt = rowIt -> second -> getElements () . begin ();
125 elemIt != rowIt -> second -> getElements () .
end (); ++elemIt)
127 varNumIndices. insert ((*elemIt) -> getIndex ());
134 rowIt = (*i) -> getRows (). begin ();
135 rowIt != (*i) -> getRows ().
end (); ++rowIt) {
137 int rowInd = rowIt -> first;
139 std::set <int>::iterator vniIt = varNumIndices . begin ();
141 for (std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
142 elemIt = rowIt -> second -> getElements () . begin ();
143 elemIt != rowIt -> second -> getElements () .
end (); ++elemIt) {
145 int colInd = (*elemIt) -> getIndex ();
147 while ((vniIt != varNumIndices .
end ()) && (*vniIt < colInd)) {
149 if (rowInd <= *vniIt) {
160 if (
problem_ -> AuxSet () -> find (yIJ) ==
165 problem_ -> AuxSet () -> insert (yIJ);
168 (*i) -> add_element (rowInd, *vniIt, yIJ);
169 (*i) -> add_element (*vniIt, rowInd, yIJ);
175 if (vniIt == varNumIndices .
end ())
197 for (std::vector <CouenneExprMatrix *>::iterator
204 printf (
"minor has %ld rows and %ld columns\n",
205 (*i) -> getRows () . size (),
206 (*i) -> getCols () . size ());
210 j = (*i) -> getCols () . begin ();
211 j != (*i) -> getCols () .
end (); ++
j)
213 (*i) -> varIndices () . push_back (
problem_ -> Var (
j -> first));
215 for (std::vector <expression *>::iterator
216 j = (*i) -> varIndices () . begin ();
217 j != (*i) -> varIndices () .
end (); ++
j) {
219 int indexVar = (*j) -> Index ();
221 printf (
"adding at [%d,%d] and viceversa\n", indexVar, size);
223 (*i) -> add_element (indexVar, size, *
j);
224 (*i) -> add_element (size, indexVar, *
j);
227 (*i) -> add_element (size, size,
new exprConst (1.));
237 if (p -> ConstraintClass (
"PSDcon"))
238 for (std::vector <CouenneConstraint *>::iterator
239 i = p -> ConstraintClass (
"PSDcon") -> begin ();
240 i != p -> ConstraintClass (
"PSDcon") ->
end (); ++i) {
247 minors_ . push_back (con -> getX ());
255 for (std::vector <CouenneExprMatrix *>::iterator
266 problem_ (rhs. problem_),
267 doNotUse_ (rhs. doNotUse_),
268 numEigVec_ (rhs. numEigVec_),
269 onlyNegEV_ (rhs. onlyNegEV_),
270 useSparsity_ (rhs. useSparsity_),
271 fillMissingTerms_ (rhs. fillMissingTerms_) {
273 for (std::vector <CouenneExprMatrix *>::const_iterator
291 for (std::vector <CouenneExprMatrix *>::const_iterator
309 roptions -> AddLowerBoundedIntegerOption
311 "The frequency (in terms of nodes) at which Couenne SDP cuts are generated.",
313 "A frequency of 0 (default) means these cuts are never generated. \
314 Any positive number n instructs Couenne to generate them at every n nodes of the B&B tree. \
315 A negative number -n means that generation should be attempted at the root node, and if successful it can be repeated at every n nodes, otherwise it is stopped altogether."
318 roptions -> AddLowerBoundedIntegerOption
320 "The number of eigenvectors of matrix X to be used to create sdp cuts.",
322 "Set to -1 to indicate that all n eigenvectors should be used. Eigenvalues are \
323 sorted in non-decreasing order, hence selecting 1 will provide cuts on the most negative eigenvalue."
326 roptions -> AddStringOption2
328 "Only use negative eigenvalues to create sdp cuts.",
330 "no",
"use all eigenvalues regardless of their sign.",
331 "yes",
"exclude all non-negative eigenvalues."
336 roptions -> AddStringOption2
337 (
"sdp_cuts_sparsify",
338 "Make cuts sparse by greedily reducing X one column at a time before extracting eigenvectors.",
344 roptions -> AddStringOption2
345 (
"sdp_cuts_fillmissing",
346 "Create fictitious auxiliary variables to fill non-fully dense minors. Can make a difference when Q has at least one zero term.",
348 "no",
"Do not create auxiliaries and simply use Fourier-Motzkin to substitute a missing auxiliary y_ij with inequalities that use bounds and the definition y_ij = x_i x_j \
349 Advantage: limits the creation of auxiliaries, reformulation stays small. Default.",
350 "yes",
"Create (at the beginning) auxiliaries that are linearized (through McCormick) and used within an SDP cut. This allows tighter cuts although it increases the size \
351 of the reformulation and hence of the linear relaxation."
355 roptions -> AddStringOption2
CouenneProblem * problem_
pointer to problem info
Power of an expression (binary operator), with constant.
These are cuts of the form.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Add list of options to be read from file.
bool fillMissingTerms_
If minor not fully dense, create fictitious auxiliary variables that will be used in sdp cuts only (t...
virtual CglCutGenerator * clone() const
Cloning constructor.
Class to represent positive semidefinite constraints //////////////////.
CouenneSdpCuts(CouenneProblem *, JnlstPtr, const Ipopt::SmartPtr< Ipopt::OptionsList >)
Constructor.
bool useSparsity_
Sparsify eigenvalues before writing inequality (default: no)
CouenneSdpCuts & operator=(const CouenneSdpCuts &)
Assignment.
Class for MINLP problems with symbolic information.
expression clone (points to another expression)
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
std::vector< CouenneExprMatrix * > minors_
minors on which to apply cuts
~CouenneSdpCuts()
Destructor.
bool doNotUse_
after construction, true if there are enough product terms to justify application.
int numEigVec_
number of eigenvectors to be used (default: n)
The in-memory representation of the variables element.
bool onlyNegEV_
only use negative eigenvalues (default: yes)
class for multiplications,