Skip to content

Commit de63402

Browse files
committed
Show non-default parameters as a formatted section before solve
Collect parameter-change messages during parsing and display them in a 'Non-default parameters' section (with UTF-8 arrow) just before the solve starts, instead of printing them inline after problem loading.
1 parent 079dc63 commit de63402

2 files changed

Lines changed: 52 additions & 7 deletions

File tree

src/CbcSolver.cpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,6 +2484,43 @@ void CbcSolver::resetRunState()
24842484
statistics_ = CbcSolverStatistics();
24852485
}
24862486

2487+
void CbcSolver::printParamChanges()
2488+
{
2489+
if (paramChanges_.empty())
2490+
return;
2491+
const bool u8 = CbcOutput::useUtf8();
2492+
const char *arrow = u8 ? " \xe2\x86\x92 " : " -> ";
2493+
FILE *fp = stderr;
2494+
fprintf(fp, "\n%s\n\n",
2495+
CoinTable::phaseStart("Non-default parameters", u8).c_str());
2496+
for (const auto &msg : paramChanges_) {
2497+
std::string name, oldVal, newVal;
2498+
size_t p1 = msg.find("Option for ");
2499+
size_t p2 = msg.find(" changed from ");
2500+
size_t p3 = msg.find(" to ");
2501+
if (p1 != std::string::npos && p2 != std::string::npos && p3 != std::string::npos) {
2502+
name = msg.substr(p1 + 11, p2 - (p1 + 11));
2503+
oldVal = msg.substr(p2 + 14, p3 - (p2 + 14));
2504+
newVal = msg.substr(p3 + 4);
2505+
} else {
2506+
p2 = msg.find(" was changed from ");
2507+
p3 = (p2 != std::string::npos) ? msg.find(" to ", p2 + 18) : std::string::npos;
2508+
if (p2 != std::string::npos && p3 != std::string::npos) {
2509+
name = msg.substr(0, p2);
2510+
oldVal = msg.substr(p2 + 18, p3 - (p2 + 18));
2511+
newVal = msg.substr(p3 + 4);
2512+
}
2513+
}
2514+
while (!newVal.empty() && (newVal.back() == '\n' || newVal.back() == ' '))
2515+
newVal.pop_back();
2516+
if (!name.empty())
2517+
fprintf(fp, " %s %s%s%s\n", name.c_str(), oldVal.c_str(), arrow, newVal.c_str());
2518+
else
2519+
fprintf(fp, " %s", msg.c_str());
2520+
}
2521+
paramChanges_.clear();
2522+
}
2523+
24872524
//###########################################################################
24882525
//###########################################################################
24892526

@@ -7308,7 +7345,7 @@ int CbcSolver::run(std::deque< std::string > inputQueue,
73087345
printGeneralWarning(model_, message);
73097346
continue;
73107347
} else {
7311-
printGeneralMessage(model_, message);
7348+
if (!message.empty()) paramChanges_.push_back(message);
73127349
}
73137350
// TODO: These should be moved to the push function
73147351
switch (cbcParamCode) {
@@ -7427,13 +7464,13 @@ int CbcSolver::run(std::deque< std::string > inputQueue,
74277464
printGeneralWarning(model_, message);
74287465
continue;
74297466
}
7430-
printGeneralMessage(model_, message);
7467+
if (!message.empty()) paramChanges_.push_back(message);
74317468
} else {
74327469
if (cbcParam->setVal(iValue, &message)) {
74337470
printGeneralWarning(model_, message);
74347471
continue;
74357472
}
7436-
printGeneralMessage(model_, message);
7473+
if (!message.empty()) paramChanges_.push_back(message);
74377474
if (cbcParamCode == CbcParam::CUTPASS) {
74387475
cutPass = iValue;
74397476
} else if (cbcParamCode == CbcParam::USESOLUTION) {
@@ -7619,7 +7656,7 @@ int CbcSolver::run(std::deque< std::string > inputQueue,
76197656
printGeneralWarning(model_, message);
76207657
continue;
76217658
} else {
7622-
printGeneralMessage(model_, message);
7659+
if (!message.empty()) paramChanges_.push_back(message);
76237660
}
76247661
if (clpParamCode == ClpParam::PRESOLVEPASS) {
76257662
preSolve = iValue;
@@ -7657,7 +7694,7 @@ int CbcSolver::run(std::deque< std::string > inputQueue,
76577694
printGeneralWarning(model_, message);
76587695
continue;
76597696
}
7660-
printGeneralMessage(model_, message);
7697+
if (!message.empty()) paramChanges_.push_back(message);
76617698
int mode = cbcParam->modeVal();
76627699
// TODO: this should be part of the push method
76637700
switch (cbcParamCode) {
@@ -8719,14 +8756,15 @@ int CbcSolver::run(std::deque< std::string > inputQueue,
87198756

87208757
switch (cbcParamCode) {
87218758
case CbcParam::SOLVECONTINUOUS: {
8722-
// Solve the LP relaxation via applyLpMethod(), which handles fast
8723-
// preprocessing, clique merging "before", model-level LP settings,
8759+
// Solve the LP relaxation via applyLpMethod(), which handles bound
8760+
// propagation, clique merging "before", model-level LP settings,
87248761
// LP racing, and the full configured ClpSolve solve — all using the
87258762
// same member-variable state as the -solve (BAB) path.
87268763
if (!goodModel) {
87278764
printGeneralWarning(model_, "** Current model not valid\n");
87288765
continue;
87298766
}
8767+
printParamChanges();
87308768
integerStatus = -1;
87318769
#ifndef CBC_OTHER_SOLVER
87328770
if (clpSolver)
@@ -8946,6 +8984,7 @@ int CbcSolver::run(std::deque< std::string > inputQueue,
89468984
printGeneralWarning(model_, "** Current model not valid\n");
89478985
break;
89488986
}
8987+
printParamChanges();
89498988
#ifdef CBC_CLUMSY_CODING
89508989
parameters.setModel(&model_);
89518990
parameters.setGoodModel(true);

src/CbcSolver.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,13 +476,19 @@ class CBCLIB_EXPORT CbcSolver {
476476

477477
// --- Input queue copies ---
478478
std::deque<std::string> saveInputQueue_;
479+
480+
/// Collected parameter-change messages (printed as a section before solve)
481+
std::vector<std::string> paramChanges_;
479482
//@}
480483

481484
///@name Private helpers
482485
//@{
483486
/// Reset cross-phase state to defaults (called by initialize)
484487
void resetRunState();
485488

489+
/// Print collected parameter changes as a formatted section, then clear.
490+
void printParamChanges();
491+
486492
/** Handle the IMPORT action: read an MPS/LP/GMPL file into the model.
487493
Called from run() when the IMPORT command is encountered.
488494
\param inputQueue Command queue (for reading filename and .par file)

0 commit comments

Comments
 (0)