Getting LP relaxation solution values - python

To get the final solution after optimization in pyscipopt, we can do
# define x to be a vector of x_ij variables
model.data = x
model.optimize()
X = model.getVal(x)
I would like to get the LP relaxation solutions at every node of the branch and bound tree. One method for doing this would be to use model.getVal(t_x_ij) for every (transformed) variable 'x_ij'. Is there a more efficient way of doing this than looping over all the transformed variables?
Please let me know if you need any further clarifications.

If you are solving a MIP, you would need to get the LP solution values during the solving process. You need to implement a callback that is executed whenever a new node LP is solved.
You might want to check out TreeD, a project I created to inspect and visualize various LP-related information during the MIP solving process of PySCIPOpt.

Related

How to obtain multiple solutions of a binary LP problem using Google's OR-Tools in Python?

I am new to integer optimization. I am trying to solve the following large (although not that large) binary linear optimization problem:
max_{x} x_1+x_2+...+x_n
subject to: A*x <= b ; x_i is binary for all i=1,...,n
As you can see,
. the control variable is a vector x of lengh, say, n=150; x_i is binary for all i=1,...,n
. I want to maximize the sum of the x_i's
. in the constraint, A is an nxn matrix and b is an nx1 vector. So I have n=150 linear inequality constraints.
I want to obtain a certain number of solutions, NS. Say, NS=100. (I know there is more than one solution, and there are potentially millions of them.)
I am using Google's OR-Tools for Python. I was able to write the problem and to obtain one solution. I have tried many different ways to obtain more solutions after that, but I just couldn't. For example:
I tried using the SCIP solver, and then I used the value of the objective function at the optimum, call it V, to add another constraint, x_1+x_2+...+x_n >= V, on top of the original "Ax<=b," and then used the CP-SAT solver to find NS feasible vectors (I followed the instructions in this guide). There is no optimization in this second step, just a quest for feasibility. This didn't work: the solver produced N replicas of the same vector. Still, when asked for the number of solutions found, it misleadingly replies that solution_printer.solution_count() is equal to NS. Here's a snippet of the code that I used:
# Define the constraints (A and b are lists)
for j in range(n):
constraint_expr = [int(A[j][l])*x[l] for l in range(n)]
model.Add(sum(constraint_expr) <= int(b[j][0]))
V = 112
constraint_obj_val = [-x[l] for l in range(n)]
model.Add(sum(constraint_obj_val) <= -V)
# Call the solver:
solver = cp_model.CpSolver()
solution_printer = VarArraySolutionPrinterWithLimit(x, NS)
solver.parameters.enumerate_all_solutions = True
status = solver.Solve(model, solution_printer)
I tried using the SCIP solver and then using solver.NextSolution(), but every time I was using this command, the algorithm would produce a vector that was less and less optimal every time: the first one corresponded to a value of, say, V=112 (the optimal one!); the second vector corresponded to a value of 111; the third one, to 108; fourth to sixth, to 103; etc.
My question is, unfortunately, a bit vague, but here it goes: what's the best way to obtain more than one solution to my optimization problem?
Please let me know if I'm not being clear enough or if you need more/other chunks of the code, etc. This is my first time posting a question here :)
Thanks in advance.
Is your matrix A integral ? if not, you are not solving the same problem with scip and CP-SAT.
Furthermore, why use scip? You should solve both part with the same solver.
Furthermore, I believe the default solution pool implementation in scip will return all solutions found, in reverse order, thus in decreasing quality order.
In Gurobi, you can do something like this to get more than one optimal solution :
solver->SetSolverSpecificParametersAsString("PoolSearchMode=2"); // or-tools [Gurobi]
From Gurobi Reference [Section 20.1]:
By default, the Gurobi MIP solver will try to find one proven optimal solution to your model.
You can use the PoolSearchMode parameter to control the approach used to find solutions.
In its default setting (0), the MIP search simply aims to find one
optimal solution. Setting the parameter to 1 causes the MIP search to
expend additional effort to find more solutions, but in a
non-systematic way. You will get more solutions, but not necessarily
the best solutions. Setting the parameter to 2 causes the MIP to do a
systematic search for the n best solutions. For both non-default
settings, the PoolSolutions parameter sets the target for the number
of solutions to find.
Another way to find multiple optimal solutions could be to first solve the original problem to optimality and then add the objective function as a constraint with lower and upper bound as the optimal objective value.

