diff --git a/include/mp/backend-std.h b/include/mp/backend-std.h index fe37586b5..296833587 100644 --- a/include/mp/backend-std.h +++ b/include/mp/backend-std.h @@ -383,6 +383,13 @@ class StdBackend : auto wrn = GetWarnings(); if (wrn.size()) writer.write("\n{}", wrn); + const auto& scw0 = GetWarning(GetSolCheckWarningKey(false)); + const auto& scw1 = GetWarning(GetSolCheckWarningKey(true)); + if (scw0.second.size() || scw1.second.size()) { + ++ stats_.n_altern_sol_checks_failed_; + ClearWarning(GetSolCheckWarningKey(false)); + ClearWarning(GetSolCheckWarningKey(true)); + } if (round() && MP_DISPATCH(IsMIP())) RoundSolution(sol.primal, writer); HandleFeasibleSolution(SolveCode(), writer.c_str(), @@ -450,6 +457,10 @@ class StdBackend : kIntermSol_, solution_stub(), solution_stub(), kIntermSol_); + if (stats_.n_altern_sol_checks_failed_) + writer.write( + "{} alternative solution checks failed.\n", + stats_.n_altern_sol_checks_failed_); } auto wrn = GetWarnings(); if (wrn.size()) @@ -569,6 +580,7 @@ class StdBackend : steady_clock::time_point time = steady_clock::now(); double setup_time = 0.0; double solution_time = 0.0; + int n_altern_sol_checks_failed_ = 0; }; Stats stats_; @@ -606,6 +618,7 @@ class StdBackend : ///////////////////////// STORING SOLVER MESSAGES ////////////////////// private: std::string solver_msg_extra_; + protected: void AddToSolverMessage(const std::string& msg) { solver_msg_extra_ += msg; } diff --git a/include/mp/solver-base.h b/include/mp/solver-base.h index 187ad2920..ec70a8aeb 100644 --- a/include/mp/solver-base.h +++ b/include/mp/solver-base.h @@ -335,6 +335,13 @@ class BasicSolver : private ErrorHandler, void AddWarning( std::string key, std::string msg, bool replace=false); + /// Get a warning type + const std::pair& + GetWarning(const std::string& key); + + /// Clear a warning type + void ClearWarning(const std::string& key); + /// Get warnings as string std::string GetWarnings() const; @@ -399,8 +406,7 @@ class BasicSolver : private ErrorHandler, void ParseOptionString(const char *s, unsigned flags); /// Map to count warnings by types. - /// Stores char* to names / descriptions for speed - /// Indexed by pointers to names, not values + /// Stores just 1 message for each type. using WarningsMap = std::map< std::string, // warning category std::pair >; // total number, description of the 1st diff --git a/src/solver.cc b/src/solver.cc index 13467d666..46937f573 100644 --- a/src/solver.cc +++ b/src/solver.cc @@ -703,6 +703,20 @@ void BasicSolver::AddWarning( v.second = std::move(msg); } +/// Get a warning type +const std::pair& +BasicSolver::GetWarning(const std::string& key) { + static std::pair dummy; + const auto& wm = GetWarningsMap(); + if (wm.end() != wm.find(key)) + return wm.at(key); + return dummy; +} + +void BasicSolver::ClearWarning(const std::string& key) { + GetWarningsMap().erase(key); +} + std::string BasicSolver::GetWarnings() const { if (GetWarningsMap().size()) { std::string wrn = "------------ WARNINGS ------------\n";