Ortools setting constraints while solving - modeling

I am using CP-SAT solver from ortools
https://developers.google.com/optimization/cp/cp_solver
I am executing the solver with a callback object
solver = cp_model.CpSolver()
solution_agg = SolutionCollector(data, self.variables, self.products, self.vehicles)
status = solver.SearchForAllSolutions(self.model, callback=solution_agg)
Solution agg is supposed to filter out all solutions that have some wrong assignments, I could not model these as linear inequalities.
What I know is that generated solutions can be converged faster and the "hits" on the verifier can be made less. If I can add constraints on-the-go inside the callback.
I tried to do this inside the callback, adding a constraint to look for solutions in lesser volume than minimum volume till now.
self.__model.Add(volume_expression <= min_found_yet)
This doesn't give error, but the number of times the verifier rejected a solution is still same.
Is it possible to form constraints while solving? If not in Ortools, then any other solver which provides?

Not directly. The solver is stateless and read the cp_model once at the start of the solve.
What you are describing seems just a minimization property. Why don't you just minimize volume_expression?

Related

what is the way to add max_solutions and max_seconds parameters to Python MIP Optimization model?

I am using python's MIP module for optimization. I have set up a model with few parameters. I would want to limit the number of solutions and add stop timer if I don't find any solution in given time. I have added these parameters as given below:
m = Model(name='opt', sense=MAXIMIZE, solver_name=CBC)
m.optimize(max_solutions=1, max_seconds= 300)
somehow none of them seem working to me. it does not even stop looking for a solution after given time and it returns 2 solution sometimes even if I want to limit it to 1. Is there something I am missing in syntax?
One more thing, Gurobi has an option to add multiple variable using add_Vars parameter. Is there anything similar available in MIP too?
Thanks.
Yeah I have been doing some tests myself (with the Python-MIP solver) and seen some similar issues. Apparently it's still quite new and many improvements have been implemented recently or are yet to be developed. I will post from what I've learned:
regarding max_seconds: There's been at least one (closed) issue on the official repo related to using max_seconds parameter and CBC.
regarding max_solutions: If you are using version 1.6.2 or before, here's an explanation for that: until 1.6.1, the m.optimize(max_solutions=1) wasn't setting the maximum solution parameter to CBC. In that case you should try with the following lines (or just update to current version):
m.max_solutions = 1
m.optimize()
If the former don't help for the max_seconds and max_solutions parameters, I guess you'd better post your question as an issue at the library's repo to get answers and support from the project contributors.
Adding multiple variables, similar to gurobipy's Model.addVars() method: Yes, you can do it as follows
p = {(i, j): m.add_var(var_type=CONTINUOUS, lb=0, name="p[%d,%d]" % (i, j))
for i in Set_i for j in Set_j}
In this example, we are adding a variable p_ij and specifying it's continuous
(vs. binary or integer), has lower bound 0, and the sets where the indexes run. Set_i and Set_j are Python lists. See the documentation here for a more detailed explanation on how to use it. Similarly, you can create indexed constraints using the add_constr method, similar to Gurobi's Model.AddConstrs() method.

Pyomo Optimization of minimum cost using binary variables

I have an optimization problem where I want to minimize for the total cost of a system, so I write an objective function that is the sum of my different costs. The problem includes using one of three machines each one with different cost at a different threshold of usage. I define each machine (model.Machine#) as a binary variable and declare the parameters of each machine cost model.Cost#). I am trying to get the cost to be able to minimize it but when I write the constraint:
model.Cost1*model.Machine1 + model.Cost2*model.Machine2 + model.Cost3*model.Machine3 == model.MachineCost
Where I also write:
model.Machine1 + model.Machine2 + model.Machine3 == 1
Gurobi is telling me that it can't handle an quadratic function referring to the first constraint mentioned above. However it is parameters multiplied by binary variables there isn't anything quadratic.
I know the question is vague and part of a larger problem but I hope you can understand what I am referring to and help me!
Thank you so much for your assistance!
What is model.MachineCost? Is it an Expression component with some kind of quadratic expression stored inside of it?
If not, can you start commenting out things in your model until you get down to a minimal working example (that causes this error) and post that? Otherwise, we can't be sure that there are not other quadratic pieces of the model that you are not showing.

Does Julia have a way to solve for unknown variables

Is there a function in Julia that is similar to the solver function in Excel where I can provide and equation, and it will solve for the unknown variable? If not, does anybody know the math behind Excel's solver function?
I am not expecting anybody to solve the equation, but if it helps:
Price = (Earnings_1/(1+r)^1)+(Earnings_2/(1+r)^2)++(Earnings_3/(1+r)^3)+(Earnings_4/(1+r)^4)+(Earnings_5/(1+r)^5)+(((Earnings_5)(RiskFreeRate))/((1+r)^5)(1-RiskFreeRate))
The known variables are: Price, All Earnings, and RiskFreeRate. I am just trying to figure out how to solve for r.
Write this instead as an expression f(r) = 0 by subtracting Price over to the other side. Now it's a rootfinding problem. If you only have one variable you're solving for (looks to be the case), then Roots.jl is a good choice.
fzero(f, a::Real, b::Real)
will search for a solution between a and b for example, and the docs have more choices for algorithms when you don't know a range to start with and only give an initial condition for example.
In addition, KINSOL in Sundials.jl is good when you know you're starting close to a multidimensional root. For multidimensional and needing some robustness to the initial condition, I'd recommend using NLsolve.jl.
There's nothing out of the box no. Root finding is a science in itself.
Luckily for you, your function has an analytic first derivative with respect to r. That means that you can use Newton Raphson, which will be extremely stable for your function.
I'm sure you're aware your function behaves badly around r = -1.

Force Gurobi MIP solve to be deterministic

I am passing a MIP problem to Gurobi using PULP, with no special params other than gap 0.1 and it looks like the solution path is different every solve. I tried to set a seed, and use that same seed for each run, and that did not help. It still took a different journey. I know it's taking a dif path, because I am doing row generation (getting a solution, checking if a constraint is broken, adding if so) and its finding a feasible optimal one run without needing, for example, constraint x - but then the very next run with the exact same input, it breaks constraint x and requires it be added as a row.
To those who think it may be due to the gap of 0.1, maybe so, but CBC solves the same way with the same gap and does not exhibit this behavior.
Any ideas? Thanks,

excel solver (Simplex LP) binary constraints

I am solving an optimization problem. the problem has binary constraints. solver is (during iteration) setting those binary constraints to decimals between 0 and 1 (approximating a relaxed gradient search). I wish to indicate to solver that it should just search over the discontinous values for 0..1.
Is there a way to do this?
Alternatively, is there an algorithm in OpenSolver which does this, that mimics the simplex-lp, and provides a global optimum?
the cheap way to do it, is to right a for-loop, and iterate over the values. I was wondering if there was a way to phrase it so that a nonlinear problem, becomes a linear problem.
Thanks.
The GRG Nonlinear and Simplex LP methods both use the Branch & Bound method when faced with integer constraints. This method "relaxes" the integer requirement first, finds a solution, then fixes one of the constraints to an integer and finds a new solution. See the Solver on-line documentation.
It is a brute force search method and can take a considerable amount of time.
The Evolutionary method uses it's own algorithm for dealing with integer constraints and is typically much faster than the other two methods.
You ask about linearizing a non-linear problem - you would need to provide more specific information in order to answer that (e.g. What is your equation? How have you set up your solver problem? etc.)

Resources