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
The optimal configuration would be
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
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.