问题
I have a large problem defined in CVXPY modelling language. I want to solve series of this problems - still the same format but with different parameters (constants).
I found out that after calling problem.solve()
internal problem generating takes 20 s and main optimization runtime takes 0.2 s. It's a lot of time when I want to solve dozens of similar problems.
Is there any tool for CVXPY like YALMIP optimizer or any possibility to reduce problem generating time?
回答1:
Yes there is. And it's even explained in the official docs.
Parameters
Parameters are symbolic representations of constants. The purpose of parameters is to change the value of a constant in a problem without reconstructing the entire problem.
Example straight from the docs (modified):
from cvxpy import *
import numpy
# Problem data.
n = 15
m = 10
numpy.random.seed(1)
A = numpy.random.randn(n, m)
b = numpy.random.randn(n, 1)
# gamma must be positive due to DCP rules.
gamma = Parameter(sign="positive") # !!!
# Construct the problem.
x = Variable(m)
error = sum_squares(A*x - b)
obj = Minimize(error + gamma*norm(x, 1))
prob = Problem(obj) # !!!
# Construct a trade-off curve of ||Ax-b||^2 vs. ||x||_1
sq_penalty = []
l1_penalty = []
x_values = []
gamma_vals = numpy.logspace(-4, 6)
for val in gamma_vals:
gamma.value = val # !!!
prob.solve() # !!!
# Use expr.value to get the numerical value of
# an expression in the problem.
sq_penalty.append(error.value)
l1_penalty.append(norm(x, 1).value)
x_values.append(x.value)
So what does it do
As you noticed, the setup of your optimization-problem might take some time, because it's following the DCP-approach (which proves convexity by construction).
Using parameter
, this DCP-processing is only done one time! Every new solve willl only change some small parts within the problem. It's important to describe your parameter as precise as possible, so that DCP can work. Example: Parameter(sign="positive")
.
Is there more you can do
Maybe. Depending on the solver, you can also use warm-starting, if you think a special guess (e.g. solution-vector of your last iteration) is a good start for the new problem.
This would replace: prob.solve()
with prob.solve(warm_start=True)
, resulting in reusing the previous solution as a start (explained here). Manually defining this vector does not seem to be possible (from cvxpy).
Sadly, the only solver supporting this (within cvxpy) is SCS as far as i know (and others will ignore it without crashing)!
来源:https://stackoverflow.com/questions/44263875/cvxpy-how-to-efficiently-solve-a-series-of-similar-problems