1+ from typing import List
12
23from pyscipopt import Model , quicksum , Variable , Constraint
34
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
65
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
710 :param X: x variable
811 :param Y: y variable
912 :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
1215 Disclaimer: For the moment, can only model 2d piecewise linear functions
1316 Adapted from https://github.com/scipopt/PySCIPOpt/blob/master/examples/finished/piecewise.py
1417 """
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 ])
1629
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 )
2231
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 )))
2633
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 )]
2836
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 )))
3038
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