Ошибка, полученная с помощью Pyomo / Ipopt при оптимизации настраиваемой функции - PullRequest
0 голосов
/ 29 апреля 2020

Я новичок ie в Пьомо и Ипопте. Я хотел бы оптимизировать задачу нелинейной оптимизации с помощью этих инструментов. Я получаю сообщение об ошибке при попытке оптимизировать функцию.

Я играл с примерами, предоставленными Pyomo. Основное отличие в моей проблеме состоит в том, что я хотел бы определить целевую функцию в отдельной функции и что она подразумевает некоторое умножение с массивами numpy, но я думаю, что обе они могут быть обработаны с помощью Pyomo.

Я попытался максимально упростить мою проблему (наверняка это не имеет смысла с точки зрения оптимизации, а просто показать проблему). Моя проблема выглядит так:

import numpy as np
from pyomo.environ import *

def myfunc(model, extra_param):
    matrix_A=np.sin(np.random.rand(100,100))+extra_param
    return sum(model.x*matrix_A-extra_param)

extra_param=5
model = ConcreteModel()
model.IDX=range(100)
model.x = Var(model.IDX,bounds=(0,1.), initialize=0.99)
model.obj=Objective(expr = myfunc(model,extra_param))
model.pprint()
solver = SolverFactory('ipopt')
solver.solve(model, tee=True)

, и я получаю следующее сообщение:

Ipopt 3.11.1: C:\Users\A\Anaconda3\Library\bin\ipopt.exe: jacdim: got M = 0, N = 0, NO = 1
ERROR: Solver (ipopt) returned non-zero return code (1)
ERROR: See the solver log above for diagnostic information.

1 Ответ

1 голос
/ 29 апреля 2020

Проблема, с которой вы столкнулись, состоит в том, что ваша целевая функция не возвращает выражение, которое приводит к скалярному значению (вы можете увидеть это, проверив результаты model.obj.pprint()).

Что-то подобное, вероятно, могло бы быть делайте что хотите:

def myfunc(model, extra_param):
    matrix_A=np.sin(np.random.rand(100,1)).flatten() + extra_param
    return sum(matrix_A[i] * model.x[i] for i in model.IDX)

Обратите внимание, что я изменил часть (100,100) в вашей функции np.random.rand на (100,1), поскольку ваша переменная model.x является вектором. Кроме того, метод .flatten() свернет массив в 1-D.

...