Update cplex_interface.cc

add cplex warmstart and parameters setting(set solver log file path by "LogFile" parameter)
This commit is contained in:
Robot
2023-04-27 16:06:45 +08:00
committed by GitHub
parent 5425dedcfb
commit 2571fc533c

View File

@@ -17,6 +17,7 @@
#include <memory>
#include "absl/strings/str_format.h"
#include "absl/strings/str_split.h"
#include "ortools/base/integral_types.h"
#include "ortools/base/logging.h"
#include "ortools/base/timer.h"
@@ -115,6 +116,8 @@ class CplexInterface : public MPSolverInterface {
virtual bool IsLP() const { return !mMip; }
virtual bool IsMIP() const { return mMip; }
bool SetSolverSpecificParametersAsString(
const std::string &parameters) override;
virtual void ExtractNewVariables();
virtual void ExtractNewConstraints();
virtual void ExtractObjective();
@@ -1108,6 +1111,18 @@ MPSolver::ResultStatus CplexInterface::Solve(MPSolverParameters const& param) {
CHECK_STATUS(
CPXXsetintparam(mEnv, CPX_PARAM_SCRIND, quiet() ? CPX_OFF : CPX_ON));
if (!solver_->solution_hint_.empty()) {
int const sol_count = solver_->solution_hint_.size();
long long int beg[1] = {0};
int *varindices = new int[sol_count];
double *values = new double[sol_count];
for (int i=0; i<sol_count; ++i) {
varindices[i] = solver_->solution_hint_[i].first->index();
values[i] = solver_->solution_hint_[i].second;
}
CPXaddmipstarts (mEnv, mLp, 1, sol_count, beg, varindices, values, NULL, NULL);
}
// Set parameters.
// NOTE: We must invoke SetSolverSpecificParametersAsString() _first_.
// Its current implementation invokes ReadParameterFile() which in
@@ -1272,5 +1287,47 @@ MPSolverInterface* BuildCplexInterface(bool mip, MPSolver* const solver) {
return new CplexInterface(solver, mip);
}
bool CplexInterface::SetSolverSpecificParametersAsString(
const std::string &parameters) {
if (parameters.empty())
return true;
for (const auto parameter : absl::StrSplit(parameters, absl::ByAnyChar(","),
absl::SkipWhitespace())) {
std::vector<std::string> key_value =
absl::StrSplit(parameter, absl::ByAnyChar("="), absl::SkipWhitespace());
if (key_value.size() != 2) {
LOG(WARNING) << absl::StrFormat(
"Cannot parse parameter '%s'. Expected format is 'parameter/name = "
"value'",
parameter);
continue;
}
std::string identifier = key_value[0];
absl::RemoveExtraAsciiWhitespace(&identifier);
std::string value = key_value[1];
absl::RemoveExtraAsciiWhitespace(&value);
try {
if(identifier.find("LogFile") != std::string::npos) {
CPXXsetlogfilename (mEnv, value.c_str(), "w");
} else {
std::string delimiter = ".";
if (value.find(delimiter) == std::string::npos) {
(void)CPXXsetintparam(mEnv, std::stoi(identifier), std::stoi(value));
} else {
(void)CPXXsetdblparam(mEnv, std::stoi(identifier), std::stod(value));
}
VLOG(2) << absl::StrFormat("Set parameter %s to %s", identifier, value);
}
} catch (...) {
LOG(WARNING) << absl::StrFormat(
"Cannot parse parameter '%s'. Expected format is 'parameter/name = value'",
identifier);
}
}
return true;
}
} // namespace operations_research
#endif // #if defined(USE_CPLEX)