微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python Gekko - 尽管我有一个最佳解决方案,但受到了约束

如何解决Python Gekko - 尽管我有一个最佳解决方案,但受到了约束

首先让我说我是线性规划和 Python Gekko 的绝对初学者。

我正在朋友家铺设层压板,我认为编写一个程序使层压板尽可能以最佳配置铺设会很酷。

以下是铺设层压板的限制

  1. 每块应为 minLaminateSize
  2. 每个都应与其相邻的部分重叠 minOverlap 的长度

最佳配置是

  1. 通过在任何列中将顶部部件与底部部件配对,尽可能有效地重复使用层压板
  2. 尽量少剪。因此,理想的切割方式是将一个完整的层压板制成两块,并将顶部的一块放在一列中,将底部的一块放在另一列中。

我能够在 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)        

我有几个问题

  1. 我是否走在正确的道路上,是否需要更改任何设置才能解决约束问题。
  2. 有没有更好的方法来编写程序并更有效地解决
  3. 我还看到,如果列数更像是 15 或 20,则需要永远解决问题。我能做些什么来有效地解决问题。我也可以使用多线程或在功能强大的计算机上运行它。

我非常需要帮助,我快疯了。

enter image description here

解决方法

一个问题是 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 举报,一经查实,本站将立刻删除。