Confusion in Python Pyomo Components (Parameter and Variable)

I am learning Pyomo Abstract Modeling from a Book.
I have an example that has an objective functionEquation is here to minimize the cost of establishing a warehouse at optimal locations to build warehouses to meet delivery demands.
The authors modeled the objective with this script Script is here.
Here in the script "model.d" is "Param" and "model.x" is "Var"
Why he has used Param for "model.d" and "Var" for "model.x"?
Please take spare precious time to help me to get out of this.
Not only in pyomo, but in general, for Operations Researchs or Optimization. A Parameter is a given value that you know prior solving the problem. On the other hand, a Variable is a value that you will find solving the problem in order to get the best solution.
Suposse that in your problem model.d is the cost of constructing the warehouse model.x. This means that for each potential warehouse x, construct it cost d. This assumme that if your building a warehouse, you know the capital cost of constructing such a warehouse, therefore, it is known before solving the problem, then model.d is a parameter. model.x is variable since you don't know whether if construct it or not. You want want the model to tell you that, therefore, it is a variable

objective function with binary variables

I am working on a complex model in pyomo. Unfortunately, i have to change the formula of the objective function, based on how is the previous value.
In particular my objective function is composed of two terms ,call them A and B, that have different order of magnitude (A is usually 2 or 3 order of magnitude higher than B, but this may vary)
In order to guarantee that A and B have the same weight of the formula, i need to write my objective function as below:
objective= A + B*K`
Where K is the value which bring the second term at the same scale/magnitude of A
example:
A=4e10
B=2e3
K=1e(10-3)=1e7
The problem is that, in order to know K, i must know the values of A and B, but pyomo doesn't give value, it just pass an expression to the solver.
I have read that thanks to a smart use of binary variables is possible to overcome this issue, anyone could suggest a useful methodology?
Kind regards
It seems like you are dealing with a multi-objective optimization problem. Since the values of variables involved in A and B are not known before solving the model, you can't define the value of K based on A and B.
There are different ways to solve multi-objective optimization problems which you can consider for your specific problem (e.g., ε-constraints method). In these problems, usually you are not interested in finding a single solution, but finding a set of Pareto optimal solutions which are not dominated by any other solution in the feasible region.

Is it possible to model a min-max-problem using pyomo

Ist it possible to formulate a min-max-optimization problem of the following form in pyomo:
min(max(g_m(x)) s.t. L
where g_m are nonlinear functions (actually constrains of another model) and L is a set of linear constrains?
How would I create the expression for the objective function of the model?
The problem is that using max() on a list of constraint-objects returns only the constraint possessesing the maximum value at a given point.
I think yes, but unless you find a clever way to reformulate your model, it might not be very efficent.
You could solve all possiblity of max(g_m(x)), then select the solution with the lowest objective function value.
I fear that the max operation is not something you can add to a minimization model, since it is not a mathematical operation, but a solver operation. This operation is on the problems level. Keep in mind that when solving a model, Pyomo requires as argument only one sense of optimization (min or max), thus making it unable to understand min-max sense. Even if it did, how could it knows what to maximize or minimize? This is why I suggest you to break your problem in two, unless you work on its formulation.

Are shadow prices valid after an infeasible solve from COIN using PULP

I am solving a minimization linear program using COIN-OR's CLP solver with PULP in Python.
The variables that are included in the problem are a subset of the total number of possible variables and sometimes my pricing heuristic will pick a subset of variables that result in an infeasible solution. After which I use shadow prices to price new variables in.
My question is, if the problem is infeasible, I still get values from calling prob.constraints[c].pi, but those values don't always seem to be "valid" or "good" per se.
Now, a solver like Gurobi won't even let me call the shadow prices after an infeasible solve.
Actually Stu, this might work! - the "dummy var" in my case could be the source/sink node, which I can loosen the flow constraints on, allowing infinite flow in/out but with a large cost. This makes the solution feasible with a very bad high optimal cost; then the pricing of the new variables should work and show me which variables to add to the problem on the next iteration. I'll give it a try and report back. My only concern is that the bigM cost coefficient on the source/sink node may skew the pricing of the variables making all of them look relatively attractive. This would be counter productive bc adding most of the variables back into the problem will defeat the purpose of my column generation in the first place. I'll test it...

Categories

Resources