Skip to content

Commit

Permalink
Don't represent (var|const) >= abs(...) as SOCP #192
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Oct 7, 2024
1 parent 00478d9 commit ec0e049
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/mp/flat/constr_2_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,7 @@ class Constraints2Expr {
ck.ConvertConstraint(ie.GetIndex());
return true;
}
return false;
}


Expand Down
14 changes: 9 additions & 5 deletions include/mp/flat/redef/conic/cones.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,9 @@ class Convert1QC : public MCKeeper<MCType> {
if (auto lhs_args = CheckSqrtXnXmNonneg(lint.var(iX)))
return ContinueRotatedSOC(lint, iX, iY,
lhs_args, rhs_args);
return ContinueStdSOC(lint.coef(iX), lint.var(iX),
lint.coef(iY), rhs_args);
if (!rhs_args.is_from_abs_) // not x >= abs(...)
return ContinueStdSOC(lint.coef(iX), lint.var(iX),
lint.coef(iY), rhs_args);
}
} else if (1 == lint.size() && // const>=y.
0.0 >= rhs*sens && // either ... <= rhs
Expand All @@ -396,9 +397,10 @@ class Convert1QC : public MCKeeper<MCType> {
// it's -k*sqrt(...) <= rhs(>0), k>0,
// which is always true TODO
if (auto rhs_args = CheckNorm2(lint.var(0))) {
return ContinueStdSOC(std::fabs(rhs),
int( MC().MakeFixedVar( 1.0 ) ),
lint.coef(0), rhs_args);
if (!rhs_args.is_from_abs_) // not const >= abs(...)
return ContinueStdSOC(std::fabs(rhs),
int( MC().MakeFixedVar( 1.0 ) ),
lint.coef(0), rhs_args);
}
}
return false;
Expand All @@ -407,6 +409,7 @@ class Convert1QC : public MCKeeper<MCType> {
/// Typedef for subexpression checkup result,
/// whether it represents some part of an SOCP cone.
struct ConeArgs {
bool is_from_abs_ {}; // No StdCone then
std::vector<double> coefs_;
std::vector<int> vars_;
double const_term = 0.0;
Expand Down Expand Up @@ -488,6 +491,7 @@ class Convert1QC : public MCKeeper<MCType> {
result.coefs_ = { 1.0 };
result.vars_ = { arg_abs };
result.res_vars_to_delete_ = { res_var };
result.is_from_abs_ = true;
return result;
}

Expand Down
8 changes: 8 additions & 0 deletions test/end2end/cases/categorized/fast/conic/modellist.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@
"solve_result_num": 0
}
},
{
"name" : "socp_13_abs_stdcone",
"tags" : ["socp"],
"objective" : -40,
"values": {
"solve_result_num": 0
}
},
{
"name" : "expcones_01__plain",
"objective" : 0.7821882953,
Expand Down
17 changes: 17 additions & 0 deletions test/end2end/cases/categorized/fast/conic/socp_13_abs_stdcone.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
####################################
# Test that we don't convert abs(x) <= 5 into a cone
# TODO Also perform the actual test, now it's just for solving
####################################

var b1 binary;
var b2 binary;
var x >=-19 <=32;
var y >= -12 <= 5;

minimize Obj: b1 - b2 - x + 3*y;

var charge_diff = abs(x-y);

s.t. Con: b1 && b2 ==> x<=y;

s.t. Cone: charge_diff <= if b1>=1 then 5 else 15;

0 comments on commit ec0e049

Please sign in to comment.