简体   繁体   中英

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.

在此处输入图像描述

One problem is that matchingSize is redefined as an Integer. It needs to be a Gekko Array variable as you correctly defined it earlier as matchingSize = m.Array(m.Var,(columnRange)) . Here is a modified version that keeps matchingSize as a Gekko object.

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

I also like to use abs3() (binary switching) instead of abs2() ( MPCC form ). The problem doesn't currently solve (infeasible solution) but this should help you investigate which constraints are preventing a feasible solution.

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

#Initialize Model
m = GEKKO(remote=False)
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.abs3(top[j]  - top[i] ) >= minOverlap)        
    m.Equation( m.abs3(top[j]  - top[i] ) <= laminateSize-minOverlap )        

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

m.Maximize(m.sum(numberOfCompleteLaminate) )

for i in range(columnRange):
    s=0
    for j in range(columnRange):
        s+=x[i][j] * (top[i] + bottom[j] )         
    m.Equation(s==matchingSize[i])
    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.01', \
                    # covergence tolerance
                    'minlp_gap_tol 0.001']

#Solve simulation
try:
    m.solve()
except:
    print('unsuccessful')
    # view infeasibilities.txt file
    # give the variables names with x = m.Var(name='x') for a more readable
    #  diagnostic file
    m.open_folder()

#Results
print(numberOfCompleteLaminate)
print(top)
print(bottom)
print(x)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM