1
+ from typing import List
1
2
2
3
from pyscipopt import Model , quicksum , Variable , Constraint
3
4
4
- def add_piecewise_linear_cons (model : Model , X : Variable , Y : Variable , a : list [float ], b : list [float ]) -> Constraint :
5
- """add constraint of the form y = f(x), where f is a piecewise linear function
6
5
6
+ def add_piecewise_linear_cons (model : Model , X : Variable , Y : Variable , a : List [float ], b : List [float ]) -> Constraint :
7
+ """add constraint of the form y = f(x), where f is a piecewise linear function
8
+
9
+ :param model: pyscipopt model to add the constraint to
7
10
:param X: x variable
8
11
:param Y: y variable
9
12
:param a: array with x-coordinates of the points in the piecewise linear relation
@@ -12,25 +15,25 @@ def add_piecewise_linear_cons(model: Model, X: Variable, Y: Variable, a: list[fl
12
15
Disclaimer: For the moment, can only model 2d piecewise linear functions
13
16
Adapted from https://github.com/scipopt/PySCIPOpt/blob/master/examples/finished/piecewise.py
14
17
"""
15
- assert len (a ) == len (b ), "Must have the same number of x and y-coordinates"
18
+ assert len (a ) == len (b ), "Must have the same number of x and y-coordinates"
19
+
20
+ K = len (a ) - 1
21
+ w , z = {}, {}
22
+ for k in range (K ):
23
+ w [k ] = model .addVar (lb = - model .infinity ())
24
+ z [k ] = model .addVar (vtype = "B" )
25
+
26
+ for k in range (K ):
27
+ model .addCons (w [k ] >= a [k ] * z [k ])
28
+ model .addCons (w [k ] <= a [k + 1 ] * z [k ])
16
29
17
- K = len (a )- 1
18
- w ,z = {},{}
19
- for k in range (K ):
20
- w [k ] = model .addVar (lb = - model .infinity ())
21
- z [k ] = model .addVar (vtype = "B" )
30
+ model .addCons (quicksum (z [k ] for k in range (K )) == 1 )
22
31
23
- for k in range (K ):
24
- model .addCons (w [k ] >= a [k ]* z [k ])
25
- model .addCons (w [k ] <= a [k + 1 ]* z [k ])
32
+ model .addCons (X == quicksum (w [k ] for k in range (K )))
26
33
27
- model .addCons (quicksum (z [k ] for k in range (K )) == 1 )
34
+ c = [float (b [k + 1 ] - b [k ]) / (a [k + 1 ] - a [k ]) for k in range (K )]
35
+ d = [b [k ] - c [k ] * a [k ] for k in range (K )]
28
36
29
- model .addCons (X == quicksum (w [k ] for k in range (K )))
37
+ new_cons = model .addCons (Y == quicksum (d [ k ] * z [ k ] + c [ k ] * w [k ] for k in range (K )))
30
38
31
- c = [float (b [k + 1 ]- b [k ]) / (a [k + 1 ]- a [k ]) for k in range (K )]
32
- d = [b [k ] - c [k ]* a [k ] for k in range (K )]
33
-
34
- new_cons = model .addCons (Y == quicksum (d [k ]* z [k ] + c [k ]* w [k ] for k in range (K )))
35
-
36
- return new_cons
39
+ return new_cons
0 commit comments