How to remove constraint in ORTools - python

Is there any way to remove defined constraint from solver with out clearing solver and creating constraints from first?
suppose my problem is to maximize sum of 3 variables which two constraints
constraint1: variable 2 should be between 8 - 10
constraint2: variable 3 should be between 5 - 10
from ortools.linear_solver import pywraplp
solver = pywraplp.Solver('SolveIntegerProblem',
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
objective = solver.Objective()
Variable[0] = solver.IntVar(0, 5, variable 0 )
Variable[1] = solver.IntVar(0, 10, variable 1 )
Variable[2] = solver.IntVar(0, 20, variable 2 )
objective.SetCoefficient(Variable[0], 1)
objective.SetCoefficient(Variable[1], 1)
objective.SetCoefficient(Variable[2], 1)
objective.SetMaximization()
constraints.append(solver.Constraint(8,10))
constraints[0].SetCoefficient(variable[1],1)
constraints.append(solver.Constraint(5,10))
constraints[1].SetCoefficient(variable[2],1)
Now in the second time of running my code I want to remove constraint number 2, but I can not find any operation to do it and the only way is to clear solver and define constraint from first.
In this semi code the number of constraints were limited but actually, in my real code the number of constraint are many and I can not define them from first.

I know this question is quite old but:
As far as I know, or-tools does not provide any interface that removes constraints or variables. From an engineering perspective, messing with the internal logic to remove them 'by hand' is dangerous.
I absolutely needed that feature for my tech stack and tried multiple python linear programming librairies out there (wrappers around clp/cbc really) and I settle on or-tools despite that flaw for 2 main reasons 1) this was the only librairy with the minimal features support I required out of the box and 2) at the time (~4-5 years ago) it was the only librairy using C bindings.
All others used one form of another of interfacing with the cbc command line which is a ... horrible way to interface with python. It is unscalable due to the overhead of writing and reading files on disk. Nasty nasty nasty. So if I remember correctly, only pylp and or-tools had c bindings and again if I remember correctly, pylp was NOT python 3 compatible (and has been in limbo ever since) so I settled on or-tools.
So to answer your question: to 'remove' variables or constraints with or-tools, I had to build my own python wrapper around or-tools. To deactivate a variable or a constraint, I would set coefficients to zero and free bounds (set to +/- infinity) and set costs to zero to effectively deactivate the constraint. In my wrapper, I would keep a list of deactivated constraints/variables and recycle them instead of creating new ones (which was proven to lead to both increased runtimes and memory leaks because C++ + python is a nightmare in those areas). I heavily suspect that I get floating points noise in the recycling but it's stable enough in practice for my needs.
So in your code example, to rerun without creating an new model from scratch you need to do:
(...)
constr1 = solver.Constraint(8,10)
constraints.append(constr1)
constraints[0].SetCoefficient(variable[1],1)
constr2 = solver.Constraint(5,10)
constraints.append(constr2)
constraints[1].SetCoefficient(variable[2],1)
constr2.SetBounds(-solver.infinity(), solver.infinity())
constr2.SetCoefficient(variable[2], 0)
# constr2 is now deactivated. If you wanted to add a new constraints, you can
# change the bounds on constr2 to recycle it and add new variables
# coefficients
That being said, very recently, python-mip was released and it supports both removing variables and constraints and has c-bindings.

Did you try to use the MPConstraint::Clear() method ?
Declaration: https://github.com/google/or-tools/blob/9487eb85f4620f93abfed64899371be88d65c6ec/ortools/linear_solver/linear_solver.h#L865
Definition: https://github.com/google/or-tools/blob/9487eb85f4620f93abfed64899371be88d65c6ec/ortools/linear_solver/linear_solver.cc#L101
Concerning Python swig wrapper MPConstraint is exported as Constraint object.
src: https://github.com/google/or-tools/blob/9487eb85f4620f93abfed64899371be88d65c6ec/ortools/linear_solver/python/linear_solver.i#L180
But the method Constraint::Clear() seems not exposed
https://github.com/google/or-tools/blob/9487eb85f4620f93abfed64899371be88d65c6ec/ortools/linear_solver/python/linear_solver.i#L270
You can try to patch the swig file and recompile make python && make install_python

Related

Ax.dev does not do anything with search space constraints?

I found some articles online that mentioned Ax.dev's capability to cope with a constrained search space (e.g. dimension_x + dimension_y <= bound). However, I only experienced Ax.dev to ignore/violate all constraints. I have tried some different constraints on the Hartmann6d example. I assume Ax.dev models the constraints as soft constraints (not sure though, might as well be my coding skills...). So, my first question is: does Ax.dev SearchSpace use parameter_constraints as soft or hard constraint(s).
My second problem:
from ax import *
number of parameters
...
c0 = SumConstraint(parameters=[ some parameters ], bound= some boundary)
c1...
space = SearchSpace(parameters=[ parameters ], parameter_constraints=[c0, c1])
exp = SimpleExperiment(
name='EXPERIMENT5',
search_space=space,
evaluation_function=black_box_function,
objective_name='BLABLA',
minimize=False,
)
sobol = Models.SOBOL(exp.search_space)
for i in range(10):
exp.new_trial(generator_run=sobol.gen(1))
exp.trials[len(exp.trials) - 1].run()
returns
SearchSpaceExhausted: Rejection sampling error (specified maximum draws (100000) exhausted, without finding sufficiently many (1) candidates). This likely means that there are no new points left in the search space.
I have not been able to find useful information concerning this, despite all promising articles online stating ax.dev benefits (such as a constrained parameter space!) :(
meta-comment: Probably a better place for GitHub issues (not much by way of Ax help/docs on stackoverflow to my knowledge, but their GitHub issues is rich and generally has a lot of developer/community support).
Does Ax.dev SearchSpace use parameter_constraints as soft or hard constraint(s)?
I think parameter constraints are hard constraints (pretty sure that's the case at least for Sobol sampling, but I'm not sure about Bayesian models).
Outcome constraints are soft penalties (constraints)
SearchSpaceExhausted: Rejection sampling error
Search: https://github.com/facebook/Ax/issues?q=is%3Aissue+sort%3Aupdated-desc+specified+maximum+draws+is%3Aclosed
--> https://github.com/facebook/Ax/issues/694
--> https://github.com/facebook/Ax/issues/694#issuecomment-987353936
Since it's on master, first I install the latest version in a conda environment:
pip install 'git+https://github.com/facebook/Ax.git#egg=ax-platform'
The relevant imports are:
from ax.modelbridge.generation_strategy import GenerationStrategy, GenerationStep
from ax.modelbridge.registry import Models
Then based on 1A. Manually configured generation strategy, I change the first GenerationStep model_kwargs from:
model_kwargs={"seed": 999}
to
model_kwargs={
"seed": 999,
"fallback_to_sample_polytope": True,
}
With the full generation strategy (gs) given by:
gs = GenerationStrategy(
steps=[
# 1. Initialization step (does not require pre-existing data and is well-suited for
# initial sampling of the search space)
GenerationStep(
model=Models.SOBOL,
num_trials=5, # How many trials should be produced from this generation step
min_trials_observed=3, # How many trials need to be completed to move to next model
max_parallelism=5, # Max parallelism for this step
model_kwargs={
"seed": 999,
"fallback_to_sample_polytope": True,
}, # Any kwargs you want passed into the model
model_gen_kwargs={}, # Any kwargs you want passed to `modelbridge.gen`
),
# 2. Bayesian optimization step (requires data obtained from previous phase and learns
# from all data available at the time of each new candidate generation call)
GenerationStep(
model=Models.GPEI,
num_trials=-1, # No limitation on how many trials should be produced from this step
max_parallelism=3, # Parallelism limit for this step, often lower than for Sobol
# More on parallelism vs. required samples in BayesOpt:
# https://ax.dev/docs/bayesopt.html#tradeoff-between-parallelism-and-total-number-of-trials
),
]
)
Finally, in the case of this issue, and as mentioned:
AxClient(generation_strategy=gs)
Or in the case of the Loop API:
optimize(..., generation_strategy=gs)
Seems to work well for my use-case; thank you! I'll try to update the other relevant issues soon.

Scipy minimize iterating past bounds

I am trying to minimize a function of 3 input variables using scipy. The function reads like so-
def myfunc(x):
x[0] = a
x[1] = b
x[2] = c
n = f(a,b,c)
return n
bound1 = (80,100)
bound2 = (10,20)
bound3 = (312,740)
guess = [a0,b0,c0]
bds = (bound1,bound2,bound3)
result = minimize(myfunc, guess,method='L-BFGS-B',bounds=bds)
The function I am trying to currently run reaches a minimum at a=100,b=10,c=740, which is at the end of the bounds.
The minimize function keeps trying to iterate past the end of bound 3 (gets to c0 value of 740.0000000149012 on its last iteration.
Is there any way to stop this from happening? i.e. stop the iteration at the actual end of my bound?
This happens due to numerical-differentiation, which itself is not only needed to infer the step-direction and size, but also to reason about termination.
In general you can't do much without being very careful in regards to whatever solver (and there are many backend-solvers) being used. The basic idea is to replace the automatic numerical-differentiation with one provided by you: this one then respects those bounds and must be careful about the solvers-internals, e.g. "how to reason about termination at this end".
Fix A:
Your problem should vanish automatically when using: Pull-request #10673, which touches your configuration: L-BFGS-B.
It seems, this PR is not part of the current release SciPy 1.4.1 (as this was 2 months before the PR).
See also #6026, where a milestone of 1.5.0 is mentioned in regards to some changes including respecting bounds in num-diff.
For above PR, you will need to install scipy from the sources, which is:
quite doable on linux (and maybe os x)
not something you should try on windows!
trust me...
See the documentation if needed.
Fix B:
Apart from that, as you are doing unconstrained-optimization (with variable-bounds) where more solver-backends are available (compared to constrained-optimization), you might try another solver, trust-constr, which has explicit support for this, see #9098.
Be careful to recognize, that you need to signal this explicitly when setting up the bounds!

Problem of C++ compilation with Expression()

I am a beginner in fenics and I am trying to resolve Poisson equation with a boundary condition which is a Perlin noise generated by opensimplex, a Python library.
I'm trying to define f, the boundary condition by Expression().
I tried Expression('function(x[0],x[1],x[2])') where function (x,y,z)=opensimplex.tmp.noise3d(x,y,z)). However, as this opensimplex function is not managed by C++, I got a compilation error; Compilation failed!.
Is there any solution to overcome this error ?
I had a similar problem when starting to work with transient flows in FEniCS.
Defining a subclass for UserExpression, before defining your variational form should enable the compilation.
from dolfin import *
parameters["reorder_dofs_serial"] = True
### (Here you add your domain generation and FunctionSpace definition)
class Expression(SubDomain):
def inside(self,a,on_boundary):
return (x[0]) and (x[1]) and (x[2]) and on_boundary
f=MyExpression(2.0)
print(assemble(f*dx(domain=UnitIntervalMesh(1))))
If this still doesn't enable compilation, please attach the relevant portions of your code, and we can try to work through them.
If you have a fixed dimension order (e.g. 2-D), you might also have to add this after reordering dofs:
parameters["form_compiler"]["quadrature_degree"]=2
Good luck!

What is the alternative of tf.Variable.ref() in Tensorflow version 0.12?

I'm trying to run open code of A3C reinforcement learning algorithm to learn A3C in A3C code
However,I got several errors and I could fix except one.
In the code, ref() which is a member function of tf.Variable is used (1,2), but in recent tensorflow version 0.12rc, that function seems to be deprecated.
So I don't know what is the best way to replace it (I don't understand exactly why the author used ref()). When I just changed it to the variable itself (for example v.ref() to v), there was no error, but reward is not changed. It seems it cannot learn and I guess it is because the variables are not properly updated.
Please advise me what is the proper way to modify the code to work.
The new method tf.Variable.read_value() is the replacement for tf.Variable.ref() in TensorFlow 0.12 and later.
The use case for this method is slightly tricky to explain, and is motivated by some caching behavior that causes multiple uses of a remote variable on a different device to use a cached value. Let's say you have the following code:
with tf.device("/cpu:0")
v = tf.Variable([[1.]])
with tf.device("/gpu:0")
# The value of `v` will be captured at this point and cached until `m2`
# is computed.
m1 = tf.matmul(v, ...)
with tf.control_dependencies([m1])
# The assign happens (on the GPU) after `m1`, but before `m2` is computed.
assign_op = v.assign([[2.]])
with tf.control_dependencies([assign_op]):
with tf.device("/gpu:0"):
# The initially read value of `v` (i.e. [[1.]]) will be used here,
# even though `m2` is computed after the assign.
m2 = tf.matmul(v, ...)
sess.run(m2)
You can use tf.Variable.read_value() to force TensorFlow to read the variable again later, and it will be subject to whatever control dependencies are in place. So if you wanted to see the result of the assign when computing m2, you'd modify the last block of the program as follows:
with tf.control_dependencies([assign_op]):
with tf.device("/gpu:0"):
# The `read_value()` call will cause TensorFlow to transfer the
# new value of `v` from the CPU to the GPU before computing `m2`.
m2 = tf.matmul(v.read_value(), ...)
(Note that, currently, if all of the ops were on the same device, you wouldn't need to use read_value(), because TensorFlow doesn't make a copy of the variable when it is used as the input to an op on the same device. This can cause a lot of confusion—for example when you enqueue a variable to a queue!—and it's one of the reasons that we're working on enhancing the memory model for variables.)

