首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gekko找不到小问题的解决方案

Gekko找不到小问题的解决方案
EN

Stack Overflow用户
提问于 2020-04-28 05:58:28
回答 1查看 382关注 0票数 4

我正在用python中的Gekko库做一些测试,我有一个小问题,我知道其中的解决方案。完整的代码如下:

代码语言:javascript
复制
from gekko import GEKKO

P = [[3.0,3.55,5.18,7.9,5.98],
    [1.56,1.56,2.48,3.15,2.38],
    [1.49,4.96,6.4,9.4,6.5]]

M = [[1,2,3,4,5],
     [6,7,8,9,10],
     [11,12,13,14,15]]

mm = M
pp = P
c1 = [300,200,150,250,180]
qtde = [10,10,10]
flex = [0.2,0.2,0.2]

m = GEKKO(remote=False)
ni = 3
nj = 5
x = [[m.Var(lb=0,integer=True) for j in range(nj)] for i in range(ni)]

s = 0
expr = []
for i in range(ni):
    for j in range(nj):
        s += x[i][j]*pp[i][j]
    expr.append(s)
    s = 0

for i in range(ni):
    for j in range(nj):
        if mm[i][j] == 0:
            m.Equation(x[i][j] == 0)


for i in range(len(flex)):
    if flex[i] == 0:
        m.Equation(sum([x[i][j] for j in range(nj)]) >= qtde[i])
    else:
        m.Equation(sum([x[i][j] for j in range(nj)]) >= qtde[i])
        m.Equation(sum([x[i][j] for j in range(nj)]) <= (1+flex[i])*qtde[i])


b = m.Array(m.Var,nj,integer=True,lb=0,ub=1)
iv = [None]*nj



for j in range(nj):
   iv[j] = m.sum([pp[i][j]*x[i][j] for i in range(ni)])
   m.Equation(iv[j] >= b[j]*c1[j])


m.Obj(m.sum(expr))

m.options.SOLVER=1 # switch to APOPT
m.solver_options = ['minlp_gap_tol 1.0e-2',\
                    'minlp_maximum_iterations 50000',\
                    'minlp_max_iter_with_int_sol 50000',\
                    'minlp_branch_method 1',\
                    'minlp_integer_leaves 2']


m.solve()    

for j in range(nj):
    m.Equation((1 - b[j])*iv[j] == 0)

m.options.SOLVER=1
m.solve()

代码退出,并返回错误:Exception: @error: Solution Not Found。这很奇怪,因为有一个明确的解决方案:

代码语言:javascript
复制
x = [[0,0,12,0,0],
     [0,0,12,0,0],
     [0,0,12,0,0]]

更奇怪的是,即使我极大地增加变量qtde (例如,qtde = [40,40,40])的值,算法也找不到解决方案。我写约束的方式有什么错误吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-28 22:36:53

有时,求解者需要更好的初始猜测或选择性界限的帮助,以远离有问题的解决方案。这里有一些东西可以帮助解决这个问题,只需要一次求解器调用。

代码语言:javascript
复制
lower = [0,0,4,0,0]
for i in range(ni):
    for j in range(nj):
        x[i][j].value = 5
        x[i][j].lower = lower[j]
        x[i][j].upper = 20

如果我将所有生成单元的下限设置为零,我总是得到一条infeasible solution消息。求解器似乎卡在全零的试解中,或者当所有值都低于某个阈值时。在这种情况下,我必须将中间单元限制为大于4才能获得成功的解决方案,而其他单元为0。下面是完整的代码:

代码语言:javascript
复制
from gekko import GEKKO

P = [[3.0,3.55,5.18,7.9,5.98],
    [1.56,1.56,2.48,3.15,2.38],
    [1.49,4.96,6.4,9.4,6.5]]

M = [[1,2,3,4,5],
     [6,7,8,9,10],
     [11,12,13,14,15]]

mm = M
pp = P
c1 = [300,200,150,250,180]
qtde = [10,10,10]
flex = [0.2,0.2,0.2]

m = GEKKO(remote=False)
ni = 3
nj = 5
x = [[m.Var(integer=True) for j in range(nj)] for i in range(ni)]

# Fix x at values to check the feasibility of the initial guess
#x = [[m.Param() for j in range(nj)] for i in range(ni)]

lower = [0,0,4,0,0]
for i in range(ni):
    for j in range(nj):
        x[i][j].value = 5
        x[i][j].lower = lower[j]
        x[i][j].upper = 20

s = 0
expr = []
for i in range(ni):
    for j in range(nj):
        s += x[i][j]*pp[i][j]
    expr.append(s)
    s = 0

for i in range(ni):
    for j in range(nj):
        if mm[i][j] == 0:
            m.Equation(x[i][j] == 0)


for i in range(len(flex)):
    if flex[i] == 0:
        m.Equation(sum([x[i][j] for j in range(nj)]) >= qtde[i])
    else:
        m.Equation(sum([x[i][j] for j in range(nj)]) >= qtde[i])
        m.Equation(sum([x[i][j] for j in range(nj)]) <= (1+flex[i])*qtde[i])


b = m.Array(m.Var,nj,value=0.5,integer=True,lb=0,ub=1)
iv = [None]*nj



for j in range(nj):
   iv[j] = m.sum([pp[i][j]*x[i][j] for i in range(ni)])
   m.Equation(iv[j] >= b[j]*c1[j])


m.Obj(m.sum(expr))

for j in range(nj):
    m.Equation((1 - b[j])*iv[j] <= 1e-5)

print('Initial guess: ' + str(x))

# solve as NLP first to see iterations
#m.solver_options = ['minlp_as_nlp 1']
#m.options.SOLVER = 1
#m.solve(debug=0)



# solve as MINLP
m.options.SOLVER=1 # switch to APOPT
m.solver_options = ['minlp_gap_tol 1.0e-2',\
                    'minlp_maximum_iterations 50000',\
                    'minlp_max_iter_with_int_sol 50000',\
                    'minlp_branch_method 1',\
                    'minlp_integer_leaves 2']

m.options.SOLVER=1
m.solve(disp=False)

print('Final solution: ' + str(x))

有了完美的求解器,就不需要初始猜测了,可以设置从0infinity的范围。有些问题更难解决,例如混合整数变量的问题和使用互补条件时的问题。你的问题两者都有,所以我对求解器在没有初始猜测或适当界限的情况下苦苦挣扎并不感到惊讶。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61469170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档