Sourav Ghosh
Sourav Ghosh

Reputation: 41

Relax Gekko constraints if solution is infeasible

I am trying to solve an MILP Optimization problem of maxmimizing a ratio with constraints that the sum of tail of the binary decion variables that the optimizer chooses is between tail_min and tail_max.

However there is a possibility that the optimizer might run into an infeasile solution given the tail_min constraint which I am trying to update using a try, except block and trying with an updated tail_min value.

I have a feeling the Gekko is just adding up a new constraint whenever I am updating the new tail_min by decrementing it by 0.005 so it'll never reach a feasible solution as the 1st constaint which had the base tail_min is still present in the list of constraints.

How do I actually update the given constraint with the new tail_min value instead of just piling up constraints every time the while loop is triggered.

isOpt_Sol = False

m.Maximize( ((m.sum([tl_c[i]*xc[i] for i in range(tot_ean_c)])) + (m.sum([tl_m[j]*xm[j] for j in range(tot_ean_m)])) ) / ((m.sum([to_c[i]*xc[i] for i in range(tot_ean_c)])) + (m.sum([to_m[j]*xm[j] for j in range(tot_ean_m)])) + 1) )

# Constraints :-
m.Equation( (m.sum([tl_c[i]*xc[i] for i in range(tot_ean_c)])) +  (m.sum([tl_m[j]*xm[j] for j in range(tot_ean_m)])) <= tail_max)
m.Equation(m.sum([xc[i] for i in range(tot_ean_c)]) == 1)
m.Equation(m.sum([xm[i] for i in range(tot_ean_m)]) == 1)

while isOpt_Sol==False:
  try:        
    print("ATTEMPTING TO SOLVE with tail_min = ", tail_min)
    m.Equation( (m.sum([tl_c[i]*xc[i] for i in range(tot_ean_c)])) +  (m.sum([tl_m[j]*xm[j] for j in range(tot_ean_m)])) > tail_min)
    m.solve(disp=True)
    isOpt_Sol = True
  except:
    tail_min = tail_min - 0.005
    print("FAILED TRYING AGAIN!")
    isOpt_Sol = False

Any help would be appreciated!

Upvotes: 2

Views: 175

Answers (1)

John Hedengren
John Hedengren

Reputation: 14376

If you need to change a value in a constraint, use m.Param() and change that value with tmin.value.

I can't verify the solution because the problem isn't complete but here is proposed a suggestion that you'll need to implement and verify.

m.Maximize( ((m.sum([tl_c[i]*xc[i] for i in range(tot_ean_c)])) \
             + (m.sum([tl_m[j]*xm[j] for j in range(tot_ean_m)])) ) \
             / ((m.sum([to_c[i]*xc[i] for i in range(tot_ean_c)])) \
             + (m.sum([to_m[j]*xm[j] for j in range(tot_ean_m)])) + 1) )

# Constraints :-
m.Equation( (m.sum([tl_c[i]*xc[i] for i in range(tot_ean_c)])) \
             +  (m.sum([tl_m[j]*xm[j] for j in range(tot_ean_m)])) <= tail_max)
m.Equation(m.sum([xc[i] for i in range(tot_ean_c)]) == 1)
m.Equation(m.sum([xm[i] for i in range(tot_ean_m)]) == 1)

tmin = m.Param(value=tail_min)
m.Equation( (m.sum([tl_c[i]*xc[i] for i in range(tot_ean_c)])) \
             +  (m.sum([tl_m[j]*xm[j] for j in range(tot_ean_m)])) > tail_min)

isOpt_Sol = False
tail_min=0.1
while not isOpt_Sol:
    tail_min = tail_min - 0.005
    tmin.value=tail_min
    print("ATTEMPTING TO SOLVE with tail_min = ", tail_min)
    m.solve(disp=True)
    if m.options.APPSTATUS==1:
        isOpt_Sol=True

Upvotes: 0

Related Questions