Making a Qobj out of a picos variable

I need to write a semidefinite program that minimizes the trace of an operator, say R, subject to the constraint that tr_A(R)^{Tb} >>0 . That means that R represents a 3 qubit quantum system and the trace over the first system gives you an operator that represents the remaining 2 qubit systems. Taking the partial transpose with respect to one of the qubits, you get the partially transposed quantum state of the restricted 2 qubit system. It is this state that I want to make positive semidefinite.
I am using PICOS (to write the SDP) and qutip (to do the operations).
P = pic.Problem()
Rho = P.add_variable('Rho',(n,n),'hermitian')
P.add_constraint(pic.trace(Rho)==1)
P.add_constraint(Rho>>0)
RhoQOBJ = Qobj(Rho)
RhoABtr = ptrace(RhoQOBJ, [0,1])
RhoABqbj = partial_transpose(RhoABtr, [0], method='dense')
RhoAB = RhoABqbj.full()
Problem: I need to make Rho a Qobj, for qutip to be able to understand it, but Rho above is only an instance of the Variable class. Anyone has any idea on how to do this?
Also I looked here, http://picos.zib.de/tuto.html#variables , it became even more confusing as this function puts the instance in a dictionary and only gives you back a key.
You need to be able to output a numpy array or sparse matrix to convert to a Qobj. I could not find anything in the picos docs that discusses this option.
I am seeing this post very late, but maybe I can help... I am not sure what the function Qobj() is doing, can you please tell me more about it.
Otherwise, there is now a new partial_transpose() function in PICOS (version released today), which hopefully does what you need.
Best,
Guillaume.

Categories

Resources