polish lp code
This commit is contained in:
@@ -1675,21 +1675,9 @@ bool MPSolverInterface::SetSolverSpecificParametersAsString(
|
||||
if (parameters.empty()) return true;
|
||||
|
||||
std::string extension = ValidFileExtensionForParameterFile();
|
||||
#if defined(__linux)
|
||||
int32 tid = static_cast<int32>(pthread_self());
|
||||
#else // defined(__linux__)
|
||||
int32 tid = 123;
|
||||
#endif // defined(__linux__)
|
||||
#if !defined(_MSC_VER)
|
||||
int32 pid = static_cast<int32>(getpid());
|
||||
#else // _MSC_VER
|
||||
int32 pid = 456;
|
||||
#endif // _MSC_VER
|
||||
int64 now = absl::GetCurrentTimeNanos();
|
||||
std::string filename =
|
||||
absl::StrFormat("/tmp/parameters-tempfile-%x-%d-%llx%s", tid, pid, now,
|
||||
extension.c_str());
|
||||
bool no_error_so_far = true;
|
||||
std::string filename;
|
||||
bool no_error_so_far = PortableTemporaryFile(nullptr, &filename);
|
||||
filename += extension;
|
||||
if (no_error_so_far) {
|
||||
no_error_so_far = PortableFileSetContents(filename, parameters).ok();
|
||||
}
|
||||
|
||||
@@ -15,89 +15,90 @@
|
||||
# [START import]
|
||||
from __future__ import print_function
|
||||
from ortools.linear_solver import pywraplp
|
||||
|
||||
# [END import]
|
||||
|
||||
|
||||
# [START data_model]
|
||||
def create_data_model():
|
||||
"""Stores the data for the problem."""
|
||||
data = {}
|
||||
# Locations in block units
|
||||
data['constraint_coeffs'] = [
|
||||
[5, 7, 9, 2, 1],
|
||||
[18, 4, -9, 10, 12],
|
||||
[4, 7, 3, 8, 5],
|
||||
[5, 13, 16, 3, -7],
|
||||
]
|
||||
data['bounds'] = [250, 285, 211, 315]
|
||||
data['obj_coeffs'] = [7, 8, 2, 9, 6]
|
||||
data['num_vars'] = 5
|
||||
data['num_constraints'] = 4
|
||||
return data
|
||||
"""Stores the data for the problem."""
|
||||
data = {}
|
||||
# Locations in block units
|
||||
data['constraint_coeffs'] = [
|
||||
[5, 7, 9, 2, 1],
|
||||
[18, 4, -9, 10, 12],
|
||||
[4, 7, 3, 8, 5],
|
||||
[5, 13, 16, 3, -7],
|
||||
]
|
||||
data['bounds'] = [250, 285, 211, 315]
|
||||
data['obj_coeffs'] = [7, 8, 2, 9, 6]
|
||||
data['num_vars'] = 5
|
||||
data['num_constraints'] = 4
|
||||
return data
|
||||
|
||||
|
||||
# [END data_model]
|
||||
|
||||
|
||||
def main():
|
||||
# [START data]
|
||||
data = create_data_model()
|
||||
# [END data]
|
||||
# [START data]
|
||||
data = create_data_model()
|
||||
# [END data]
|
||||
|
||||
# [START solver]
|
||||
# MOE:begin_strip
|
||||
# Create the mip solver with the CBC backend.
|
||||
solver = pywraplp.Solver(
|
||||
'simple_mip_program',
|
||||
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
|
||||
# [END solver]
|
||||
# [START variables]
|
||||
infinity = solver.infinity()
|
||||
x = {}
|
||||
for j in range(data['num_vars']):
|
||||
x[j] = solver.IntVar(0, infinity, 'x[%i]' % j)
|
||||
print('Number of variables =', solver.NumVariables())
|
||||
# [END variables]
|
||||
|
||||
# [START constraints]
|
||||
for i in range(data['num_constraints']):
|
||||
constraint = solver.RowConstraint(0, data['bounds'][i], '')
|
||||
# [START solver]
|
||||
# Create the mip solver with the CBC backend.
|
||||
solver = pywraplp.Solver('simple_mip_program',
|
||||
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
|
||||
# [END solver]
|
||||
# [START variables]
|
||||
infinity = solver.infinity()
|
||||
x = {}
|
||||
for j in range(data['num_vars']):
|
||||
constraint.SetCoefficient(x[j], data['constraint_coeffs'][i][j])
|
||||
print('Number of constraints =', solver.NumConstraints())
|
||||
# In Python, you can also set the constraints as follows.
|
||||
# for i in range(data['num_constraints']):
|
||||
# constraint_expr = \
|
||||
# [data['constraint_coeffs'][i][j] * x[j] for j in range(data['num_vars'])]
|
||||
# solver.Add(sum(constraint_expr) <= data['bounds'][i])
|
||||
# [END constraints]
|
||||
x[j] = solver.IntVar(0, infinity, 'x[%i]' % j)
|
||||
print('Number of variables =', solver.NumVariables())
|
||||
# [END variables]
|
||||
|
||||
# [START objective]
|
||||
objective = solver.Objective()
|
||||
for j in range(data['num_vars']):
|
||||
objective.SetCoefficient(x[j], data['obj_coeffs'][j])
|
||||
objective.SetMaximization()
|
||||
# In Python, you can also set the objective as follows.
|
||||
# obj_expr = [data['obj_coeffs'][j] * x[j] for j in range(data['num_vars'])]
|
||||
# solver.Maximize(solver.Sum(obj_expr))
|
||||
# [END objective]
|
||||
# [START constraints]
|
||||
for i in range(data['num_constraints']):
|
||||
constraint = solver.RowConstraint(0, data['bounds'][i], '')
|
||||
for j in range(data['num_vars']):
|
||||
constraint.SetCoefficient(x[j], data['constraint_coeffs'][i][j])
|
||||
print('Number of constraints =', solver.NumConstraints())
|
||||
# In Python, you can also set the constraints as follows.
|
||||
# for i in range(data['num_constraints']):
|
||||
# constraint_expr = \
|
||||
# [data['constraint_coeffs'][i][j] * x[j] for j in range(data['num_vars'])]
|
||||
# solver.Add(sum(constraint_expr) <= data['bounds'][i])
|
||||
# [END constraints]
|
||||
|
||||
# [START solve]
|
||||
status = solver.Solve()
|
||||
# [END solve]
|
||||
|
||||
# [START print_solution]
|
||||
if status == pywraplp.Solver.OPTIMAL:
|
||||
print('Objective value =', solver.Objective().Value())
|
||||
# [START objective]
|
||||
objective = solver.Objective()
|
||||
for j in range(data['num_vars']):
|
||||
print(x[j].name(), ' = ', x[j].solution_value())
|
||||
print()
|
||||
print('Problem solved in %f milliseconds' % solver.wall_time())
|
||||
print('Problem solved in %d iterations' % solver.iterations())
|
||||
print('Problem solved in %d branch-and-bound nodes' % solver.nodes())
|
||||
else:
|
||||
print('The problem does not have an optimal solution.')
|
||||
# [END print_solution]
|
||||
objective.SetCoefficient(x[j], data['obj_coeffs'][j])
|
||||
objective.SetMaximization()
|
||||
# In Python, you can also set the objective as follows.
|
||||
# obj_expr = [data['obj_coeffs'][j] * x[j] for j in range(data['num_vars'])]
|
||||
# solver.Maximize(solver.Sum(obj_expr))
|
||||
# [END objective]
|
||||
|
||||
# [START solve]
|
||||
status = solver.Solve()
|
||||
# [END solve]
|
||||
|
||||
# [START print_solution]
|
||||
if status == pywraplp.Solver.OPTIMAL:
|
||||
print('Objective value =', solver.Objective().Value())
|
||||
for j in range(data['num_vars']):
|
||||
print(x[j].name(), ' = ', x[j].solution_value())
|
||||
print()
|
||||
print('Problem solved in %f milliseconds' % solver.wall_time())
|
||||
print('Problem solved in %d iterations' % solver.iterations())
|
||||
print('Problem solved in %d branch-and-bound nodes' % solver.nodes())
|
||||
else:
|
||||
print('The problem does not have an optimal solution.')
|
||||
# [END print_solution]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
# [END program]
|
||||
|
||||
@@ -91,7 +91,22 @@ util::StatusOr<MPSolutionResponse> SatSolveProto(
|
||||
}
|
||||
|
||||
MPModelProto* const mp_model = request.mutable_model();
|
||||
auto shift_bounds_preprocessor = ApplyMipPresolveSteps(mp_model);
|
||||
std::unique_ptr<glop::ShiftVariableBoundsPreprocessor>
|
||||
shift_bounds_preprocessor;
|
||||
|
||||
const auto status =
|
||||
ApplyMipPresolveSteps(mp_model, &shift_bounds_preprocessor);
|
||||
if (status == MPSolverResponseStatus::MPSOLVER_INFEASIBLE) {
|
||||
if (params.log_search_progress()) {
|
||||
// This is needed for our benchmark scripts.
|
||||
sat::CpSolverResponse cp_response;
|
||||
cp_response.set_status(sat::CpSolverStatus::INFEASIBLE);
|
||||
LOG(INFO) << CpSolverResponseStats(cp_response);
|
||||
}
|
||||
response.set_status(MPSolverResponseStatus::MPSOLVER_INFEASIBLE);
|
||||
response.set_status_str("Problem proven infeasible during MIP presolve");
|
||||
return response;
|
||||
}
|
||||
const std::vector<double> var_scaling =
|
||||
sat::ScaleContinuousVariables(params.mip_var_scaling(), mp_model);
|
||||
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
|
||||
namespace operations_research {
|
||||
|
||||
std::unique_ptr<glop::ShiftVariableBoundsPreprocessor> ApplyMipPresolveSteps(
|
||||
MPModelProto* model) {
|
||||
return nullptr;
|
||||
MPSolverResponseStatus ApplyMipPresolveSteps(
|
||||
MPModelProto* model, std::unique_ptr<glop::ShiftVariableBoundsPreprocessor>*
|
||||
shift_bounds_preprocessor) {
|
||||
return MPSolverResponseStatus::MPSOLVER_NOT_SOLVED;
|
||||
}
|
||||
|
||||
} // namespace operations_research
|
||||
|
||||
@@ -21,12 +21,18 @@
|
||||
|
||||
namespace operations_research {
|
||||
|
||||
// Apply presolve steps to improve the MIP -> IP imperfect conversion. The
|
||||
// Applies presolve steps to improve the MIP -> IP imperfect conversion. The
|
||||
// stricter the domain of the variable, the more room we have for scaling the
|
||||
// constraint to integers and prevent overflow.
|
||||
// If the bounds were shifted, returns the shifting preprocessor.
|
||||
std::unique_ptr<glop::ShiftVariableBoundsPreprocessor> ApplyMipPresolveSteps(
|
||||
MPModelProto* model);
|
||||
//
|
||||
// If the bounds were shifted, pass in the preprocessor for postsolve to the
|
||||
// given unique_ptr.
|
||||
//
|
||||
// Returns the presolve status which is currently UNKNOWN for most cases but
|
||||
// might be INFEASIBLE if there is some trivial infeasiblity in the model.
|
||||
MPSolverResponseStatus ApplyMipPresolveSteps(
|
||||
MPModelProto* model, std::unique_ptr<glop::ShiftVariableBoundsPreprocessor>*
|
||||
shift_bounds_preprocessor);
|
||||
|
||||
} // namespace operations_research
|
||||
#endif // OR_TOOLS_LINEAR_SOLVER_SAT_SOLVER_UTILS_H_
|
||||
|
||||
@@ -111,9 +111,9 @@ class SCIPInterface : public MPSolverInterface {
|
||||
void SetRelativeMipGap(double value) override;
|
||||
void SetPrimalTolerance(double value) override;
|
||||
void SetDualTolerance(double value) override;
|
||||
void SetPresolveMode(int value) override;
|
||||
void SetScalingMode(int value) override;
|
||||
void SetLpAlgorithm(int value) override;
|
||||
void SetPresolveMode(int presolve) override;
|
||||
void SetScalingMode(int scaling) override;
|
||||
void SetLpAlgorithm(int lp_algorithm) override;
|
||||
|
||||
// SCIP parameters allow to lower and upper bound the number of threads used
|
||||
// (via "parallel/minnthreads" and "parallel/maxnthread", respectively). Here,
|
||||
@@ -712,7 +712,8 @@ MPSolver::ResultStatus SCIPInterface::Solve(const MPSolverParameters& param) {
|
||||
default:
|
||||
if (solution != nullptr) {
|
||||
result_status_ = MPSolver::FEASIBLE;
|
||||
} else if (scip_status == SCIP_STATUS_TIMELIMIT) {
|
||||
} else if (scip_status == SCIP_STATUS_TIMELIMIT ||
|
||||
scip_status == SCIP_STATUS_TOTALNODELIMIT) {
|
||||
result_status_ = MPSolver::NOT_SOLVED;
|
||||
} else {
|
||||
result_status_ = MPSolver::ABNORMAL;
|
||||
@@ -821,9 +822,9 @@ void SCIPInterface::SetDualTolerance(double value) {
|
||||
if (status_.ok()) status_ = status;
|
||||
}
|
||||
|
||||
void SCIPInterface::SetPresolveMode(int value) {
|
||||
void SCIPInterface::SetPresolveMode(int presolve) {
|
||||
// See the NOTE on SetRelativeMipGap().
|
||||
switch (value) {
|
||||
switch (presolve) {
|
||||
case MPSolverParameters::PRESOLVE_OFF: {
|
||||
const auto status =
|
||||
SCIP_TO_STATUS(SCIPsetIntParam(scip_, "presolving/maxrounds", 0));
|
||||
@@ -837,22 +838,22 @@ void SCIPInterface::SetPresolveMode(int value) {
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
SetIntegerParamToUnsupportedValue(MPSolverParameters::PRESOLVE, value);
|
||||
SetIntegerParamToUnsupportedValue(MPSolverParameters::PRESOLVE, presolve);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SCIPInterface::SetScalingMode(int value) {
|
||||
void SCIPInterface::SetScalingMode(int scaling) {
|
||||
SetUnsupportedIntegerParam(MPSolverParameters::SCALING);
|
||||
}
|
||||
|
||||
// Only the root LP algorithm is set as setting the node LP to a
|
||||
// non-default value rarely is beneficial. The node LP algorithm could
|
||||
// be set as well with "lp/resolvealgorithm".
|
||||
void SCIPInterface::SetLpAlgorithm(int value) {
|
||||
void SCIPInterface::SetLpAlgorithm(int lp_algorithm) {
|
||||
// See the NOTE on SetRelativeMipGap().
|
||||
switch (value) {
|
||||
switch (lp_algorithm) {
|
||||
case MPSolverParameters::DUAL: {
|
||||
const auto status =
|
||||
SCIP_TO_STATUS(SCIPsetCharParam(scip_, "lp/initalgorithm", 'd'));
|
||||
@@ -874,7 +875,7 @@ void SCIPInterface::SetLpAlgorithm(int value) {
|
||||
}
|
||||
default: {
|
||||
SetIntegerParamToUnsupportedValue(MPSolverParameters::LP_ALGORITHM,
|
||||
value);
|
||||
lp_algorithm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "ortools/base/file.h"
|
||||
#include "ortools/port/file.h"
|
||||
|
||||
@@ -28,7 +35,20 @@ namespace operations_research {
|
||||
|
||||
bool PortableTemporaryFile(const char* directory_prefix,
|
||||
std::string* filename_out) {
|
||||
return false;
|
||||
#if defined(__linux)
|
||||
int32 tid = static_cast<int32>(pthread_self());
|
||||
#else // defined(__linux__)
|
||||
int32 tid = 123;
|
||||
#endif // defined(__linux__)
|
||||
#if !defined(_MSC_VER)
|
||||
int32 pid = static_cast<int32>(getpid());
|
||||
#else // _MSC_VER
|
||||
int32 pid = 456;
|
||||
#endif // _MSC_VER
|
||||
int64 now = absl::GetCurrentTimeNanos();
|
||||
std::string filename =
|
||||
absl::StrFormat("/tmp/parameters-tempfile-%x-%d-%llx", tid, pid, now);
|
||||
return true;
|
||||
}
|
||||
|
||||
::util::Status PortableDeleteFile(absl::string_view file_name) {
|
||||
|
||||
Reference in New Issue
Block a user