From 5da2fbb7e3f005fb3df5b14a2062b12b01a313b4 Mon Sep 17 00:00:00 2001 From: Gleb Belov Date: Tue, 19 Dec 2023 22:35:10 +1100 Subject: [PATCH] -!: print ranges straightaway, e.g., '0-99 solved...' --- include/mp/common.h | 9 ++--- include/mp/solver-base.h | 38 ++++++++++++++++++++- src/solver.cc | 72 +++++++++++++++------------------------- 3 files changed, 66 insertions(+), 53 deletions(-) diff --git a/include/mp/common.h b/include/mp/common.h index b7e4aab04..de00159d7 100644 --- a/include/mp/common.h +++ b/include/mp/common.h @@ -149,11 +149,6 @@ namespace sol { * (use description from the comment.) For extra codes, use * passing ranges (e.g., for stopping with a feasible solution * on a limit, use 400-449), otherwise SPECIFIC+ codes. - * - * If a code description's 2nd-last word is 'codes' (case-sensitive), - * for example: - * 'solved? solution candidate may be infeasible; codes 100-199', - * this code is printed as a header. */ enum Status { /** If not touched. Don't register this code. */ @@ -274,11 +269,11 @@ enum Status { LIMIT_NO_FEAS_SOFTMEM = LIMIT_NO_FEAS + 10, /** Failure, without a feasible solution. - Codes 500-599. + Codes 500-999. With a feasible solution, use LIMIT_FEAS_FAILURE. */ FAILURE = 500, /** End of the 'failure' range. */ - FAILURE_LAST = 599, + FAILURE_LAST = 999, /** Failure. A numeric issue without a feasible solution. * With a feasible solution, use UNCERTAIN. */ diff --git a/include/mp/solver-base.h b/include/mp/solver-base.h index 74d4dfc80..5a001dbca 100644 --- a/include/mp/solver-base.h +++ b/include/mp/solver-base.h @@ -2,6 +2,7 @@ #define SOLVERBASE_H #include +#include #include "solver-opt.h" #include "common.h" @@ -105,8 +106,43 @@ class SolveResultRegistry { /// Destroy virtual ~SolveResultRegistry() { } + /// Registry entry. + /// This is a pair, + /// meaning a range (first-last) of result codes. + /// Plus a description. + class RegEntry { + public: + /// Construct from a range + RegEntry(int a, int b, std::string d) + : first_(a), last_(b), descr_(std::move(d)) + { assert(a<=b); } + /// Construct from a single code + RegEntry(int a, std::string d) + : first_(a), last_(a), descr_(std::move(d)) { } + /// Is signle code? + bool isSingle() const { return first()==last(); } + /// First + int first() const { return first_; } + /// Last + int last() const { return last_; } + /// Descr + const std::string& descr() const { return descr_; } + /// operator<: + /// We need range 100-199 to come before range 100-149 + /// before single code 100, etc. + bool operator<(const RegEntry& k) const { + return first() < k.first() + ? true : first() > k.first() + ? false : last() > k.last(); + } + private: + int first_; + int last_; + std::string descr_; + }; + /// Registry map - using SRRegMap = std::map; + using SRRegMap = std::set; /// Add a map with result descriptions void AddSolveResults(const SRRegMap& sm, diff --git a/src/solver.cc b/src/solver.cc index 6d458cd1b..727a8d599 100644 --- a/src/solver.cc +++ b/src/solver.cc @@ -400,26 +400,11 @@ bool SolverAppOptionParser::ShowSolverOptions(const char* param) { bool SolverAppOptionParser::ShowSolveResults() { solver_.Print("Solve result table for {}\n", solver_.long_name()); for (const auto& sr: solver_.GetSolveResultRegistry()) { - const auto& desc = sr.second; - bool fHeader = false; - auto p2=desc.size()-1; // find 2nd last word - while (p2