Search code examples
linear-programmingglpkmathprog

Modelling piecewise function in GLPK


I am trying to use GLPK to solve an optimization problem for which I have a piecewise function (2 sub-functions). In short, the problem is about minimizing energy costs in an environment by scheduling the operation of certain (electrical) appliances. Production of energy is also being considered, rendering my objective function to be the minimization of the following function:

objective function

The idea is that, for each instant, balance[i] will store the overall energy balance (that is, the difference between energy consumed and produced). Therefore, if balance[i]>= 0 the amount of energy demanded surpasses production and we need to buy energy from the grid; otherwise, production exceeds demands and we can sell excess energy to the grid.

For each time instant, the value of balance[i] will depend on energy production, fixed energy consumptions (both previously known, so no problem variables involved) and on energy consumptions of scheduled appliances (computed as a function of the problem variables).

In trying to model this in GLPK I introduced a binary variable that, for each instant i, tells the signal of balance[i]. The idea is to write the objective function as:

minimize obj: sum {i in k} (z[i]*balance[i]*buy + (1-z[i])*balance[i]*sell)

Thus, I want z[i] to be 1 when balance[i]>= 0 and z[i] to be 0 otherwise (balance[i] < 0).

How can I define the constraints on z[i]? I know one can define conditional constraints in GLPK, but as far as I know I can't write:

s.t. zUpperi{i in k: balance[i] >= 0}: z[i] = 1;

because balance[i] depends on problem variables... Are there other ways of expressing this constraint? Or is this not even possible in GLPK?


Solution

  • Your approach

    minimize obj: sum {i in k} (z[i]*balance[i]*buy + (1-z[i])*balance[i]*sell)
    

    makes the problem nonlinear (quadratic) as you multiply two variables. In general we can do:

    minimize obj: sum {i in k} (posbal[i]*buy + negbal[i]*(-sell)) 
    
    # constraints 
    posbal[i] - negbal[i] = balance[i]
    posbal[i] <= z[i]*maxbal[i]
    negbal[i] <= (1-z[i])*maxbal[i]
    
    # bounds
    posbal[i] >= 0, negbal[i] >= 0
    -maxbal[i] <= balance[i] <= maxbal[i]
    z[i] binary
    

    where maxbal[i] is a constant bound on balance[i]. I assume sell,buy are constants.

    Often this construct can be simplified further, but that depends on the details of the model.