From 825890d9266aea7d35449b5ff92db61ef4a7ba4d Mon Sep 17 00:00:00 2001 From: Gleb Belov Date: Tue, 12 Nov 2024 14:29:28 +1100 Subject: [PATCH] MP2NL: 'nonlinear' alg cons #237 They come first in the NL --- solvers/mp2nl/mp2nlmodelapi.cc | 50 +++++++++++++++++++++++++++++----- solvers/mp2nl/mp2nlmodelapi.h | 32 ++++++++++++++++++++-- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/solvers/mp2nl/mp2nlmodelapi.cc b/solvers/mp2nl/mp2nlmodelapi.cc index 55e8030c5..d592a0ff6 100644 --- a/solvers/mp2nl/mp2nlmodelapi.cc +++ b/solvers/mp2nl/mp2nlmodelapi.cc @@ -261,6 +261,8 @@ void MP2NLModelAPI::PrepareModel() { MapExpressions(); MarkVars(); SortVars(); + MarkAlgCons(); + SortAlgCons(); } void MP2NLModelAPI::MapExpressions() { @@ -492,6 +494,24 @@ void MP2NLModelAPI::SortVars() { } } +void MP2NLModelAPI::MarkAlgCons() { + mark_data_.con_prior_.clear(); + mark_data_.con_prior_.resize(alg_con_info_.size()); + for (auto i=alg_con_info_.size(); i--; ) { + mark_data_.con_prior_[i] = { -(int)is_alg_con_nl_[i], i }; + } +} + +void MP2NLModelAPI::SortAlgCons() { + std::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--; ) { + mark_data_.con_order_12_[i] = mark_data_.con_prior_[i].second; + mark_data_.con_order_21_[mark_data_.con_prior_[i].second] = i; + } +} + void MP2NLModelAPI::Add2ColSizes(ArrayRef vars) { for (auto v: vars) ++mark_data_.col_sizes_orig_[v]; @@ -673,7 +693,8 @@ void MP2NLModelAPI::FeedVarBounds(VarBoundsWriter& vbw) { template void MP2NLModelAPI::FeedConBounds(ConBoundsWriter& cbw) { - for (size_t i=0; i void MP2NLModelAPI::FeedLinearConExpr(int i, ConLinearExprWriterFactory& svwf) { - FeedExtLinPart(alg_con_info_[i], svwf); + FeedExtLinPart(alg_con_info_[GetOldAlgConIndex(i)], svwf); } template @@ -759,7 +780,7 @@ template void MP2NLModelAPI::FeedConExpression( int icon, ConExprWriter& ew) { if (icon < (int)alg_con_info_.size()) - FeedAlgConExpression(icon, ew); + FeedAlgConExpression(GetOldAlgConIndex(icon), ew); else FeedLogicalConExpression(icon - alg_con_info_.size(), ew); } @@ -1096,7 +1117,7 @@ void MP2NLModelAPI::FeedInitialDualGuesses(IDGWriter& igw) { if (y0.size()) { auto ig = igw.MakeVectorWriter(y0.size()); for (size_t i=0; iGetNewVarIndex(i); + else if (suf::CON==kind && iGetNewAlgConIndex(i); sw.Write(i0, val); } } @@ -1200,7 +1223,12 @@ void MP2NLModelAPI::FeedRowAndObjNames(ColNameWriter& wrt) { wrt << (nm ? nm : ".."); } }; - write_names(alg_con_info_); // @todo any permutations + for (size_t i=0; i=0 && j0 < n_alg_cons); + duals_[j0] = rd.ReadNext(); + } } } @@ -1457,6 +1489,7 @@ class MP2NLSolverImpl auto& suf = modelsuf.values_.at(kind & 3); suf.clear(); suf.resize(nitems_[kind & 3]); + auto n_alg_cons = Header().num_algebraic_cons; while (sr.Size()) { auto sparse_entry = sr.ReadNext(); if (sparse_entry.first<0 || sparse_entry.first>=nmax) { @@ -1467,6 +1500,9 @@ class MP2NLSolverImpl int i0 = sparse_entry.first; if (0 == (kind & 3)) // variable suffix i0 = mapi_.GetOldVarIndex(i0); + else + if (1 == (kind & 3) && i0 < n_alg_cons) + i0 = mapi_.GetOldAlgConIndex(i0); suf[i0] = sparse_entry.second; } } diff --git a/solvers/mp2nl/mp2nlmodelapi.h b/solvers/mp2nl/mp2nlmodelapi.h index c27747945..37ab06bc0 100644 --- a/solvers/mp2nl/mp2nlmodelapi.h +++ b/solvers/mp2nl/mp2nlmodelapi.h @@ -923,10 +923,28 @@ class MP2NLModelAPI public: /// Get new var index for an old var index - int GetNewVarIndex(int i) const { return mark_data_.var_order_21_[i]; } + int GetNewVarIndex(int i) const { + assert(i>=0 && i=0 && i=0 && i=0 && i @@ -961,6 +979,12 @@ class MP2NLModelAPI /// Sort variables void SortVars(); + /// Mark alg cons for sorting + void MarkAlgCons(); + + /// Sort alg cons + void SortAlgCons(); + NLHeader DoMakeHeader(); /// Parameters passed when marking variables in an expression tree @@ -991,6 +1015,10 @@ class MP2NLModelAPI std::vector var_order_12_; // new index -> old index std::vector var_order_21_; // old index -> new index + std::vector< std::pair< int, int > > con_prior_; // new index -> con weight, orig. index + std::vector con_order_12_; // new index -> old index + std::vector con_order_21_; // old index -> new index + std::vector col_sizes_orig_; // column sizes for original sorting };