Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions ortools/linear_solver/cplex_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)