Skip to content

Commit 98d5740

Browse files
authored
Merge pull request ERGO-Code#2490 from ERGO-Code/debugsol
Expand MIP debug solution capabilities
2 parents dc5dca0 + d5ff107 commit 98d5740

File tree

4 files changed

+54
-28
lines changed

4 files changed

+54
-28
lines changed

highs/mip/HighsDebugSol.cpp

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,30 +35,44 @@ void HighsDebugSol::activate() {
3535
if (file) {
3636
std::string varname;
3737
double varval;
38+
std::string line;
39+
bool incolsection;
3840
std::map<std::string, int> nametoidx;
3941

40-
for (HighsInt i = 0; i != mipsolver->model_->num_col_; ++i)
41-
nametoidx["c" + std::to_string(i)] = i;
42+
for (HighsInt i = 0; i != mipsolver->orig_model_->num_col_; ++i)
43+
nametoidx[mipsolver->orig_model_->col_names_[i]] = i;
4244

43-
debugSolution.resize(mipsolver->model_->num_col_, 0.0);
44-
while (!file.eof()) {
45-
file >> varname;
45+
debugOrigSolution.resize(mipsolver->orig_model_->num_col_, 0.0);
46+
while (std::getline(file, line)) {
47+
// Check for start and stop markers
48+
if (line.find("# Columns") != std::string::npos) {
49+
incolsection = true;
50+
continue;
51+
}
52+
if (line.find("# Rows") != std::string::npos) {
53+
break;
54+
}
55+
if (!incolsection) continue;
56+
57+
std::istringstream linestream(line);
58+
linestream >> varname;
4659
auto it = nametoidx.find(varname);
4760
if (it != nametoidx.end()) {
48-
file >> varval;
61+
linestream >> varval;
62+
debugOrigSolution[it->second] = varval;
4963
highsLogDev(mipsolver->options_mip_->log_options, HighsLogType::kInfo,
5064
"%s = %g\n", varname.c_str(), varval);
51-
debugSolution[it->second] = varval;
65+
debugOrigSolution[it->second] = varval;
5266
}
53-
54-
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
5567
}
68+
debugSolution = debugOrigSolution;
5669

5770
HighsCDouble debugsolobj = 0.0;
58-
for (HighsInt i = 0; i != mipsolver->model_->num_col_; ++i)
59-
debugsolobj += mipsolver->model_->col_cost_[i] * debugSolution[i];
71+
for (HighsInt i = 0; i != mipsolver->orig_model_->num_col_; ++i)
72+
debugsolobj += mipsolver->orig_model_->col_cost_[i] *
73+
HighsCDouble(debugOrigSolution[i]);
6074

61-
debugSolObjective = double(debugsolobj);
75+
debugSolObjective = double(debugsolobj + mipsolver->orig_model_->offset_);
6276
debugSolActive = true;
6377
printf("debug sol active\n");
6478
registerDomain(mipsolver->mipdata_->domain);

highs/mip/HighsDebugSol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class HighsLp;
2929
struct HighsDebugSol {
3030
const HighsMipSolver* mipsolver;
3131
double debugSolObjective;
32+
std::vector<double> debugOrigSolution;
3233
std::vector<double> debugSolution;
3334
bool debugSolActive;
3435
std::unordered_map<const HighsDomain*, std::multiset<HighsDomainChange>>

highs/mip/HighsMipSolver.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ void HighsMipSolver::run() {
8787
analysis_.mipTimerStart(kMipClockInit);
8888
mipdata_->init();
8989
analysis_.mipTimerStop(kMipClockInit);
90+
#ifdef HIGHS_DEBUGSOL
91+
mipdata_->debugSolution.activate();
92+
bool debugSolActive = false;
93+
std::swap(mipdata_->debugSolution.debugSolActive, debugSolActive);
94+
#endif
9095
analysis_.mipTimerStart(kMipClockRunPresolve);
9196
mipdata_->runPresolve(options_mip_->presolve_reduction_limit);
9297
analysis_.mipTimerStop(kMipClockRunPresolve);
@@ -119,6 +124,9 @@ void HighsMipSolver::run() {
119124
highsLogUser(options_mip_->log_options, HighsLogType::kInfo,
120125
"MIP-Timing: %11.2g - starting setup\n", timer_.read());
121126
analysis_.mipTimerStart(kMipClockRunSetup);
127+
#ifdef HIGHS_DEBUGSOL
128+
mipdata_->debugSolution.debugSolActive = debugSolActive;
129+
#endif
122130
mipdata_->runSetup();
123131
analysis_.mipTimerStop(kMipClockRunSetup);
124132
if (analysis_.analyse_mip_time && !submip)

highs/mip/HighsMipSolverData.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -694,11 +694,6 @@ void HighsMipSolverData::init() {
694694
}
695695

696696
void HighsMipSolverData::runPresolve(const HighsInt presolve_reduction_limit) {
697-
#ifdef HIGHS_DEBUGSOL
698-
bool debugSolActive = false;
699-
std::swap(debugSolution.debugSolActive, debugSolActive);
700-
#endif
701-
702697
mipsolver.timer_.start(mipsolver.timer_.presolve_clock);
703698
presolve::HPresolve presolve;
704699
if (!presolve.okSetInput(mipsolver, presolve_reduction_limit)) {
@@ -709,13 +704,6 @@ void HighsMipSolverData::runPresolve(const HighsInt presolve_reduction_limit) {
709704
presolve_status = presolve.getPresolveStatus();
710705
}
711706
mipsolver.timer_.stop(mipsolver.timer_.presolve_clock);
712-
713-
#ifdef HIGHS_DEBUGSOL
714-
debugSolution.debugSolActive = debugSolActive;
715-
if (debugSolution.debugSolActive) debugSolution.registerDomain(domain);
716-
assert(!debugSolution.debugSolActive ||
717-
checkSolution(debugSolution.debugSolution));
718-
#endif
719707
}
720708

721709
void HighsMipSolverData::runSetup() {
@@ -1022,10 +1010,18 @@ void HighsMipSolverData::runSetup() {
10221010
heuristics.setupIntCols();
10231011

10241012
#ifdef HIGHS_DEBUGSOL
1025-
if (numRestarts == 0) {
1026-
debugSolution.activate();
1027-
assert(!debugSolution.debugSolActive ||
1028-
checkSolution(debugSolution.debugSolution));
1013+
if (debugSolution.debugSolActive) {
1014+
debugSolution.debugSolution.clear();
1015+
debugSolution.debugSolution = postSolveStack.getReducedPrimalSolution(
1016+
debugSolution.debugOrigSolution);
1017+
debugSolution.debugSolObjective = 0;
1018+
HighsCDouble debugsolobj = 0.0;
1019+
for (HighsInt i = 0; i != mipsolver.model_->num_col_; ++i)
1020+
debugsolobj +=
1021+
mipsolver.colCost(i) * HighsCDouble(debugSolution.debugSolution[i]);
1022+
debugSolution.debugSolObjective = static_cast<double>(debugsolobj);
1023+
debugSolution.registerDomain(domain);
1024+
assert(checkSolution(debugSolution.debugSolution));
10291025
}
10301026
#endif
10311027

@@ -1218,6 +1214,10 @@ void HighsMipSolverData::performRestart() {
12181214
presolvedModel = lp.getLp();
12191215
presolvedModel.offset_ = offset;
12201216
presolvedModel.integrality_ = std::move(integrality);
1217+
#ifdef HIGHS_DEBUGSOL
1218+
bool debugSolActive = false;
1219+
std::swap(debugSolution.debugSolActive, debugSolActive);
1220+
#endif
12211221

12221222
const HighsBasis& basis = firstrootbasis;
12231223
if (basis.valid) {
@@ -1321,6 +1321,9 @@ void HighsMipSolverData::performRestart() {
13211321
}
13221322
// Bounds are currently in the original space since presolve will have
13231323
// changed offset_
1324+
#ifdef HIGHS_DEBUGSOL
1325+
debugSolution.debugSolActive = debugSolActive;
1326+
#endif
13241327
runSetup();
13251328

13261329
postSolveStack.removeCutsFromModel(numCuts);

0 commit comments

Comments
 (0)