I have an optimization problem. all of my other constraints are linear but I have a constraint that is like this:
in this equation, s and r and k are constants that I have the values and a and s are unknown parameters.
actually, the objective function is:
and it has some other linear constraints.
I'm searching for a python package that can solve this problem and can make that constraint that I mentioned above as a parameter for the optimization problem.
I first searched for linear programming solutions but when I tried to make that constraint in pulp I got this error:
TypeError: Non-constant expressions cannot be multiplied
This is possible with PySCIPOpt:
from pyscipopt import Model
model = Model()
x = model.addVar("x")
y = model.addVar("y")
z = model.addVar("z")
model.setObjective(c)
model.addCons(x / (y*z) >= 0)
model.optimize()
You can formulate any polynomial expression in this way.
Related
I cannot figure out how to solve this separable differential equation using sympy. Help would be greatly appreciated.
y′=(y−4)(y−2),y(0)=5
Here was my attempt, thanks in advance!!!
import sympy as sp
x,y,t = sp.symbols('x,y,t')
y_ = sp.Function('y_')(x)
diff_eq = sp.Eq(sp.Derivative(y_,x), (y-4)*(y-2))
ics = {y_.subs(x,0):5}
sp.dsolve(diff_eq, y_, ics = ics)
the output is y(x) = xy^2 -6xy +8x + 5
The primary error is the introduction of y_. This makes the variable y a constant parameter of the ODE and you get the wrong solution.
If you correct this you get an error of "too many solutions for the integration constant". This is a bug caused by not simplifying the integration constant after it first occurs. So multiplication and addition of constants should just be absorbed, an additive constant in an exponent should become a multiplicative factor for the exponential. As it is, exp(2*C_1)==3 has two solutions if C_1 is considered as an angle (it's a bit of tortured logic from computing roots in the complex plane).
The newer versions can actually solve this fully if you give the third hint in the classification list 'separable', '1st_exact', '1st_rational_riccati', ... that does something different than partial fraction decomposition of the first two
from sympy import *
x = Symbol('x')
y = Function('y')(x)
dsolve(Eq(y.diff(x), (y-2)*(y-4)),y,
ics={y.subs(x,0):5},
hint='1st_rational_riccati')
returning
\displaystyle y{\left(x \right)} = \frac{2 \cdot \left(6 - e^{2 x}\right)}{3 - e^{2 x}}
It's not entirely lasso because I add an extra constraint but I'm not sure how I'm supposed to solve a problem like the following using cvxpy
import cvxpy as cp
import numpy as np
A = np.random.rand(5000,1000)
v0 = np.random.rand(1000,1)
v = cp.Variable(v0.shape)
iota = np.ones(v0.shape)
lam = 1
objective = cp.Minimize( (A#(v-v0)).T#(A#(v-v0)) + lam * cp.abs(v).T # iota )
constraints = [v >= 0]
prob = cp.Problem(objective, constraints)
res = prob.solve()
I tried various versions of this but this is the one that most clearly shows what I'm trying to do. I get the error:
DCPError: Problem does not follow DCP rules. Specifically: The objective is not DCP. Its following subexpressions are not: ....
And then an error I don't undeerstand haha.
CVXPY is a modeling language for convex optimization. Therefore, there is a set of rules your problem must follow to ensure your problem is convex indeed. These are what cvxpy refers to DCP: Disciplined Convex Programming. As the error suggests, your objective is not DCP.
To be more precise, the problem is in the objective (A#(v-v0)).T#(A#(v-v0)): cvxpy don't know it is indeed convex (from program point of view, it's just few multiplications).
To ensure your problem is DCP, it's best to use cvxpy atomic functions.
Essentially you are modeling x^T * x (if x=A#(v-v0)), which is the squares of norm 2 of a vector. cp.norm2 is the way to ensure cvxpy will know the problem is convex.
change the line of the objective function to:
objective = cp.Minimize(cp.norm2(A # (v - v0)) ** 2 + lam * cp.abs(v).T # iota)
and it works.
(Also take a look at cvxpy example of lasso regression)
The problem being solved is finding the truss with the least weight, exactly done as on this website: https://www.layopt.com/truss/. This method is also called the ground structure method. I am aiming to add some functionallity to the method through an MILP optimization. Initially, I started with the cvxpy Linear Programming (LP) solver but since it can't solve MILP I am now using the IBM ILOG CPLEX solver with the python module docplex. Unfortunately I am bumping into an problem, but first in short how the optimization works is:
Initialize: Make nodes, place a load (f) and supports (dof)
Make the potential members of the truss, with full connectivity all the nodes will be connected with each other. These potential members will form the truss and have the two variables a and q and the constant length property l.
Calculate the equilibrium matrix B, which is guaranteed sparce and symmetric.
Build the LP-model, which is done via calling the Model() object and start solving it.
..
"build the model"
model = Model()
a = model.continuous_var_list(len(members), name='a', lb=0, ub=1)
q = []
Bcons = []
for k, fk in enumerate(f):
qk = model.continuous_var_list(len(members), name=f'q{k}', lb=-10 ** 10, ub=10 ** 10)
Bconsk = model.add_constraints(
sum(B[i, j] * qk[j] for j in range(len(qk))) == fk[i] for i in range(len(dof)) if dof[i] != 0)
model.add_constraints(qk[i] <= sigma * a[i] for i in range(len(qk)))
model.add_constraints(qk[i] >= -sigma * a[i] for i in range(len(qk)))
q.append(qk)
Bcons.append(Bconsk)
model.set_objective('min', sum(a[i] * l[i] for i in range(len(a))))
model.print_information()
"solve model and update results"
sol = model.solve()
print(model.solve_details)
For small problem sizes (less than 1000 members) the LP converges in the CPLEX solver and works perfectly. However for larger problem sizes (e.g. more than 10 000 members) the problem is 'optimal with unscaled infeasibilities'. What does this mean and how can I solve this larger LP?
What I tried so far:
Solving the same problem in cvxpy. This module can solve up to 120 000 members without any problems.. So I actually would expect that the professional solver can also do this.
Found Coping with an Ill-Conditioned Problem or Handling Unscaled Infeasibilities, but I cant find any scaling parameters in the module docplex
..
Results:
Nodes: 231 Members: 16290
Model: docplex_model1
- number of variables: 32580
- binary=0, integer=0, continuous=32580
- number of constraints: 33038
- linear=33038
- parameters: defaults
- objective: minimize
- problem type is: LP
status = optimal with unscaled infeasibilities
time = 131.297 s.
problem = LP
The agressive scaling mdl.parameters.read.scale = 1 works as commented by #Philippe Couronne
I do not know how to set up and solve the following linear optimization problem in Python. Can you help?
R and Beta are vectors of length n with known constants.
x is a vector of length n but is unknown - to be optimized.
constraints:
`B * x = 200 cross product (elementwise product then sum)
x(i)>0
find optimal values in vector x such that we maximize:
max(R * x)
It seems to be not a very complicated, but I did not succeed setting up the problem in the scipy library. Any help is appreciated.
That looks like a linear programming problem, take a look into the scipy library to solve that.
I am trying to solve quadratic programming problem using IBM's Cplex Python API. The problem has non-linear constraints. Does Cplex accept non-linear constraint for quadratic programming? More specifically, given unknowns [x1,x2,x3,x4,x5], I need to put in two constraints
Constraint A (x2+x3) / (1-x1) = z1
Constraint B (x4+x5) / (1-x1) = z2
Where z1 and z2 are known numbers.
Cplex does have instructions on how to enter quadratic constraints, but none that I can find on entering non-linear constraints in general.
could
from docplex.mp.model import Model
mdl = Model(name='example')
z1=2;
z2=3;
mdl.x1 = mdl.continuous_var(0,10,name='x1')
mdl.x2 = mdl.continuous_var(0,10,name='x2')
mdl.x3 = mdl.continuous_var(0,10,name='x3')
mdl.x4 = mdl.continuous_var(0,10,name='x4')
mdl.x5 = mdl.continuous_var(0,10,name='x5')
mdl.add_constraint(mdl.x2+mdl.x3==z1*(1-mdl.x1), 'A')
mdl.add_constraint(mdl.x4+mdl.x5==z2*(1-mdl.x1), 'B')
mdl.solve()
print(mdl.x1.solution_value);
print(mdl.x2.solution_value);
print(mdl.x3.solution_value);
print(mdl.x4.solution_value);
print(mdl.x5.solution_value);
help ?