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));
79 (image -> ArgList () [0] -> Type () !=
CONST) &&
80 (image -> ArgList () [1] -> Value () == 2.)) {
82 int index0 = image -> ArgList () [0] -> Index ();
85 ((*i) -> Index () >= 0))
87 cauldron -> add_element (index0, index0, (*i));
92 printf (
"Cauldron so far\n");
101 minors_ . push_back (cauldron);
107 for (std::vector <CouenneExprMatrix *>::iterator
116 std::set <int> varNumIndices;
119 rowIt = (*i) -> getRows (). begin ();
120 rowIt != (*i) -> getRows ().
end (); ++rowIt) {
122 varNumIndices. insert (rowIt -> first);
124 for (std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
125 elemIt = rowIt -> second -> getElements () . begin ();
126 elemIt != rowIt -> second -> getElements () .
end (); ++elemIt)
128 varNumIndices. insert ((*elemIt) -> getIndex ());
135 rowIt = (*i) -> getRows (). begin ();
136 rowIt != (*i) -> getRows ().
end (); ++rowIt) {
138 int rowInd = rowIt -> first;
140 std::set <int>::iterator vniIt = varNumIndices . begin ();
142 for (std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
143 elemIt = rowIt -> second -> getElements () . begin ();
144 elemIt != rowIt -> second -> getElements () .
end (); ++elemIt) {
146 int colInd = (*elemIt) -> getIndex ();
148 while ((vniIt != varNumIndices .
end ()) && (*vniIt < colInd)) {
150 if (rowInd <= *vniIt) {
161 if (
problem_ -> AuxSet () -> find (yIJ) ==
166 problem_ -> AuxSet () -> insert (yIJ);
169 (*i) -> add_element (rowInd, *vniIt, yIJ);
170 (*i) -> add_element (*vniIt, rowInd, yIJ);
176 if (vniIt == varNumIndices .
end ())
198 for (std::vector <CouenneExprMatrix *>::iterator
205 printf (
"minor has %ld rows and %ld columns\n",
206 (*i) -> getRows () . size (),
207 (*i) -> getCols () . size ());
211 j = (*i) -> getCols () . begin ();
212 j != (*i) -> getCols () .
end (); ++
j)
214 (*i) -> varIndices () . push_back (
problem_ -> Var (
j -> first));
216 for (std::vector <expression *>::iterator
217 j = (*i) -> varIndices () . begin ();
218 j != (*i) -> varIndices () .
end (); ++
j) {
220 int indexVar = (*j) -> Index ();
222 printf (
"adding at [%d,%d] and viceversa\n", indexVar, size);
224 (*i) -> add_element (indexVar, size, *
j);
225 (*i) -> add_element (size, indexVar, *
j);
228 (*i) -> add_element (size, size,
new exprConst (1.));
238 if (p -> ConstraintClass (
"PSDcon"))
239 for (std::vector <CouenneConstraint *>::iterator
240 i = p -> ConstraintClass (
"PSDcon") -> begin ();
241 i != p -> ConstraintClass (
"PSDcon") ->
end (); ++i) {
248 minors_ . push_back (con -> getX ());
256 for (std::vector <CouenneExprMatrix *>::iterator
267 problem_ (rhs. problem_),
268 doNotUse_ (rhs. doNotUse_),
269 numEigVec_ (rhs. numEigVec_),
270 onlyNegEV_ (rhs. onlyNegEV_),
271 useSparsity_ (rhs. useSparsity_),
272 fillMissingTerms_ (rhs. fillMissingTerms_) {
274 for (std::vector <CouenneExprMatrix *>::const_iterator
292 for (std::vector <CouenneExprMatrix *>::const_iterator
310 roptions -> AddLowerBoundedIntegerOption
312 "The frequency (in terms of nodes) at which Couenne SDP cuts are generated.",
314 "A frequency of 0 (default) means these cuts are never generated. \
315 Any positive number n instructs Couenne to generate them at every n nodes of the B&B tree. \
316 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."
319 roptions -> AddLowerBoundedIntegerOption
321 "The number of eigenvectors of matrix X to be used to create sdp cuts.",
323 "Set to -1 to indicate that all n eigenvectors should be used. Eigenvalues are \
324 sorted in non-decreasing order, hence selecting 1 will provide cuts on the most negative eigenvalue."
327 roptions -> AddStringOption2
329 "Only use negative eigenvalues to create sdp cuts.",
331 "no",
"use all eigenvalues regardless of their sign.",
332 "yes",
"exclude all non-negative eigenvalues."
337 roptions -> AddStringOption2
338 (
"sdp_cuts_sparsify",
339 "Make cuts sparse by greedily reducing X one column at a time before extracting eigenvectors.",
345 roptions -> AddStringOption2
346 (
"sdp_cuts_fillmissing",
347 "Create fictitious auxiliary variables to fill non-fully dense minors. Can make a difference when Q has at least one zero term.",
349 "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 \
350 Advantage: limits the creation of auxiliaries, reformulation stays small. Default.",
351 "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 \
352 of the reformulation and hence of the linear relaxation."
356 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,