From da7dc5e0704757a74f98b55556417daf61ce2927 Mon Sep 17 00:00:00 2001 From: "lperron@google.com" Date: Fri, 17 Jan 2014 19:04:26 +0000 Subject: [PATCH] remove MPSolver::*Objective* setters, getters, use setters/getters on objective --- .../samples/IntegerProgramming.java | 6 +- .../samples/LinearProgramming.java | 11 +-- examples/csharp/csintegerprogramming.cs | 10 +-- examples/csharp/cslinearprogramming.cs | 14 ++-- examples/csharp/volsay.cs | 2 +- examples/csharp/volsay3.cs | 2 +- examples/python/3_jugs_mip.py | 2 +- examples/python/assignment6_mip.py | 2 +- examples/python/blending.py | 2 +- examples/python/coloring_ip.py | 2 +- examples/python/diet1_mip.py | 2 +- examples/python/game_theory_taha.py | 4 +- examples/python/integer_programming.py | 7 +- examples/python/knapsack_mip.py | 2 +- examples/python/least_square.py | 2 +- examples/python/linear_programming.py | 11 +-- examples/python/production.py | 2 +- examples/python/stigler.py | 2 +- examples/python/volsay.py | 2 +- examples/python/volsay2.py | 2 +- examples/python/volsay3.py | 2 +- src/linear_solver/gurobi_interface.cc | 5 +- src/linear_solver/linear_solver.cc | 36 +--------- src/linear_solver/linear_solver.h | 16 ----- src/linear_solver/linear_solver.swig | 69 +++++++++---------- src/linear_solver/model_exporter.cc | 27 ++++++-- src/linear_solver/model_exporter.h | 5 ++ 27 files changed, 115 insertions(+), 134 deletions(-) diff --git a/examples/com/google/ortools/linearsolver/samples/IntegerProgramming.java b/examples/com/google/ortools/linearsolver/samples/IntegerProgramming.java index 3374aeef6d..811646e03f 100644 --- a/examples/com/google/ortools/linearsolver/samples/IntegerProgramming.java +++ b/examples/com/google/ortools/linearsolver/samples/IntegerProgramming.java @@ -54,8 +54,8 @@ public class IntegerProgramming { MPVariable x2 = solver.makeIntVar(0.0, infinity, "x2"); // Minimize x1 + 2 * x2. - solver.setObjectiveCoefficient(x1, 1); - solver.setObjectiveCoefficient(x2, 2); + solver.objective().setCoefficient(x1, 1); + solver.objective().setCoefficient(x2, 2); // 2 * x2 + 3 * x1 >= 17. MPConstraint ct = solver.makeConstraint(17, infinity); @@ -75,7 +75,7 @@ public class IntegerProgramming { // The objective value of the solution. System.out.println("Optimal objective value = " + - solver.objectiveValue()); + solver.objective().value()); // The value of each variable in the solution. System.out.println("x1 = " + x1.solutionValue()); diff --git a/examples/com/google/ortools/linearsolver/samples/LinearProgramming.java b/examples/com/google/ortools/linearsolver/samples/LinearProgramming.java index 2d5c5f9c45..6445055940 100644 --- a/examples/com/google/ortools/linearsolver/samples/LinearProgramming.java +++ b/examples/com/google/ortools/linearsolver/samples/LinearProgramming.java @@ -55,10 +55,10 @@ public class LinearProgramming { MPVariable x3 = solver.makeNumVar(0.0, infinity, "x3"); // Maximize 10 * x1 + 6 * x2 + 4 * x3. - solver.setObjectiveCoefficient(x1, 10); - solver.setObjectiveCoefficient(x2, 6); - solver.setObjectiveCoefficient(x3, 4); - solver.setMaximization(); + solver.objective().setCoefficient(x1, 10); + solver.objective().setCoefficient(x2, 6); + solver.objective().setCoefficient(x3, 4); + solver.objective().setMaximization(); // x1 + x2 + x3 <= 100. MPConstraint c0 = solver.makeConstraint(-infinity, 100.0); @@ -93,7 +93,8 @@ public class LinearProgramming { " milliseconds"); // The objective value of the solution. - System.out.println("Optimal objective value = " + solver.objectiveValue()); + System.out.println("Optimal objective value = " + + solver.objective().value()); // The value of each variable in the solution. System.out.println("x1 = " + x1.solutionValue()); diff --git a/examples/csharp/csintegerprogramming.cs b/examples/csharp/csintegerprogramming.cs index f9c01fa2ed..39f41bf593 100644 --- a/examples/csharp/csintegerprogramming.cs +++ b/examples/csharp/csintegerprogramming.cs @@ -29,8 +29,8 @@ public class CsIntegerProgramming Variable x2 = solver.MakeIntVar(0.0, double.PositiveInfinity, "x2"); // Minimize x1 + 2 * x2. - solver.SetObjectiveCoefficient(x1, 1); - solver.SetObjectiveCoefficient(x2, 2); + solver.Objective().SetCoefficient(x1, 1); + solver.Objective().SetCoefficient(x2, 2); // 2 * x2 + 3 * x1 >= 17. Constraint ct = solver.MakeConstraint(17, double.PositiveInfinity); @@ -50,7 +50,8 @@ public class CsIntegerProgramming " milliseconds"); // The objective value of the solution. - Console.WriteLine("Optimal objective value = " + solver.ObjectiveValue()); + Console.WriteLine("Optimal objective value = " + + solver.Objective().Value()); // The value of each variable in the solution. Console.WriteLine("x1 = " + x1.SolutionValue()); @@ -89,7 +90,8 @@ public class CsIntegerProgramming " milliseconds"); // The objective value of the solution. - Console.WriteLine("Optimal objective value = " + solver.ObjectiveValue()); + Console.WriteLine("Optimal objective value = " + + solver.Objective().Value()); // The value of each variable in the solution. Console.WriteLine("x1 = " + x1.SolutionValue()); diff --git a/examples/csharp/cslinearprogramming.cs b/examples/csharp/cslinearprogramming.cs index 05d38b7f39..2d7be341d4 100644 --- a/examples/csharp/cslinearprogramming.cs +++ b/examples/csharp/cslinearprogramming.cs @@ -30,10 +30,10 @@ public class CsLinearProgramming Variable x3 = solver.MakeNumVar(0.0, double.PositiveInfinity, "x3"); // Maximize 10 * x1 + 6 * x2 + 4 * x3. - solver.SetObjectiveCoefficient(x1, 10); - solver.SetObjectiveCoefficient(x2, 6); - solver.SetObjectiveCoefficient(x3, 4); - solver.SetMaximization(); + solver.Objective().SetCoefficient(x1, 10); + solver.Objective().SetCoefficient(x2, 6); + solver.Objective().SetCoefficient(x3, 4); + solver.Objective().SetMaximization(); // x1 + x2 + x3 <= 100. Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 100.0); @@ -68,7 +68,8 @@ public class CsLinearProgramming " milliseconds"); // The objective value of the solution. - Console.WriteLine("Optimal objective value = " + solver.ObjectiveValue()); + Console.WriteLine("Optimal objective value = " + + solver.Objective().Value()); // The value of each variable in the solution. Console.WriteLine("x1 = " + x1.SolutionValue()); @@ -122,7 +123,8 @@ public class CsLinearProgramming " milliseconds"); // The objective value of the solution. - Console.WriteLine("Optimal objective value = " + solver.ObjectiveValue()); + Console.WriteLine("Optimal objective value = " + + solver.Objective().Value()); // The value of each variable in the solution. Console.WriteLine("x1 = " + x1.SolutionValue()); diff --git a/examples/csharp/volsay.cs b/examples/csharp/volsay.cs index 99c08eb6d1..a04a2f44e4 100644 --- a/examples/csharp/volsay.cs +++ b/examples/csharp/volsay.cs @@ -57,7 +57,7 @@ public class Volsay return; } - Console.WriteLine("Objective: {0}", solver.ObjectiveValue()); + Console.WriteLine("Objective: {0}", solver.Objective().Value()); Console.WriteLine("Gas : {0} ReducedCost: {1}", Gas.SolutionValue(), diff --git a/examples/csharp/volsay3.cs b/examples/csharp/volsay3.cs index 5fc57d8a6b..f2310bd024 100644 --- a/examples/csharp/volsay3.cs +++ b/examples/csharp/volsay3.cs @@ -87,7 +87,7 @@ public class Volsay3 return; } - Console.WriteLine("Objective: {0}", solver.ObjectiveValue()); + Console.WriteLine("Objective: {0}", solver.Objective().Value()); foreach(int p in PRODUCTS) { Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", products[p], diff --git a/examples/python/3_jugs_mip.py b/examples/python/3_jugs_mip.py index 33c3747f9e..8560811bb7 100644 --- a/examples/python/3_jugs_mip.py +++ b/examples/python/3_jugs_mip.py @@ -150,7 +150,7 @@ def main(sol = 'GLPK'): solver.Solve() print - print 'z: ', int(solver.ObjectiveValue()) + print 'z: ', int(solver.Objective().Value()) t = start while t != end: diff --git a/examples/python/assignment6_mip.py b/examples/python/assignment6_mip.py index 0a0fbcfd98..04be504256 100644 --- a/examples/python/assignment6_mip.py +++ b/examples/python/assignment6_mip.py @@ -136,7 +136,7 @@ def main(sol = 'GLPK'): solver.Solve() print - print 'z: ', int(solver.ObjectiveValue()) + print 'z: ', int(solver.Objective().Value()) print 'Assigned' for j in J: diff --git a/examples/python/blending.py b/examples/python/blending.py index 28c351e873..ef6e738c32 100644 --- a/examples/python/blending.py +++ b/examples/python/blending.py @@ -106,7 +106,7 @@ def main(sol = 'GLPK'): print - print 'z = ', solver.ObjectiveValue() + print 'z = ', solver.Objective().Value() print 'Metals' for i in Metals: print p[i].SolutionValue(), diff --git a/examples/python/coloring_ip.py b/examples/python/coloring_ip.py index abb365d309..617e2fcbb7 100644 --- a/examples/python/coloring_ip.py +++ b/examples/python/coloring_ip.py @@ -143,7 +143,7 @@ def main(sol = 'GLPK'): solver.Solve() print - print "number of colors:", int(solver.ObjectiveValue()) + print "number of colors:", int(solver.Objective().Value()) print "colors used:", [int(u[i].SolutionValue()) for i in range(nc)] print diff --git a/examples/python/diet1_mip.py b/examples/python/diet1_mip.py index 1d937d93dc..da0b5ef93a 100644 --- a/examples/python/diet1_mip.py +++ b/examples/python/diet1_mip.py @@ -94,7 +94,7 @@ def main(sol = 'GLPK'): # solver.Solve() - print "Cost:", solver.ObjectiveValue() + print "Cost:", solver.Objective().Value() print [int(x[i].SolutionValue()) for i in range(n)] print diff --git a/examples/python/game_theory_taha.py b/examples/python/game_theory_taha.py index 6bad7b050e..45891747d0 100644 --- a/examples/python/game_theory_taha.py +++ b/examples/python/game_theory_taha.py @@ -74,7 +74,7 @@ def main(sol = 'GLPK'): print print 'row player:'; - print 'v = ', solver.ObjectiveValue() + print 'v = ', solver.Objective().Value() print 'Strategies: ' for i in range(rows): print x1[i].SolutionValue(), @@ -101,7 +101,7 @@ def main(sol = 'GLPK'): print print 'column player:'; - print 'v2 = ', solver.ObjectiveValue() + print 'v2 = ', solver.Objective().Value() print 'Strategies: ' for i in range(rows): print x2[i].SolutionValue(), diff --git a/examples/python/integer_programming.py b/examples/python/integer_programming.py index 8299c54dfe..fa116016ba 100644 --- a/examples/python/integer_programming.py +++ b/examples/python/integer_programming.py @@ -45,8 +45,9 @@ def RunIntegerExampleCppStyleAPI(optimization_problem_type): x2 = solver.IntVar(0.0, infinity, 'x2') # Minimize x1 + 2 * x2. - solver.SetObjectiveCoefficient(x1, 1) - solver.SetObjectiveCoefficient(x2, 2) + objective = solver.Objective() + objective.SetCoefficient(x1, 1) + objective.SetCoefficient(x2, 2) # 2 * x2 + 3 * x1 >= 17. ct = solver.Constraint(17, infinity) @@ -69,7 +70,7 @@ def SolveAndPrint(solver, variable_list): print('Problem solved in %f milliseconds' % solver.WallTime()) # The objective value of the solution. - print('Optimal objective value = %f' % solver.ObjectiveValue()) + print('Optimal objective value = %f' % solver.Objective().Value()) # The value of each variable in the solution. for variable in variable_list: diff --git a/examples/python/knapsack_mip.py b/examples/python/knapsack_mip.py index 1b0263b712..943ae25014 100644 --- a/examples/python/knapsack_mip.py +++ b/examples/python/knapsack_mip.py @@ -86,7 +86,7 @@ def main(sol = 'GLPK'): solver.Solve() print - print 'z: ', int(solver.ObjectiveValue()) + print 'z: ', int(solver.Objective().Value()) print 'take:', for i in items: diff --git a/examples/python/least_square.py b/examples/python/least_square.py index ed09ed4821..67b92da9db 100644 --- a/examples/python/least_square.py +++ b/examples/python/least_square.py @@ -81,7 +81,7 @@ def main(sol = 'GLPK'): solver.Solve() print - print 'z = ', solver.ObjectiveValue() + print 'z = ', solver.Objective().Value() for i in range(p + 1): print a[i].SolutionValue(), print diff --git a/examples/python/linear_programming.py b/examples/python/linear_programming.py index b63830d771..b2a6aa4eaf 100644 --- a/examples/python/linear_programming.py +++ b/examples/python/linear_programming.py @@ -50,10 +50,11 @@ def RunLinearExampleCppStyleAPI(optimization_problem_type): x3 = solver.NumVar(0.0, infinity, 'x3') # Maximize 10 * x1 + 6 * x2 + 4 * x3. - solver.SetObjectiveCoefficient(x1, 10) - solver.SetObjectiveCoefficient(x2, 6) - solver.SetObjectiveCoefficient(x3, 4) - solver.SetMaximization() + objective = solver.Objective() + objective.SetCoefficient(x1, 10) + objective.SetCoefficient(x2, 6) + objective.SetCoefficient(x3, 4) + objective.SetMaximization() # x1 + x2 + x3 <= 100. c0 = solver.Constraint(-infinity, 100.0, 'c0') @@ -89,7 +90,7 @@ def SolveAndPrint(solver, variable_list, constraint_list): print('Problem solved in %f milliseconds' % solver.WallTime()) # The objective value of the solution. - print('Optimal objective value = %f' % solver.ObjectiveValue()) + print('Optimal objective value = %f' % solver.Objective().Value()) # The value of each variable in the solution. for variable in variable_list: diff --git a/examples/python/production.py b/examples/python/production.py index 69964ff4a9..17e9ab5793 100644 --- a/examples/python/production.py +++ b/examples/python/production.py @@ -86,7 +86,7 @@ def main(sol = 'GLPK'): solver.Solve() print - print 'z = ', solver.ObjectiveValue() + print 'z = ', solver.Objective().Value() for p in range(num_products): print products[p], ': inside:', inside[p].SolutionValue(), '(ReducedCost:', inside[p].ReducedCost(), ')', diff --git a/examples/python/stigler.py b/examples/python/stigler.py index 655624ae65..4e994f40ac 100644 --- a/examples/python/stigler.py +++ b/examples/python/stigler.py @@ -365,7 +365,7 @@ def main(sol = 'GLPK'): print - print 'Cost = %0.2f' % solver.ObjectiveValue() + print 'Cost = %0.2f' % solver.Objective().Value() # print 'Cost:', cost.SolutionValue() print 'Total cost: %0.2f' % total_cost.SolutionValue() print diff --git a/examples/python/volsay.py b/examples/python/volsay.py index e123c0ceff..f83b90eb1c 100644 --- a/examples/python/volsay.py +++ b/examples/python/volsay.py @@ -62,7 +62,7 @@ def main(unused_argv): solver.Solve() print - print 'objective = ', solver.ObjectiveValue() + print 'objective = ', solver.Objective().Value() print 'Gas = ', Gas.SolutionValue(), 'ReducedCost =', Gas.ReducedCost() print 'Chloride:', Chloride.SolutionValue(), 'ReducedCost =', Chloride.ReducedCost() diff --git a/examples/python/volsay2.py b/examples/python/volsay2.py index 90303ca55a..cbe7872b1d 100644 --- a/examples/python/volsay2.py +++ b/examples/python/volsay2.py @@ -67,7 +67,7 @@ def main(unused_argv): solver.Solve() print - print 'objective = ', solver.ObjectiveValue() + print 'objective = ', solver.Objective().Value() for i in range(num_products): print products[i], '=', production[i].SolutionValue(), print 'ReducedCost = ', production[i].ReducedCost() diff --git a/examples/python/volsay3.py b/examples/python/volsay3.py index 51686e8737..781e998b81 100644 --- a/examples/python/volsay3.py +++ b/examples/python/volsay3.py @@ -76,7 +76,7 @@ def main(unused_argv): solver.Solve() print - print 'objective = ', solver.ObjectiveValue() + print 'objective = ', solver.Objective().Value() for i in range(num_products): print products[i], '=', production[i].SolutionValue(), print 'ReducedCost = ', production[i].ReducedCost() diff --git a/src/linear_solver/gurobi_interface.cc b/src/linear_solver/gurobi_interface.cc index af979351f4..c9a7ae08c5 100644 --- a/src/linear_solver/gurobi_interface.cc +++ b/src/linear_solver/gurobi_interface.cc @@ -664,9 +664,8 @@ MPSolver::ResultStatus GurobiInterface::Solve(const MPSolverParameters& param) { } } - if (solution_count > 0) { - DCHECK(result_status_ == MPSolver::FEASIBLE || - result_status_ == MPSolver::OPTIMAL); + if (solution_count > 0 && (result_status_ == MPSolver::FEASIBLE || + result_status_ == MPSolver::OPTIMAL)) { // Get the results. const int total_num_rows = solver_->constraints_.size(); const int total_num_cols = solver_->variables_.size(); diff --git a/src/linear_solver/linear_solver.cc b/src/linear_solver/linear_solver.cc index 0b474ae34c..cac6f709a5 100644 --- a/src/linear_solver/linear_solver.cc +++ b/src/linear_solver/linear_solver.cc @@ -263,37 +263,6 @@ void MPVariable::SetInteger(bool integer) { } } -// ----- Objective (DEPRECATED methods) ----- - -double MPSolver::objective_value() const { return Objective().Value(); } - -double MPSolver::best_objective_bound() const { - return Objective().BestBound(); -} - -void MPSolver::ClearObjective() { MutableObjective()->Clear(); } - -void MPSolver::SetObjectiveCoefficient(const MPVariable* const var, - double coeff) { - MutableObjective()->SetCoefficient(var, coeff); -} - -void MPSolver::SetObjectiveOffset(double value) { - MutableObjective()->SetOffset(value); -} - -void MPSolver::AddObjectiveOffset(double value) { - MutableObjective()->AddOffset(value); -} - -void MPSolver::SetOptimizationDirection(bool maximize) { - MutableObjective()->SetOptimizationDirection(maximize); -} - -bool MPSolver::Maximization() const { return Objective().maximization(); } - -bool MPSolver::Minimization() const { return Objective().minimization(); } - // ----- Version ----- std::string MPSolver::SolverVersion() const { return interface_->SolverVersion(); } @@ -506,9 +475,9 @@ MPSolver::LoadStatus MPSolver::LoadModelFromProto( ct_proto.coefficient(j)); } } - SetOptimizationDirection(input_model.maximize()); + objective->SetOptimizationDirection(input_model.maximize()); if (input_model.has_objective_offset()) { - MutableObjective()->SetOffset(input_model.objective_offset()); + objective->SetOffset(input_model.objective_offset()); } return MPSolver::NO_ERROR; } @@ -1426,3 +1395,4 @@ int MPSolverParameters::GetIntegerParam(MPSolverParameters::IntegerParam param) } // namespace operations_research + diff --git a/src/linear_solver/linear_solver.h b/src/linear_solver/linear_solver.h index 12d1b320d8..a6738c8f98 100644 --- a/src/linear_solver/linear_solver.h +++ b/src/linear_solver/linear_solver.h @@ -517,22 +517,6 @@ class MPSolver { // Debugging: verify that the given MPVariable* belongs to this solver. bool OwnsVariable(const MPVariable* var) const; - // *** DEPRECATED *** - // Setters and getters for the objective. Please call - // Objective().Getter() and MutableObjective()->Setter() instead. - // TODO(user): remove when they are no longer used. - double objective_value() const; - double best_objective_bound() const; - void ClearObjective(); - void SetObjectiveCoefficient(const MPVariable* const var, double coeff); - void SetObjectiveOffset(double value); - void AddObjectiveOffset(double value); - void SetOptimizationDirection(bool maximize); - void SetMinimization() { SetOptimizationDirection(false); } - void SetMaximization() { SetOptimizationDirection(true); } - bool Maximization() const; - bool Minimization() const; - private: // Computes the size of the constraint with the largest number of // coefficients with index in [min_constraint_index, diff --git a/src/linear_solver/linear_solver.swig b/src/linear_solver/linear_solver.swig index e18e31b70a..247bfb40b7 100644 --- a/src/linear_solver/linear_solver.swig +++ b/src/linear_solver/linear_solver.swig @@ -24,7 +24,6 @@ %} #ifdef SWIGPYTHON - // Define the renaming of methods. %ignore MakeBoolVarArray; %ignore MakeIntVarArray; @@ -47,7 +46,6 @@ %rename (LookupVariable) LookupVariableOrNull; %rename (Nodes) nodes; %rename (NumVar) MakeNumVar; -%rename (ObjectiveValue) objective_value; %rename (Offset) offset; %rename (ReducedCost) reduced_cost; %rename (SetLb) SetLB; @@ -437,30 +435,30 @@ class LinearConstraint(object): return self.Constraint(*args) def Minimize(self, expr): - self.ClearObjective() - self.SetMinimization() + self.Objective().Clear() + self.Objective().SetMinimization() coeffs = {} offset = expr.Visit(coeffs) - self.AddObjectiveOffset(offset) + self.Objective().SetOffset(offset) if sys.version_info[0] >= 3: # Python 3 for v, c, in coeffs.items(): - self.SetObjectiveCoefficient(v, float(c)) + self.Objective().SetCoefficient(v, float(c)) else: for v, c, in coeffs.iteritems(): - self.SetObjectiveCoefficient(v, float(c)) + self.Objective().SetCoefficient(v, float(c)) def Maximize(self, expr): - self.ClearObjective() - self.SetMaximization() + self.Objective().Clear() + self.Objective().SetMaximization() coeffs = {} offset = expr.Visit(coeffs) - self.AddObjectiveOffset(offset) + self.Objective().SetOffset(offset) if sys.version_info[0] >= 3: # Python 3 for v, c, in coeffs.items(): - self.SetObjectiveCoefficient(v, float(c)) + self.Objective().SetCoefficient(v, float(c)) else: for v, c, in coeffs.iteritems(): - self.SetObjectiveCoefficient(v, float(c)) + self.Objective().SetCoefficient(v, float(c)) } } @@ -520,12 +518,11 @@ namespace operations_research { %rename (setIntegerParam) MPSolverParameters::SetIntegerParam; // Rename rules on MPSolver. -%rename (addObjectiveOffset) MPSolver::AddObjectiveOffset; -%rename (bestObjectiveBound) MPSolver::best_objective_bound; %rename (checkAllNamesValidity) MPSolver::CheckAllNamesValidity; %rename (checkNameValidity) MPSolver::CheckNameValidity; +%rename (clear) MPConstraint::Clear; +%rename (clear) MPObjective::Clear; %rename (clear) MPSolver::Clear; -%rename (clearObjective) MPSolver::ClearObjective; %rename (computeExactConditionNumber) MPSolver::ComputeExactConditionNumber; %rename (loadModel) MPSolver::LoadModel; %rename (lookupVariableOrNull) MPSolver::LookupVariableOrNull; @@ -539,13 +536,12 @@ namespace operations_research { %rename (numConstraints) MPSolver::NumConstraints; %rename (numVariables) MPSolver::NumVariables; %rename (objective) MPSolver::MutableObjective; -%rename (objectiveValue) MPSolver::objective_value; %rename (reset) MPSolver::Reset; -%rename (setMaximization) MPSolver::SetMaximization; -%rename (setMinimization) MPSolver::SetMinimization; -%rename (setObjectiveCoefficient) MPSolver::SetObjectiveCoefficient; -%rename (setObjectiveOffset) MPSolver::SetObjectiveOffset; -%rename (setOptimizationDirection) MPSolver::SetOptimizationDirection; +%rename (setMaximization) MPObjective::SetMaximization(); +%rename (setMinimization) MPObjective::SetMinimization(); +%rename (setCoefficient) MPObjective::SetCoefficient; +%rename (setOffset) MPObjective::SetOffset; +%rename (setOptimizationDirection) MPObjective::SetOptimizationDirection; %rename (setTimeLimit) MPSolver::set_time_limit; %rename (setWriteModelFilename) MPSolver::set_write_model_filename; %rename (solve) MPSolver::Solve; @@ -679,6 +675,9 @@ namespace operations_research { %ignore MPSolver::ExportModelToNewProto; %ignore MPSolver::FillSolutionResponse; %ignore MPSolver::SolveWithProtocolBuffers; +// Ignore Objective(), use MutableObjective() instead. +%ignore MPSolver::Objective; +%rename (Objective) MPSolver::MutableObjective; %typemap(cscode) MPVariable %{ public static LinearExpr operator+(Variable a, double v) @@ -1040,44 +1039,44 @@ namespace operations_research { public void Minimize(LinearExpr expr) { - ClearObjective(); - SetMinimization(); + Objective().Clear(); + Objective().SetMinimization(); Dictionary coefficients = new Dictionary(); double constant = expr.Visit(coefficients); foreach (KeyValuePair pair in coefficients) { - SetObjectiveCoefficient(pair.Key, pair.Value); + Objective().SetCoefficient(pair.Key, pair.Value); } - SetObjectiveOffset(constant); + Objective().SetOffset(constant); } public void Maximize(LinearExpr expr) { - ClearObjective(); - SetMaximization(); + Objective().Clear(); + Objective().SetMaximization(); Dictionary coefficients = new Dictionary(); double constant = expr.Visit(coefficients); foreach (KeyValuePair pair in coefficients) { - SetObjectiveCoefficient(pair.Key, pair.Value); + Objective().SetCoefficient(pair.Key, pair.Value); } - SetObjectiveOffset(constant); + Objective().SetOffset(constant); } public void Minimize(Variable var) { - ClearObjective(); - SetMinimization(); - SetObjectiveCoefficient(var, 1.0); + Objective().Clear(); + Objective().SetMinimization(); + Objective().SetCoefficient(var, 1.0); } public void Maximize(Variable var) { - ClearObjective(); - SetMaximization(); - SetObjectiveCoefficient(var, 1.0); + Objective().Clear(); + Objective().SetMaximization(); + Objective().SetCoefficient(var, 1.0); } %} diff --git a/src/linear_solver/model_exporter.cc b/src/linear_solver/model_exporter.cc index 436d0c4121..1f26bf570a 100644 --- a/src/linear_solver/model_exporter.cc +++ b/src/linear_solver/model_exporter.cc @@ -15,6 +15,7 @@ #include #include +#include "base/commandlineflags.h" #include "base/integral_types.h" #include "base/logging.h" #include "base/stringprintf.h" @@ -24,6 +25,10 @@ #include "linear_solver/linear_solver2.pb.h" #include "util/fp_utils.h" +DEFINE_bool(lp_shows_unused_variables, false, + "Decides wether variable unused in the objective and constraints" + " are shown when exported to a file using the lp format."); + namespace operations_research { using new_proto::MPConstraintProto; @@ -111,6 +116,9 @@ void MPModelProtoExporter::AppendComments(const std::string& separator, num_integer_variables_); StringAppendF(output, "%s %-14s : %d\n", sep, "Continuous", num_continuous_variables_); + if (FLAGS_lp_shows_unused_variables) { + StringAppendF(output, "%s Unused variables are shown\n", sep); + } } bool MPModelProtoExporter::AppendLpTerm(int var_index, double coefficient, @@ -189,22 +197,28 @@ bool MPModelProtoExporter::ExportModelAsLpFormat(bool obfuscated, if (proto_.objective_offset() != 0.0) { StringAppendF(output, "%-+.16G Constant ", proto_.objective_offset()); } - for (int i = 0; i < proto_.variable_size(); ++i) { - if (!AppendLpTerm(i, proto_.variable(i).objective_coefficient(), output)) { + std::vector show_variable(proto_.variable_size(), + FLAGS_lp_shows_unused_variables); + for (int var_index = 0; var_index < proto_.variable_size(); ++var_index) { + const double coeff = proto_.variable(var_index).objective_coefficient(); + if (!AppendLpTerm(var_index, coeff, output)) { return false; } + show_variable[var_index] = coeff != 0.0 || FLAGS_lp_shows_unused_variables; } - // Constraints StringAppendF(output, "\nSubject to\n"); for (int cst_index = 0; cst_index < proto_.constraint_size(); ++cst_index) { const MPConstraintProto& ct_proto = proto_.constraint(cst_index); std::string term; for (int i = 0; i < ct_proto.var_index_size(); ++i) { - if (!AppendLpTerm(ct_proto.var_index(i), ct_proto.coefficient(i), - &term)) { + const int var_index = ct_proto.var_index(i); + const double coeff = ct_proto.coefficient(i); + if (!AppendLpTerm(var_index, coeff, &term)) { return false; } + show_variable[var_index] = + coeff != 0.0 || FLAGS_lp_shows_unused_variables; } const double lb = ct_proto.lower_bound(); const double ub = ct_proto.upper_bound(); @@ -238,6 +252,7 @@ bool MPModelProtoExporter::ExportModelAsLpFormat(bool obfuscated, StringAppendF(output, " 1 <= Constant <= 1\n"); } for (int var_index = 0; var_index < proto_.variable_size(); ++var_index) { + if (!show_variable[var_index]) continue; const MPVariableProto& var_proto = proto_.variable(var_index); const double lb = var_proto.lower_bound(); const double ub = var_proto.upper_bound(); @@ -260,6 +275,7 @@ bool MPModelProtoExporter::ExportModelAsLpFormat(bool obfuscated, if (num_binary_variables_ > 0) { StringAppendF(output, "Binaries\n"); for (int var_index = 0; var_index < proto_.variable_size(); ++var_index) { + if (!show_variable[var_index]) continue; const MPVariableProto& var_proto = proto_.variable(var_index); if (IsBoolean(var_proto)) { StringAppendF(output, " %s\n", GetVariableName(var_index).c_str()); @@ -271,6 +287,7 @@ bool MPModelProtoExporter::ExportModelAsLpFormat(bool obfuscated, if (num_integer_variables_ > 0) { StringAppendF(output, "Generals\n"); for (int var_index = 0; var_index < proto_.variable_size(); ++var_index) { + if (!show_variable[var_index]) continue; const MPVariableProto& var_proto = proto_.variable(var_index); if (var_proto.is_integer() && !IsBoolean(var_proto)) { StringAppendF(output, " %s\n", GetVariableName(var_index).c_str()); diff --git a/src/linear_solver/model_exporter.h b/src/linear_solver/model_exporter.h index f07b7ed5ad..bedaa2852f 100644 --- a/src/linear_solver/model_exporter.h +++ b/src/linear_solver/model_exporter.h @@ -116,6 +116,11 @@ class MPModelProtoExporter { // Appends a general "Comment" section with useful metadata about the model // to "output". + // Note(user): there may be less variables in output than in the original + // model, as unused variables are not shown by default. Similarly, there + // may be more constraints in a .lp file as in the original model as + // a constraint lhs <= term <= rhs will be output as the two constraints + // term >= lhs and term <= rhs. void AppendComments(const std::string& separator, std::string* output) const; // Appends a term to "output", in "Lp" format.