0

I want to use piecewise function to modify values in my pyomo model :

  • 2 -> 1
  • -3 -> 0
  • 5 -> 0.5
  • 0 -> 0

I have a variable called model.test taking values in [-3,0,2,5] :

h_change : Size=11, Index=vehicules
    Key : Lower : Value : Upper : Fixed : Stale : Domain
      0 :    -3 :   0.0 :     5 : False : False : Integers
      1 :    -3 :   2.0 :     5 : False : False : Integers
      2 :    -3 :   2.0 :     5 : False : False : Integers
      3 :    -3 :   2.0 :     5 : False : False : Integers
      4 :    -3 :   0.0 :     5 : False : False : Integers
      5 :    -3 :  -3.0 :     5 : False : False : Integers
      6 :    -3 :   0.0 :     5 : False : False : Integers
      7 :    -3 :   0.0 :     5 : False : False : Integers
      8 :    -3 :   0.0 :     5 : False : False : Integers
      9 :    -3 :   0.0 :     5 : False : False : Integers
     10 :    -3 :   5.0 :     5 : False : False : Integers

I used this next piecewise constraint :

model.test = Var(model.vehicules, initialize=0, bounds=(0,1))

DOMAIN_PTS = [-3.,0.,2.,5.]
RANGE_PTS  = [0.,0.,1.,0.5]

model.con = Piecewise(model.vehicules, #Indexation
                        model.test, # Var res
                        model.h_change, #Var observées
                          pw_pts=DOMAIN_PTS,
                          pw_constr_type='EQ',
                          f_rule=RANGE_PTS)

My variable model.test resulting is like this :

test : Size=11, Index=vehicules
    Key : Lower : Value               : Upper : Fixed : Stale : Domain
      0 :     0 :                 0.0 :     1 : False : False :  Reals
      1 :     0 : 0.20000000000000004 :     1 : False : False :  Reals
      2 :     0 : 0.20000000000000004 :     1 : False : False :  Reals
      3 :     0 : 0.20000000000000004 :     1 : False : False :  Reals
      4 :     0 :                 0.0 :     1 : False : False :  Reals
      5 :     0 :                 0.0 :     1 : False : False :  Reals
      6 :     0 :                 0.0 :     1 : False : False :  Reals
      7 :     0 :                 0.0 :     1 : False : False :  Reals
      8 :     0 :                 0.0 :     1 : False : False :  Reals
      9 :     0 :                 0.0 :     1 : False : False :  Reals
     10 :     0 :  0.5000000000000001 :     1 : False : False :  Reals

I don't understand why my 2 values (index 1, 2, 3) became 0.2 instead of 1.

Can you help me to understand what is wrong with my code ?


UPDATE :


I tried this code to test (from http://yetanothermathprogrammingconsultant.blogspot.com/2019/02/piecewise-linear-functions-and.html)

#
# expected solution X=5, Y=6
#

xdata = [1., 3., 6., 10.]
ydata  = [6.,2.,8.,7.]

from pyomo.core import *

model = ConcreteModel()

model.X = Var(bounds=(1,10))
model.Y = Var(bounds=(0,100))

model.con = Piecewise(model.Y,model.X,
                      pw_pts=xdata,
                      pw_constr_type='EQ',
                      f_rule=ydata,
                      pw_repn='SOS2')

# see what we get for Y when X=5
def con2_rule(model):
    return model.X==5

model.con2 = Constraint(rule=con2_rule)

model.obj = Objective(expr=model.Y, sense=maximize)

But with my solver (Couenne) I got

Y=7.600000072980164.

I think there is then a issue with my solver and not with the PieceWise code ...

LCMa
  • 445
  • 3
  • 13
  • Not sure, but... In the previous line of code you bound `model.test` to (0, 1). Try removing/relaxing that bound on the variable, perhaps to just NonNegativeReals – AirSquid Jul 30 '20 at 14:10
  • I tried to play with those bounds but without success ... When putting no bounds and domain or just domain=NonNegatuceReals, my solver stop early without solution (" This application has requested the Runtime to terminate it in an unusual way."). Putting bounds=(0,2) gives the same result as before (0.2 instead of 1)... – LCMa Jul 30 '20 at 14:17
  • hmmm. And it looks like you are working with 2 models??? `model` and `model_3` simultaneously? – AirSquid Jul 30 '20 at 14:19
  • Sorry, I will edit my first message.I'm only working with one model (called model_3 in reality, but easier to understand when called simply model) – LCMa Jul 30 '20 at 14:21
  • I'm going to delete my answer below, which is off-track. Hopefully it will improve your chances of getting a good solution to this. – AirSquid Jul 30 '20 at 16:03

2 Answers2

0

I found a way to make my constraint working :

simply change pw_repn='SOS2' to pw_repn='CC'

LCMa
  • 445
  • 3
  • 13
-1

Try to use cplex solver. I run the code with CPLEX solver and it gives me the same result.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 02 '22 at 22:04