如何解决Python Gekko - 尽管我有一个最佳解决方案,但受到了约束
首先让我说我是线性规划和 Python Gekko 的绝对初学者。
我正在朋友家铺设层压板,我认为编写一个程序使层压板尽可能以最佳配置铺设会很酷。
以下是铺设层压板的限制
- 每块应为 minLaminateSize
- 每个都应与其相邻的部分重叠 minOverlap 的长度
最佳配置是
我能够在 python Gekko 中快速编写以下程序。但我快疯了,因为定义的一些约束正在打破
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]
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,ub=laminateSize) for i in range(columnRange)]
numberOfCompleteLaminate=[m.Var(integer=True,ub=10) for i in range(columnRange)]
for i in range(columnRange):
x[i] = [m.Var(integer=True,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)
上面的程序给出了下面的结果
[[2.0],[2.0],[2.0]]
[[40.0],[80.0],[120.0],[40.0],[40.0]]
[[120.0],[120.0]]
虽然找到了最佳结果,但我发现约束没有得到满足。 例如:[40.0],[40.0] 这种组合不应该存在,因为重叠约束不会得到满足。由以下代码行定义
m.Equation( m.abs2(top[j] - top[i] ) >= minOverlap)
我有几个问题
- 我是否走在正确的道路上,是否需要更改任何设置才能解决约束问题。
- 有没有更好的方法来编写程序并更有效地解决它
- 我还看到,如果列数更像是 15 或 20,则需要永远解决问题。我能做些什么来有效地解决问题。我也可以使用多线程或在功能强大的计算机上运行它。
我非常需要帮助,我快疯了。
解决方法
一个问题是 matchingSize
被重新定义为整数。它必须是 Gekko Array 变量,因为您之前将其正确定义为 matchingSize = m.Array(m.Var,(columnRange))
。这是一个保留 matchingSize
作为 Gekko 对象的修改版本。
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])
我也喜欢使用 abs3()
(二进制切换)而不是 abs2()
(MPCC form)。该问题目前没有解决(不可行的解决方案),但这应该可以帮助您调查哪些限制因素阻碍了可行的解决方案。
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]
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,ub=laminateSize) for i in range(columnRange)]
numberOfCompleteLaminate=[m.Var(integer=True,ub=10) for i in range(columnRange)]
for i in range(columnRange):
x[i] = [m.Var(integer=True,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)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。