Gekko can't find solution of a small problem

耗尽温柔 提交于 2020-05-27 05:14:06

问题


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


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

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?


回答1:


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

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.



来源:https://stackoverflow.com/questions/61469170/gekko-cant-find-solution-of-a-small-problem

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!