Gekko找不到小问题的解决方案 [英] Gekko can't find solution of a small problem

查看:163
本文介绍了Gekko找不到小问题的解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用python的Gekko库进行一些测试,但有一个小问题,我知道解决方案.完成代码如下:

I am making some tests with Gekko library from python, and have a small problem in which I know the solution. The complet code is as follows:

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.这很奇怪,因为有一个明确的解决方案:

The code exits with an error:Exception: @error: Solution Not Found. Which is strange, since there is a clear solution:

x = [[0,0,12,0,0],
     [0,0,12,0,0],
     [0,0,12,0,0]]

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

More strange is the fact that even if I increase enormously the value of the variable qtde (for example, qtde = [40,40,40]), the algorithm cannot find a solution. Is there some mistake in the way I am writing the constraints?

推荐答案

有时候,求解器需要更好的初始猜测或选择范围的帮助,以避开有问题的解决方案.只需一个求解器调用,即可帮助解决问题.

Sometimes solvers need help with a better initial guess or selective bounds to stay away from problematic solutions. Here is something that helps solve the problem with only one solver call.

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以上才能获得成功的解决方案,而其他单元为零.这是完整的代码:

I always get an infeasible solution message if I set the lower bound to zero for all generation units. The solver appears to get stuck at a trial solution of all zeros or when all are below a certain threshold. In this case, I had to bound the middle unit to be above 4 to get a successful solution while the others are at zero. Here is the complete code:

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))

有了一个完美的求解器,就不需要进行初步猜测,并且可以将范围从0设置为infinity.有些问题较难解决,例如混合整数变量的问题以及使用互补条件时的问题.您的问题同时存在,因此对于没有最初的猜测或适当的边界的求解器,我感到惊讶.

With a perfect solver, an initial guess would not be needed and bounds could be set from 0 to infinity. Some problems are harder to solve, such as problems with mixed integer variables and when using complementarity conditions. Your problem has both so I'm not surprised that the solver struggles without the initial guess or appropriate bounds.

这篇关于Gekko找不到小问题的解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