问题
Problem
类是确定和解决优化问题的入口点。
每个 Problem
实例封装一个优化问题,即目标和一组约束条件。
solve()
方法要么解决实例所编码的问题,
返回最优值并将变量值设置为最优点,要么报告问题实际上是不可行的或无界的。
您可以这样构建一个问题,解决它,然后检查其值以及变量的值:
problem = Problem(Minimize(expression), constraints)
problem.solve()
if problem.status not in ["infeasible", "unbounded"]:
# Otherwise, problem.value is inf or -inf, respectively.
print("Optimal value: %s" % problem.value)
for variable in problem.variables():
print("Variable %s: value %s" % (variable.name(), variable.value))
问题是 不可变的 ,除了通过指定
Parameter
值来进行的。这意味着
创建问题后,*不能*修改问题的目标或约束条件。如果您想要向现有问题添加约束条件,
您应该使用以下习语创建一个新问题:
problem = Problem(Minimize(expression), constraints)
problem = Problem(problem.objective, problem.constraints + new_constraints)
除了如何实例化它、如何解决问题实例 solve()
,
以及如何查询求解器的结果( status
和
value
),大多数用户不需要了解有关
Problem
类的任何信息。
关于问题实例的大小以及关于最近的求解调用的统计信息,
分别由 SizeMetrics
和
SolverStats
类捕获,并可以通过
Problem
类的
size_metrics()
和
solver_stats()
属性来访问。
最小化
- class cvxpy.Minimize(expr)[source]
An optimization objective for minimization.
- Parameters:
expr (Expression) – The expression to minimize. Must be a scalar.
- Raises:
ValueError – If expr is not a scalar.
最大化
- class cvxpy.Maximize(expr)[source]
An optimization objective for maximization.
- Parameters:
expr (Expression) – The expression to maximize. Must be a scalar.
- Raises:
ValueError – If expr is not a scalar.
问题
- class cvxpy.Problem(objective: Minimize | Maximize, constraints: List[Constraint] | None = None)[source]
A convex optimization problem.
Problems are immutable, save for modification through the specification of
Parameter
- Parameters:
- atoms() List[Atom] [source]
Accessor method for atoms.
- Returns:
A list of the atom types in the problem; note that this list contains classes, not instances.
- Return type:
list of
Atom
- backward() None [source]
Compute the gradient of a solution with respect to Parameters.
This method differentiates through the solution map of the problem, obtaining the gradient of a solution with respect to the Parameters. In other words, it calculates the sensitivities of the Parameters with respect to perturbations in the optimal Variable values. This can be useful for integrating CVXPY into automatic differentiation toolkits.
backward()
populates thegradient
attribute of each Parameter in the problem as a side-effect. It can only be called after callingsolve()
withrequires_grad=True
.Below is a simple example:
import cvxpy as cp import numpy as np p = cp.Parameter() x = cp.Variable() quadratic = cp.square(x - 2 * p) problem = cp.Problem(cp.Minimize(quadratic), [x >= 0]) p.value = 3.0 problem.solve(requires_grad=True, eps=1e-10) # backward() populates the gradient attribute of the parameters problem.backward() # Because x* = 2 * p, dx*/dp = 2 np.testing.assert_allclose(p.gradient, 2.0)
In the above example, the gradient could easily be computed by hand. The
backward()
is useful because for almost all problems, the gradient cannot be computed analytically.This method can be used to differentiate through any DCP or DGP problem, as long as the problem is DPP compliant (i.e.,
problem.is_dcp(dpp=True)
orproblem.is_dgp(dpp=True)
evaluates toTrue
).This method uses the chain rule to evaluate the gradients of a scalar-valued function of the Variables with respect to the Parameters. For example, let x be a variable and p a Parameter; x and p might be scalars, vectors, or matrices. Let f be a scalar-valued function, with z = f(x). Then this method computes dz/dp = (dz/dx) (dx/p). dz/dx is chosen as the all-ones vector by default, corresponding to choosing f to be the sum function. You can specify a custom value for dz/dx by setting the
gradient
attribute on your variables. For example,import cvxpy as cp import numpy as np b = cp.Parameter() x = cp.Variable() quadratic = cp.square(x - 2 * b) problem = cp.Problem(cp.Minimize(quadratic), [x >= 0]) b.value = 3. problem.solve(requires_grad=True, eps=1e-10) x.gradient = 4. problem.backward() # dz/dp = dz/dx dx/dp = 4. * 2. == 8. np.testing.assert_allclose(b.gradient, 8.)
The
gradient
attribute on a variable can also be interpreted as a perturbation to its optimal value.- Raises:
ValueError – if solve was not called with
requires_grad=True
SolverError – if the problem is infeasible or unbounded
- constants() List[Constant] [source]
Accessor method for constants.
- Returns:
A list of the constants in the problem.
- Return type:
list of
Constant
- derivative() None [source]
Apply the derivative of the solution map to perturbations in the Parameters
This method applies the derivative of the solution map to perturbations in the Parameters to obtain perturbations in the optimal values of the Variables. In other words, it tells you how the optimal values of the Variables would be changed by small changes to the Parameters.
You can specify perturbations in a Parameter by setting its
delta
attribute (if unspecified, the perturbation defaults to 0).This method populates the
delta
attribute of the Variables as a side-effect.This method can only be called after calling
solve()
withrequires_grad=True
. It is compatible with both DCP and DGP problems (that are also DPP-compliant).Below is a simple example:
import cvxpy as cp import numpy as np p = cp.Parameter() x = cp.Variable() quadratic = cp.square(x - 2 * p) problem = cp.Problem(cp.Minimize(quadratic), [x >= 0]) p.value = 3.0 problem.solve(requires_grad=True, eps=1e-10) # derivative() populates the delta attribute of the variables p.delta = 1e-3 problem.derivative() # Because x* = 2 * p, dx*/dp = 2, so (dx*/dp)(p.delta) == 2e-3 np.testing.assert_allclose(x.delta, 2e-3)
- Raises:
ValueError – if solve was not called with
requires_grad=True
SolverError – if the problem is infeasible or unbounded
- get_problem_data(solver, gp: bool = False, enforce_dpp: bool = False, ignore_dpp: bool = False, verbose: bool = False, canon_backend: str | None = None, solver_opts: dict | None = None)[source]
Returns the problem data used in the call to the solver.
When a problem is solved, CVXPY creates a chain of reductions enclosed in a
SolvingChain
, and compiles it to some low-level representation that is compatible with the targeted solver. This method returns that low-level representation.For some solving chains, this low-level representation is a dictionary that contains exactly those arguments that were supplied to the solver; however, for other solving chains, the data is an intermediate representation that is compiled even further by the solver interfaces.
A solution to the equivalent low-level problem can be obtained via the data by invoking the solve_via_data method of the returned solving chain, a thin wrapper around the code external to CVXPY that further processes and solves the problem. Invoke the unpack_results method to recover a solution to the original problem.
For example:
objective = ... constraints = ... problem = cp.Problem(objective, constraints) data, chain, inverse_data = problem.get_problem_data(cp.SCS) # calls SCS using `data` soln = chain.solve_via_data(problem, data) # unpacks the solution returned by SCS into `problem` problem.unpack_results(soln, chain, inverse_data)
Alternatively, the data dictionary returned by this method contains enough information to bypass CVXPY and call the solver directly.
For example:
problem = cp.Problem(objective, constraints) data, _, _ = problem.get_problem_data(cp.SCS) import scs probdata = { 'A': data['A'], 'b': data['b'], 'c': data['c'], } cone_dims = data['dims'] cones = { "f": cone_dims.zero, "l": cone_dims.nonneg, "q": cone_dims.soc, "ep": cone_dims.exp, "s": cone_dims.psd, } soln = scs.solve(data, cones)
The structure of the data dict that CVXPY returns depends on the solver. For details, consult the solver interfaces in cvxpy/reductions/solvers.
- Parameters:
solver (str) – The solver the problem data is for.
gp (bool, optional) – If True, then parses the problem as a disciplined geometric program instead of a disciplined convex program.
enforce_dpp (bool, optional) – When True, a DPPError will be thrown when trying to parse a non-DPP problem (instead of just a warning). Defaults to False.
ignore_dpp (bool, optional) – When True, DPP problems will be treated as non-DPP, which may speed up compilation. Defaults to False.
canon_backend (str, optional) – ‘CPP’ (default) | ‘SCIPY’ Specifies which backend to use for canonicalization, which can affect compilation time. Defaults to None, i.e., selecting the default backend.
verbose (bool, optional) – If True, print verbose output related to problem compilation.
solver_opts (dict, optional) – A dict of options that will be passed to the specific solver. In general, these options will override any default settings imposed by cvxpy.
- Returns:
dict or object – lowest level representation of problem
SolvingChain – The solving chain that created the data.
list – The inverse data generated by the chain.
- Raises:
cvxpy.error.DPPError – Raised if DPP settings are invalid.
- is_dcp(dpp: bool = False) bool [source]
Does the problem satisfy DCP rules?
- Parameters:
dpp (bool, optional) –
If True, enforce the disciplined parametrized programming (DPP) ruleset; only relevant when the problem involves Parameters. DPP is a mild restriction of DCP. When a problem involving Parameters is DPP, subsequent solves can be much faster than the first one. For more information, consult the documentation at
https://www.cvxpy.org/tutorial/advanced/index.html#disciplined-parametrized-programming
- Returns:
True if the Expression is DCP, False otherwise.
- Return type:
bool
- is_dgp(dpp: bool = False) bool [source]
Does the problem satisfy DGP rules?
- Parameters:
dpp (bool, optional) –
If True, enforce the disciplined parametrized programming (DPP) ruleset; only relevant when the problem involves Parameters. DPP is a mild restriction of DGP. When a problem involving Parameters is DPP, subsequent solves can be much faster than the first one. For more information, consult the documentation at
https://www.cvxpy.org/tutorial/advanced/index.html#disciplined-parametrized-programming
- Returns:
True if the Expression is DGP, False otherwise.
- Return type:
bool
- is_dpp(context: str = 'dcp') bool [source]
Does the problem satisfy DPP rules?
DPP is a mild restriction of DGP. When a problem involving Parameters is DPP, subsequent solves can be much faster than the first one. For more information, consult the documentation at
https://www.cvxpy.org/tutorial/advanced/index.html#disciplined-parametrized-programming
- Parameters:
context (str) – Whether to check DPP-compliance for DCP or DGP;
context
should be either'dcp'
or'dgp'
. Callingproblem.is_dpp('dcp')
is equivalent toproblem.is_dcp(dpp=True)
, and problem.is_dpp(‘dgp’)` is equivalent to problem.is_dgp(dpp=True).- Returns:
Whether the problem satisfies the DPP rules.
- Return type:
bool
- parameters()[source]
Accessor method for parameters.
- Returns:
A list of the parameters in the problem.
- Return type:
list of
Parameter
- classmethod register_solve(name: str, func) None [source]
Adds a solve method to the Problem class.
- Parameters:
name (str) – The keyword for the method.
func (function) – The function that executes the solve method. This function must take as its first argument the problem instance to solve.
- solve(*args, **kwargs)[source]
Compiles and solves the problem using the specified method.
Populates the
status
andvalue
attributes on the problem object as a side-effect.- Parameters:
solver (str, optional) – The solver to use. For example, ‘ECOS’, ‘SCS’, or ‘OSQP’.
verbose (bool, optional) – Overrides the default of hiding solver output, and prints logging information describing CVXPY’s compilation process.
gp (bool, optional) – If True, parses the problem as a disciplined geometric program instead of a disciplined convex program.
qcp (bool, optional) – If True, parses the problem as a disciplined quasiconvex program instead of a disciplined convex program.
requires_grad (bool, optional) –
Makes it possible to compute gradients of a solution with respect to Parameters by calling
problem.backward()
after solving, or to compute perturbations to the variables given perturbations to Parameters by callingproblem.derivative()
.Gradients are only supported for DCP and DGP problems, not quasiconvex problems. When computing gradients (i.e., when this argument is True), the problem must satisfy the DPP rules.
enforce_dpp (bool, optional) – When True, a DPPError will be thrown when trying to solve a non-DPP problem (instead of just a warning). Only relevant for problems involving Parameters. Defaults to False.
ignore_dpp (bool, optional) – When True, DPP problems will be treated as non-DPP, which may speed up compilation. Defaults to False.
method (function, optional) – A custom solve method to use.
kwargs (keywords, optional) – Additional solver specific arguments. See Notes below.
Notes
CVXPY interfaces with a wide range of solvers; the algorithms used by these solvers have arguments relating to stopping criteria, and strategies to improve solution quality.
There is no one choice of arguments which is perfect for every problem. If you are not getting satisfactory results from a solver, you can try changing its arguments. The exact way this is done depends on the specific solver. Here are some examples:
prob.solve(solver='ECOS', abstol=1e-6) prob.solve(solver='OSQP', max_iter=10000). mydict = {"MSK_DPAR_INTPNT_CO_TOL_NEAR_REL": 10} prob.solve(solver='MOSEK', mosek_params=mydict).
You should refer to CVXPY’s web documentation for details on how to pass solver solver arguments, available at
https://www.cvxpy.org/tutorial/advanced/index.html#setting-solver-options
- Returns:
The optimal value for the problem, or a string indicating why the problem could not be solved.
- Return type:
float
- Raises:
cvxpy.error.DCPError – Raised if the problem is not DCP and gp is False.
cvxpy.error.DGPError – Raised if the problem is not DGP and gp is True.
cvxpy.error.DPPError – Raised if DPP settings are invalid.
cvxpy.error.SolverError – Raised if no suitable solver exists among the installed solvers, or if an unanticipated error is encountered.
- unpack_results(solution, chain: SolvingChain, inverse_data) None [source]
Updates the problem state given the solver results.
Updates problem.status, problem.value and value of primal and dual variables.
- Parameters:
solution (object) – The solution returned by applying the chain to the problem and invoking the solver on the resulting data.
chain (SolvingChain) – A solving chain that was used to solve the problem.
inverse_data (list) – The inverse data returned by applying the chain to the problem.
- Raises:
cvxpy.error.SolverError – If the solver failed
- variables() List[Variable] [source]
Accessor method for variables.
- Returns:
A list of the variables in the problem.
- Return type:
list of
Variable
- property compilation_time: float | None
The number of seconds it took to compile the problem the last time it was compiled.
- Type:
float
- property constraints: List[Constraint]
A shallow copy of the problem’s constraints.
Note that constraints cannot be reassigned, appended to, or otherwise modified after creation, except through parameters.
- property objective: Minimize | Maximize
The problem’s objective.
Note that the objective cannot be reassigned after creation, and modifying the objective after creation will result in undefined behavior.
- property size_metrics: SizeMetrics
Information about the problem’s size.
- Type:
- property solver_stats: SolverStats
Information returned by the solver.
- Type:
- property status: str
The status from the last time the problem was solved; one of optimal, infeasible, or unbounded (with or without suffix inaccurate).
- Type:
str
- property value
The value from the last time the problem was solved (or None if not solved).
- Type:
float
SizeMetrics(大小度量)
- class cvxpy.problems.problem.SizeMetrics(problem: Problem)[source]
Reports various metrics regarding the problem.
- num_scalar_variables
The number of scalar variables in the problem.
- Type:
integer
- num_scalar_data
The number of scalar constants and parameters in the problem. The number of constants used across all matrices, vectors, in the problem. Some constants are not apparent when the problem is constructed: for example, The sum_squares expression is a wrapper for a quad_over_lin expression with a constant 1 in the denominator.
- Type:
integer
- num_scalar_eq_constr
The number of scalar equality constraints in the problem.
- Type:
integer
- num_scalar_leq_constr
The number of scalar inequality constraints in the problem.
- Type:
integer
- max_data_dimension
The longest dimension of any data block constraint or parameter.
- Type:
integer
- max_big_small_squared
The maximum value of (big)(small)^2 over all data blocks of the problem, where (big) is the larger dimension and (small) is the smaller dimension for each data block.
- Type:
integer
SolverStats(求解器统计)
- class cvxpy.problems.problem.SolverStats(solver_name: str, solve_time: float | None = None, setup_time: float | None = None, num_iters: int | None = None, extra_stats: dict | None = None)[source]
Reports some of the miscellaneous information that is returned by the solver after solving but that is not captured directly by the Problem instance.
- solver_name
The name of the solver.
- Type:
str
- solve_time
The time (in seconds) it took for the solver to solve the problem.
- Type:
double
- setup_time
The time (in seconds) it took for the solver to setup the problem.
- Type:
double
- num_iters
The number of iterations the solver had to go through to find a solution.
- Type:
int
- extra_stats
Extra statistics specific to the solver; these statistics are typically returned directly from the solver, without modification by CVXPY. This object may be a dict, or a custom Python object.
- Type:
object
- extra_stats: dict | None = None
- classmethod from_dict(attr: dict, solver_name: str) SolverStats [source]
Construct a SolverStats object from a dictionary of attributes.
- Parameters:
attr (dict) – A dictionary of attributes returned by the solver.
solver_name (str) – The name of the solver.
- Returns:
A SolverStats object.
- Return type:
- num_iters: int | None = None
- setup_time: float | None = None
- solve_time: float | None = None
- solver_name: str