You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/constraint.md
+38-5Lines changed: 38 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,6 +25,16 @@ from pyoptinterface import copt
25
25
model = copt.Model()
26
26
```
27
27
28
+
## Constraint Sense
29
+
30
+
The sense of a constraint can be one of the following:
31
+
32
+
-`poi.Eq`: equal
33
+
-`poi.Leq`: less than or equal
34
+
-`poi.Geq`: greater than or equal
35
+
36
+
They are the abbreviations of `poi.ConstraintSense.Equal`, `poi.ConstraintSense.LessEqual` or `poi.ConstraintSense.GreaterEqual` and can be used in the `sense` argument of the constraint creation functions.
37
+
28
38
## Linear Constraint
29
39
It is defined as:
30
40
@@ -42,16 +52,15 @@ It can be added to the model using the `add_linear_constraint` method of the `Mo
42
52
x = model.add_variable(name="x")
43
53
y = model.add_variable(name="y")
44
54
45
-
con = model.add_linear_constraint(2.0*x + 3.0*y, poi.ConstraintSense.LessEqual, 1.0)
55
+
con = model.add_linear_constraint(2.0*x + 3.0*y, poi.Leq, 1.0)
# modify the coefficient of the linear part of the constraint
236
246
model.set_normalized_coefficient(con, x, 2.0)
237
247
```
248
+
249
+
## Create constraint with comparison operator
250
+
251
+
In other modeling languages, we can create a constraint with a comparison operator, like:
252
+
253
+
```python
254
+
model.addConsr(x + y <=1)
255
+
```
256
+
257
+
This is quite convenient, so PyOptInterface now supports to create constraint with comparison operators `<=`, `==`, `>=` as a shortcut to create a linear or quadratic constraint.
258
+
259
+
```{code-cell}
260
+
model.add_linear_constraint(x + y <= 1)
261
+
model.add_linear_constraint(x <= y)
262
+
model.add_quadratic_constraint(x*x + y*y <= 1)
263
+
```
264
+
265
+
:::{note}
266
+
267
+
Creating constraint with comparison operator may cause performance issue especially the left-hand side and right-hand side of the constraint are complex expressions. PyOptInterface needs to create a new expression by subtracting the right-hand side from the left-hand side, which may be time-consuming.
268
+
269
+
If that becomes the bottleneck of performance, it is recommended to construct the left-hand side expression with `ExprBuilder` and call `add_linear_constraint` or `add_quadratic_constraint` method to create constraints explicitly.
Copy file name to clipboardExpand all lines: docs/source/getting_started.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -245,7 +245,7 @@ con = model.add_linear_constraint(x1+x2, poi.ConstraintSense.Equal, 1, name="con
245
245
```
246
246
`model.add_linear_constraint` adds a linear constraint to the model.
247
247
- The first argument `x1+x2` is the left-hand side of the constraint.
248
-
- The second argument is the sense of the constraint. It can be `poi.ConstraintSense.Equal`, `poi.ConstraintSense.LessEqual` or `poi.ConstraintSense.GreaterEqual`.
248
+
- The second argument is the sense of the constraint. It can be `poi.ConstraintSense.Equal`, `poi.ConstraintSense.LessEqual` or `poi.ConstraintSense.GreaterEqual` which can also be written as `poi.Eq`, `poi.Leq`, and `poi.Geq`.
249
249
- The third argument is the right-hand side of the constraint. It must be a constant.
250
250
- The fourth argument is optional and can be used to specify the name of the constraint.
The optimization model is not ways feasible, and the optimizer may tell us some information about the infeasibility to diagnose the problem. There are two ways to handle the infeasibilities:
10
+
11
+
- Find the IIS (Irreducible Infeasible Set) to identify the minimal set of constraints that cause the infeasibility.
12
+
- Relax the constraints and solve a weaker problem to find out which constraints are violated and how much.
13
+
14
+
PyOptInterface currently supports the first method to find the IIS (only with Gurobi and COPT). The following code snippet shows how to find the IIS of an infeasible model:
15
+
16
+
```{code-cell}
17
+
import pyoptinterface as poi
18
+
from pyoptinterface import copt
19
+
20
+
model = copt.Model()
21
+
22
+
x = model.add_variable(lb=0.0, name="x")
23
+
y = model.add_variable(lb=0.0, name="y")
24
+
25
+
con1 = model.add_linear_constraint(x + y, poi.Geq, 5.0)
26
+
con2 = model.add_linear_constraint(x + 2 * y, poi.Leq, 1.0)
This code snippet creates an infeasible model with two constraints and finds the IIS of the model. Obviously, the constraints are contradictory because `x + 2 * y <= 1` and `x + y >= 5` cannot be satisfied at the same time when `x` and `y` are non-negative. The optimizer will detect that the model is infeasible and return the IIS, which is the set of constraints that cause the infeasibility. We can query whether a constraint is in the IIS by calling `get_constraint_attribute` with the `ConstraintAttribute.IIS` attribute.
40
+
41
+
Sometimes, the bounds of the variables are not consistent with the constraints, and we need to query the IIS of the bounds of variables by calling `get_variable_attribute` with the `VariableAttribute.IISLowerBound` and `VariableAttribute.IISUpperBound` attributes.
42
+
43
+
The following code snippet shows how to tell if the bounds of a variable are in the IIS:
44
+
45
+
```{code-cell}
46
+
model = copt.Model()
47
+
48
+
x = model.add_variable(lb=0.0, ub=2.0, name="x")
49
+
y = model.add_variable(lb=0.0, ub=3.0, name="y")
50
+
51
+
con1 = model.add_linear_constraint(x + y, poi.Geq, 6.0)
Copy file name to clipboardExpand all lines: docs/source/numpy.md
+35-4Lines changed: 35 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,13 +4,15 @@ kernelspec:
4
4
name: python3
5
5
---
6
6
7
-
# Numpy Container and N-queens Problem
7
+
# Matrix Modeling
8
8
9
-
In the previous [container](container.md) section, we have introduced the `tupledict` container to store and manipulate multi-dimensional data.
9
+
In the previous [container](container.md) section, we have introduced the `tupledict` container to store and manipulate multidimensional data.
10
10
11
-
However, due to the Bring Your Own Container (BYOC) principle, variables and constraints in PyOptInterface can just simple Python objects that can be stored in Numpy `ndarrays` directly as a multi-dimensional array, and you can enjoy the features of Numpy such like [fancy-indexing](https://numpy.org/doc/stable/user/basics.indexing.html) automatically.
11
+
However, due to the Bring Your Own Container (BYOC) principle, variables and constraints in PyOptInterface can just simple Python objects that can be stored in Numpy `ndarray` directly as a multidimensional array, and you can enjoy the features of Numpy such like [fancy-indexing](https://numpy.org/doc/stable/user/basics.indexing.html) automatically.
12
12
13
-
We will use N-queens problem as example to show how to use Numpy `ndarrays` as container to store 2-dimensional variables and construct optimization model.
13
+
## N-queen problem
14
+
15
+
We will use N-queens problem as example to show how to use Numpy `ndarray` as container to store 2-dimensional variables and construct optimization model.
14
16
15
17
Firstly, we import the necessary modules:
16
18
@@ -63,3 +65,32 @@ x_value = get_v(x)
63
65
64
66
print(x_value.astype(int))
65
67
```
68
+
69
+
## Built-in functions to add variables and constraints as Numpy `ndarray`
70
+
71
+
Although you can construct the `ndarray` of variables and constraints manually, PyOptInterface provides built-in functions to simplify the process. The following code snippet shows how to use the built-in functions to add variables and constraints as Numpy `ndarray`:
Here we use two built-in functions `add_m_variables` and `add_m_linear_constraints` to add variables and constraints as Numpy `ndarray` respectively.
91
+
92
+
The reference of these functions are listed in <project:#model.add_m_variables> and <project:#model.add_m_linear_constraints>.
93
+
94
+
`add_m_variables` returns a `ndarray` of variables with the specified shape.
95
+
96
+
`add_m_linear_constraints` adds multiple linear constraints to the model at once formulated as $Ax \le b$ or $Ax = b$ or $Ax \ge b$ where the matrix $A$ can be a dense `numpy.ndarray` or a sparse matrix `scipy.sparse.sparray`.
0 commit comments