diff --git a/include/mp/flat/converter_multiobj.h b/include/mp/flat/converter_multiobj.h index 69fe49e7e..486a62279 100644 --- a/include/mp/flat/converter_multiobj.h +++ b/include/mp/flat/converter_multiobj.h @@ -98,11 +98,13 @@ class MOManager { objval_last_ = objs.front(); // 0. save emulated obj value // @todo 1. check if the solver correctly reports the current emulated obj // 2. Let's recompute the original objectives + // and the last iteration's objective, TODO: if needed const auto& xx = sol.GetVarValues()(); if (xx.size()) { // This can be invoked w/o solution objs.resize( MPCD(num_objs()) ); for (int i=0; i<(int)objs.size(); ++i) objs[i] = ComputeValue(MPCD(get_obj(i)), xx); + objval_last_ = ComputeValue(obj_new_[i_current_obj_-1], xx); } } } diff --git a/include/mp/flat/prepro_prod.h b/include/mp/flat/prepro_prod.h index 06684896c..4e1e701f4 100644 --- a/include/mp/flat/prepro_prod.h +++ b/include/mp/flat/prepro_prod.h @@ -90,7 +90,7 @@ class PreproProd std::get<2>(tpl) = {bnds.lb(), bnds.ub()}; } - std::sort(terms_flt_.begin(), terms_flt_.end(), + std::stable_sort(terms_flt_.begin(), terms_flt_.end(), [](const auto& tpl1, const auto& tpl2) { return std::get<0>(tpl1) < std::get<0>(tpl2); }); diff --git a/solvers/mp2nl/mp2nlbackend.cc b/solvers/mp2nl/mp2nlbackend.cc index caaf0eab5..86d9d81f9 100644 --- a/solvers/mp2nl/mp2nlbackend.cc +++ b/solvers/mp2nl/mp2nlbackend.cc @@ -85,11 +85,14 @@ class MP2NLSolverQueryCallbacksImpl result.values_[2] }); result.values_[0] = suf_pre.GetVarValues()(); - result.values_[2] = suf_pre.GetObjValues()(); result.values_[1] = suf_pre.GetConValues()(CG_Algebraic); const auto& suf_log = suf_pre.GetConValues()(CG_Logical); result.values_[1].insert(result.values_[1].end(), suf_log.begin(), suf_log.end()); + if (be_.multiobj()) // Skip because we compress objectives + result.values_[2].clear(); // @todo native multiobj + else + result.values_[2] = suf_pre.GetObjValues()(); return result; } private: diff --git a/solvers/mp2nl/mp2nlmodelapi.cc b/solvers/mp2nl/mp2nlmodelapi.cc index d4ab36736..790bedeca 100644 --- a/solvers/mp2nl/mp2nlmodelapi.cc +++ b/solvers/mp2nl/mp2nlmodelapi.cc @@ -486,7 +486,7 @@ void MP2NLModelAPI::MarkVars() { } void MP2NLModelAPI::SortVars() { - std::sort(mark_data_.var_prior_.begin(), mark_data_.var_prior_.end()); + std::stable_sort(mark_data_.var_prior_.begin(), mark_data_.var_prior_.end()); mark_data_.var_order_12_.resize(var_lbs_.size()); mark_data_.var_order_21_.resize(var_lbs_.size()); for (auto i=var_lbs_.size(); i--; ) { @@ -504,7 +504,7 @@ void MP2NLModelAPI::MarkAlgCons() { } void MP2NLModelAPI::SortAlgCons() { - std::sort(mark_data_.con_prior_.begin(), mark_data_.con_prior_.end()); + std::stable_sort(mark_data_.con_prior_.begin(), mark_data_.con_prior_.end()); mark_data_.con_order_12_.resize(alg_con_info_.size()); mark_data_.con_order_21_.resize(alg_con_info_.size()); for (auto i=alg_con_info_.size(); i--; ) { @@ -1352,6 +1352,7 @@ class MP2NLSolverImpl */ int OnAMPLOptions(const AMPLOptions& ) { suf_map_.clear(); // clear for new solution + if_suf_data_registered_ = false; return 0; } @@ -1496,7 +1497,9 @@ class MP2NLSolverImpl auto sparse_entry = sr.ReadNext(); if (sparse_entry.first<0 || sparse_entry.first>=nmax) { sr.SetError(NLW2_SOLRead_Bad_Suffix, - "bad suffix element index"); + fmt::format( + "bad suffix({}, kind={}) element index: {}, should be in [{}, {})", + name, kind, sparse_entry.first, 0, nmax)); return; } int i0 = sparse_entry.first; diff --git a/solvers/mp2nl/mp2nlmodelapi.h b/solvers/mp2nl/mp2nlmodelapi.h index 37ab06bc0..6f6f1eadb 100644 --- a/solvers/mp2nl/mp2nlmodelapi.h +++ b/solvers/mp2nl/mp2nlmodelapi.h @@ -1041,11 +1041,12 @@ class MP2NLModelAPI void MarkRangeOrEqn(const LinConRange& lcr) { Add2ColSizes(lcr.vars()); if (lcr.lb() > MinusInfinity() - && lcr.ub() < Infinity()) + && lcr.ub() < Infinity()) { if (lcr.lb() < lcr.ub()) ++mark_data_.n_ranges_; else ++mark_data_.n_eqns_; + } } /// Mark LinConEQ @@ -1351,20 +1352,38 @@ class MP2NLModelAPI public: /// Construct ItemInfo (BasicItemDispatcher& disp, void* pitem, - bool fLogical + bool fLogical, + bool f_m = 0, LinPartRefOrStorage lpe = {} //, StaticItemTypeID iid, ExpressionTypeID eid ) - : disp_(disp), p_item_(pitem), f_logical_(fLogical) + : disp_(disp), p_item_(pitem), f_logical_(fLogical), + f_marked_(f_m), lin_part_ext_(lpe) // no storing, itemID_(iid), exprID_(eid) { } /// Copy construct ItemInfo(const ItemInfo& ii) - : ItemInfo(ii.disp_, ii.p_item_, ii.f_logical_) { } + : ItemInfo(ii.disp_, ii.p_item_, ii.f_logical_, + ii.f_marked_, ii.lin_part_ext_) { } /// operator= ItemInfo& operator=(const ItemInfo& ii) { assert(&disp_==&ii.disp_); p_item_ = ii.p_item_; assert(f_logical_==ii.f_logical_); + f_marked_ = ii.f_marked_; + lin_part_ext_ = ii.lin_part_ext_; + return *this; + } + /// Move construct + ItemInfo(ItemInfo&& ii) + : ItemInfo(ii.disp_, ii.p_item_, ii.f_logical_, + ii.f_marked_, std::move(ii.lin_part_ext_)) { } + /// operator=(&&) + ItemInfo& operator=(ItemInfo&& ii) { + assert(&disp_==&ii.disp_); + p_item_ = ii.p_item_; + assert(f_logical_==ii.f_logical_); + f_marked_ = ii.f_marked_; + lin_part_ext_ = std::move(ii.lin_part_ext_); return *this; } /// Get dispatcher