diff --git a/include/mp/flat/constr_eval.h b/include/mp/flat/constr_eval.h new file mode 100644 index 000000000..b1d9c73a3 --- /dev/null +++ b/include/mp/flat/constr_eval.h @@ -0,0 +1,264 @@ +#ifndef CONSTR_EVAL_H +#define CONSTR_EVAL_H + +/** + * Evaluations and violations + * of (mainly functional) constraints + */ + +#include + +#include "constr_functional.h" +#include "constr_general.h" + +namespace mp { + +/// Compute result of the max constraint. +template +double ComputeValue(const MaxConstraint& con, const VarVec& x) { + double result = -INFINITY; + for (auto i: con.GetArguments()) { + if (result < x[i]) + result = x[i]; + } + return result; +} + +/// Compute result of the min constraint. +template +double ComputeValue(const MinConstraint& con, const VarVec& x) { + double result = INFINITY; + for (auto i: con.GetArguments()) { + if (result > x[i]) + result = x[i]; + } + return result; +} + +/// Compute result of the abs constraint. +template +double ComputeValue(const AbsConstraint& con, const VarVec& x) { + return std::fabs(x[con.GetArguments()[0]]); +} + +/// Compute result of the and constraint. +template +double ComputeValue(const AndConstraint& con, const VarVec& x) { + for (auto i: con.GetArguments()) { + if (x[i] < 0.5) + return 0.0; + } + return 1.0; +} + +/// Compute result of the or constraint. +template +double ComputeValue(const OrConstraint& con, const VarVec& x) { + for (auto i: con.GetArguments()) { + if (x[i] >= 0.5) + return 1.0; + } + return 0.0; +} + +/// Compute result of the not constraint. +template +double ComputeValue(const NotConstraint& con, const VarVec& x) { + return x[con.GetArguments()[0]] < 0.5; +} + +/// Compute result of the div constraint. +template +double ComputeValue(const DivConstraint& con, const VarVec& x) { + auto divt = x[con.GetArguments()[0]]; + auto divs = x[con.GetArguments()[1]]; + return 0.0==std::fabs(divs) + ? (divt>=0.0 ? INFINITY : -INFINITY) + : divt / divs; +} + +/// Compute result of the IfThen constraint. +template +double ComputeValue(const IfThenConstraint& con, const VarVec& x) { + auto i = x[con.GetArguments()[0]]; + return x[ + con.GetArguments()[(i>=0.5) ? 1 : 2]]; +} + +/// Compute result of the Implication constraint. +template +double ComputeValue(const ImplicationConstraint& con, const VarVec& x) { + auto i = x[con.GetArguments()[0]]; + auto c1 = x[con.GetArguments()[1]]; + auto c2 = x[con.GetArguments()[2]]; + return (i>=0.5 && c1>=0.5) || (i<0.5 && c2>=0.5); +} + +/// Compute result of the AllDiff constraint. +template +double ComputeValue(const AllDiffConstraint& con, const VarVec& x) { + const auto& args = con.GetArguments(); + for (auto i=args.size(); i--; ) { + for (auto j=i; j--; ) { // Should be integer vars. + if (std::round(x[args[i]]) == std::round(x[args[j]])) + return 0.0; + } + } + return 1.0; +} + +/// Compute result of the NumberofConst constraint. +/// Currently assumes integer variables +/// (otherwise the result may be larger.) +template +double ComputeValue(const NumberofConstConstraint& con, const VarVec& x) { + double result = 0.0; + auto k = std::round(con.GetParameters()[0]); + for (auto v: con.GetArguments()) { + if (std::round(x[v]) == k) + ++result; + } + return result; +} + +/// Compute result of the NumberofVar constraint. +/// Currently assumes integer variables +/// (otherwise the result may be larger.) +template +double ComputeValue(const NumberofVarConstraint& con, const VarVec& x) { + double result = 0.0; + const auto& args = con.GetArguments(); + auto k = std::round(x[args[0]]); + for (auto i=args.size(); --i; ) { + if (std::round(x[args[i]]) == k) + ++result; + } + return result; +} + +/// Compute result of the count constraint. +template +double ComputeValue(const CountConstraint& con, const VarVec& x) { + double result = 0.0; + for (auto v: con.GetArguments()) { + if (x[v] >= 0.5) + ++result; + } + return result; +} + +/// Compute result of the exp constraint. +template +double ComputeValue(const ExpConstraint& con, const VarVec& x) { + return std::exp(x[con.GetArguments()[0]]); +} + +/// Compute result of the expA constraint. +template +double ComputeValue(const ExpAConstraint& con, const VarVec& x) { + return std::pow( + con.GetParameters()[0], x[con.GetArguments()[0]]); +} + +/// Compute result of the log constraint. +template +double ComputeValue(const LogConstraint& con, const VarVec& x) { + return std::log(x[con.GetArguments()[0]]); +} + +/// Compute result of the logA constraint. +template +double ComputeValue(const LogAConstraint& con, const VarVec& x) { + return + std::log(x[con.GetArguments()[0]]) + / std::log(con.GetParameters()[0]); +} + +/// Compute result of the pow constraint. +template +double ComputeValue(const PowConstraint& con, const VarVec& x) { + return std::pow( + x[con.GetArguments()[0]], con.GetParameters()[0]); +} + +/// Compute result of the sin constraint. +template +double ComputeValue(const SinConstraint& con, const VarVec& x) { + return std::sin(x[con.GetArguments()[0]]); +} + +/// Compute result of the cos constraint. +template +double ComputeValue(const CosConstraint& con, const VarVec& x) { + return std::cos(x[con.GetArguments()[0]]); +} + +/// Compute result of the tan constraint. +template +double ComputeValue(const TanConstraint& con, const VarVec& x) { + return std::tan(x[con.GetArguments()[0]]); +} + +/// Compute result of the asin constraint. +template +double ComputeValue(const AsinConstraint& con, const VarVec& x) { + return std::asin(x[con.GetArguments()[0]]); +} + +/// Compute result of the acos constraint. +template +double ComputeValue(const AcosConstraint& con, const VarVec& x) { + return std::acos(x[con.GetArguments()[0]]); +} + +/// Compute result of the atan constraint. +template +double ComputeValue(const AtanConstraint& con, const VarVec& x) { + return std::atan(x[con.GetArguments()[0]]); +} + +/// Compute result of the sinh constraint. +template +double ComputeValue(const SinhConstraint& con, const VarVec& x) { + return std::sinh(x[con.GetArguments()[0]]); +} + +/// Compute result of the cosh constraint. +template +double ComputeValue(const CoshConstraint& con, const VarVec& x) { + return std::cosh(x[con.GetArguments()[0]]); +} + +/// Compute result of the tanh constraint. +template +double ComputeValue(const TanhConstraint& con, const VarVec& x) { + return std::tanh(x[con.GetArguments()[0]]); +} + +/// Compute result of a conditional constraint. +/// Actually, for violation itself, we could do this: +/// If the subconstr is violated but should hold, +/// return the exact gap, despite this is a logical constraint. +/// If the subconstr holds but should not, return 0.0. +template +double ComputeValue( + const ConditionalConstraint& con, const VarVec& x) { + auto viol = con.GetConstraint().ComputeViolation(x); + bool ccon_valid = viol<=0.0; + bool has_arg = x[con.GetResultVar()] >= 0.5; + switch (con.GetContext()) { + case Context::CTX_MIX: + return has_arg == ccon_valid; + case Context::CTX_POS: + return has_arg < ccon_valid; + case Context::CTX_NEG: + return has_arg > ccon_valid; + default: + return INFINITY; + } +} + + +} // namespace mp + +#endif // CONSTR_EVAL_H diff --git a/include/mp/flat/constr_functional.h b/include/mp/flat/constr_functional.h index 6ffe18cdb..b7f7d5f2d 100644 --- a/include/mp/flat/constr_functional.h +++ b/include/mp/flat/constr_functional.h @@ -57,7 +57,7 @@ DEF_LOGICAL_FUNC_CONSTR( AllDiffConstraint, VarArray, //////////////////////////////////////////////////////////////////////// DEF_NUMERIC_FUNC_CONSTR_WITH_PRM( NumberofConstConstraint, VarArray, DblParamArray1, - "numberof_const(k (=x0), {x1...xn})"); + "numberof_const(k, {x0...xn})"); //////////////////////////////////////////////////////////////////////// DEF_NUMERIC_FUNC_CONSTR( NumberofVarConstraint, VarArray, diff --git a/include/mp/flat/constr_keeper.h b/include/mp/flat/constr_keeper.h index 5cc1fd854..66a9b6015 100644 --- a/include/mp/flat/constr_keeper.h +++ b/include/mp/flat/constr_keeper.h @@ -14,7 +14,7 @@ #include "mp/flat/constr_hash.h" #include "mp/flat/redef/redef_base.h" #include "mp/valcvt-node.h" -#include "mp/flat/constr_viol.h" +#include "mp/flat/constr_eval.h" namespace mp { diff --git a/include/mp/flat/constr_viol.h b/include/mp/flat/constr_viol.h deleted file mode 100644 index 34279116d..000000000 --- a/include/mp/flat/constr_viol.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef CONSTR_VIOL_H -#define CONSTR_VIOL_H - -/** - * Violations of (mainly functional) constraints - */ - -#include - -#include "constr_functional.h" -#include "constr_general.h" - -namespace mp { - -/// Compute result of the max constraint. -template -double ComputeValue(const MaxConstraint& con, const VarVec& x) { - double result = -INFINITY; - for (auto i: con.GetArguments()) { - if (result < x[i]) - result = x[i]; - } - return result; -} - -/// Compute result of the min constraint. -template -double ComputeValue(const MinConstraint& con, const VarVec& x) { - double result = INFINITY; - for (auto i: con.GetArguments()) { - if (result > x[i]) - result = x[i]; - } - return result; -} - -/// Compute result of the abs constraint. -template -double ComputeValue(const AbsConstraint& con, const VarVec& x) { - return std::fabs(x[con.GetArguments()[0]]); -} - -/// Compute result of the and constraint. -template -double ComputeValue(const AndConstraint& con, const VarVec& x) { - for (auto i: con.GetArguments()) { - if (x[i] < 0.5) - return 0.0; - } - return 1.0; -} - -/// Compute result of the or constraint. -template -double ComputeValue(const OrConstraint& con, const VarVec& x) { - for (auto i: con.GetArguments()) { - if (x[i] >= 0.5) - return 1.0; - } - return 0.0; -} - -/// Compute result of the not constraint. -template -double ComputeValue(const NotConstraint& con, const VarVec& x) { - return x[con.GetArguments()[0]] < 0.5; -} - - -} // namespace mp - -#endif // CONSTR_VIOL_H