Saturday, 20 February 2021

Python Gekko - Constrained are getting violated although i have an optimal solution

Let me start by saying that I am an absolute beginner in Linear Programming and Python Gekko.

I was laying laminate in my friend's house and I thought it would be cool to write a program such that the laminate is laid in as optimal configuration as possible.

Below are the constraints for laying the laminate

  1. Each piece should be of minLaminateSize
  2. Each should overlap with its adjacent piece for a length of minOverlap

The optimal configuration would be

  1. Reusing the laminate as efficiently as possible by pairing the top piece with the bottom piece in any column
  2. Make as less cuts as possible. So ideal cut would be making a full laminate into two pieces and placing the top piece in one of the column and bottom piece in another column.

I was able to quickly write the below program in python Gekko. But i am going crazy as some of the constraints defined are breaking

from gekko import GEKKO
import numpy as np
from gekko.apm import get_file

#Initialize Model
m = GEKKO()
columnRange=10

#define parameter
height=[400,400,400,400,400,400,400,400,400,400]


laminateSize = 120
minOverlap = 40
minLaminateSize = 40
top = m.Array(m.Var,(columnRange))
bottom = m.Array(m.Var,(columnRange))
matchingSize = m.Array(m.Var,(columnRange))
numberOfCompleteLaminate = m.Array(m.Var,(columnRange))
x = m.Array(m.Var,(columnRange,columnRange))


#initialize variables
top=[m.Var(integer=False,lb=0, ub=laminateSize) for i in range(columnRange)]
bottom=[m.Var(120,integer=False,lb=0, ub=laminateSize) for i in range(columnRange)]
numberOfCompleteLaminate=[m.Var(integer=True,lb=0, ub=10) for i in range(columnRange)]


for i in range(columnRange):
    x[i] = [m.Var(integer=True,lb=0, ub=1 ) for j in range(columnRange)]


for i in range(columnRange):
    m.Equation(top[i]+bottom[i]+numberOfCompleteLaminate[i]*laminateSize == height[i])
    m.Equation(top[i]>=minLaminateSize )
    m.Equation(bottom[i]>=minLaminateSize )


for i in range(columnRange-1):
    j=i+1     
    m.Equation( m.abs2(top[j]  - top[i] ) >= minOverlap)        
    m.Equation( m.abs2(top[j]  - top[i] )  <= laminateSize-minOverlap )        

for i in range(columnRange):
     m.Equation( sum( x[i,j] for j in range(columnRange) ) <= 1 )
     m.Equation( sum( x[j,i] for j in range(columnRange) ) <= 1)

m.Maximize(m.sum(numberOfCompleteLaminate) )


for i in range(columnRange):
    matchingSize[i]=0
    for j in range(columnRange):
        matchingSize[i]=matchingSize[i] + x[i][j] * (top[i] + bottom[j] )         
    m.Equation(matchingSize[i]<=laminateSize)
    m.Maximize(matchingSize[i])


m.Maximize(m.sum(x))     

#Set global options
m.options.SOLVER = 1
m.options.SCALING=1
m.options.IMODE = 3

m.solver_options = ['minlp_maximum_iterations 1500', \
                    # minlp iterations with integer solution
                    'minlp_max_iter_with_int_sol 10', \
                    # treat minlp as nlp
                    'minlp_as_nlp 0', \
                    # nlp sub-problem max iterations
                    'nlp_maximum_iterations 50', \
                    # 1 = depth first, 2 = breadth first
                    'minlp_branch_method 1', \
                    # maximum deviation from whole number
                    'minlp_integer_tol 0.1', \
                    # covergence tolerance
                    'minlp_gap_tol 0.01']
#Solve simulation
m.solve()

#Results


print(numberOfCompleteLaminate)
print(top)
print(bottom)
print(x)

The above program gives the below result

[[2.0], [2.0], [2.0], [2.0], [2.0], [2.0], [2.0], [2.0], [2.0], [2.0]]
[[40.0], [80.0], [120.0], [80.0], [40.0], [40.0], [80.0], [120.0], [80.0], [40.0]]
[[120.0], [80.0], [40.0], [80.0], [120.0], [120.0], [80.0], [40.0], [80.0], [120.0]]

Although an optimal result is found, i see that the constraint is not fulfilled. For eg: [40.0], [40.0] This combination should never exist as the overlap constrain would not be fulfilled. Defined by the below line of code

    m.Equation( m.abs2(top[j]  - top[i] ) >= minOverlap)        

I have a couple of questions

  1. Am I on the right path, is there any settings that I have to change to solve the constraints.
  2. Is there a better way to write the program and solve it more efficiently
  3. Also i see that if the number of columns are more like 15 or 20 it is taking forever to solve the problem. Is there anything i can do to efficiently solve the problem. I am also okay with multithreading or running it on a powerful computer.

I badly need help, I am going crazy.

enter image description here



from Python Gekko - Constrained are getting violated although i have an optimal solution

No comments:

Post a Comment