what is the way to add max_solutions and max_seconds parameters to Python MIP Optimization model? - python-3.x

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.

Related

How to get all solutions which causes to optimal result in Gurobi

I have an implementation in Gurobi in python. My problem has different choices of selecting parameters to reach the optimal result. Now I need all solutions which reach the optimal value of result. How can I get them ? I know the blow code which just returns one solution.
if m.status == GRB.Status.OPTIMAL:
for v in m.getVars():
print (v.varname, v.x)
This can be achieved using the SolutionPool. You can specify how many solutions you want Gurobi to return.

Ortools setting constraints while solving

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?

PySCIPOpt/SCIP - Branching/Separation with fractional variable

I began using PySCIPOpt/SCIP for a Coursera course on discrete optimization. I'd need to implement a simple separation from a fractional variable and wonder how to do it. Online SCIP literature does not provide relevant example.
Any Python example for me to get inspired for my assignment?
Thank you for the answer. Indeed I spent some hours reading SCIP documentation and I have trouble interfacing SCIp methods in Python.
I have been able to implement in Python a simple constraint handler to add first-type cuts and I'd like to add a separator to add second-type cuts.
The latter cuts are typically x = 0 or 1 cuts based on fractional x values and I stumble more with syntax - addCut() - and using generic methods than the process itself.
A Python example, a bit more involved than tsp.py, would greatly help me.
Your question is quite broad. I try to give some hints on where to look for an answer:
general information on separators in SCIP
difference between constraint handlers and separators
Python example on a separator implemented as constraint handler to solve the Traveling Salesman Problem
I can try to answer your question more precisely, if you explain your application/problem in more detail.

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,

Resources