简体   繁体   English

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

[英]Gekko can't find solution of a small problem

I am making some tests with Gekko library from python, and have a small problem in which I know the solution.我正在使用 python 的 Gekko 库进行一些测试,并且有一个我知道解决方案的小问题。 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()


The code exits with an error: Exception: @error: Solution Not Found .代码退出并出现错误: 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]]

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.更奇怪的是,即使我极大地增加变量qtde的值(例如, qtde = [40,40,40] ),算法也找不到解决方案。 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

I always get an infeasible solution message if I set the lower bound to zero for all generation units.如果我将所有发电单元的下限设置为零,我总是会收到infeasible solution消息。 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.在这种情况下,我必须将中间单元绑定在 4 以上才能获得成功的解决方案,而其他单元则为零。 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))

With a perfect solver, an initial guess would not be needed and bounds could be set from 0 to infinity .使用完美的求解器,不需要初始猜测,并且可以将边界设置为从0infinity Some problems are harder to solve, such as problems with mixed integer variables and when using complementarity conditions.有些问题更难解决,例如混合 integer 变量和使用互补条件时的问题。 Your problem has both so I'm not surprised that the solver struggles without the initial guess or appropriate bounds.你的问题两者都有,所以我并不惊讶求解器在没有初始猜测或适当界限的情况下挣扎。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM