как я могу использовать оптимизатор gekko без известной целевой функции (скажем, некоторой случайной функции) и с известными переменными и ограничениями? - PullRequest
4 голосов
/ 20 января 2020

Я пытаюсь свести к минимуму и максимизировать случайную «тестовую функцию», используя gekko, который связан с A. A состоит из 4 параметров между диапазоном (0-100) и суммой A <100. Однако я продолжаю получать странные результаты потому что минимум тестовой функции должен быть 2500, а максимальный 10000. Мой код ниже. Может кто-нибудь сказать мне, где проблема? Заранее спасибо </p>


    import numpy as np
    from gekko import GEKKO 


    def test_function(x):
        return np.dot(x, x)


    A = m.Array(m.Var, (4))
    # initial guess
    ig = [1, 5, 5, 1]
    # lower bounds
    i = 0
    for Ai in A:
        Ai.value = ig[i]
        Ai.lower = 0
        Ai.upper = 100
        i += 1
    m.Equation(np.sum(A) < 100)
    m.Obj(test_function(A))
    m.solve()
    print(test_function(A))
    print (A)

результаты

Solver         :  IPOPT (v3.12)
 Solution time  :   1.379999999971915E-002 sec
 Objective      :   4.141037033873033E-007
 Successful solution
 ---------------------------------------------------

(((((v1)*(v1))+((v2)*(v2)))+((v3)*(v3)))+((v4)*(v4)))
[[0.00042734466188] [0.00015629584657] [0.00015629584657]
 [0.00042734466188]]

Process finished with exit code 0

Ответы [ 2 ]

3 голосов
/ 23 января 2020

Я изменил проблему, чтобы соответствовать вашему утверждению. Существует также понимание списка, которое упрощает процесс определения новых переменных с верхними и нижними границами. Следующий скрипт показывает два способа доступа к test_function(x) с (1) переменными Gekko, которые являются символами c выражениями или (2) со значениями чисел c для оценки этого ограничения и целевой функции.

import numpy as np
from gekko import GEKKO 
m = GEKKO(remote=False)
def test_function(x):
    return np.dot(x, x)
ig = [1, 5, 5, 1] # initial guess
A = np.array([m.Var(value=ig[i],lb=0,ub=10000,name='a'+str(i)) \
              for i in range(4)])
m.Equation(test_function(A)>2500)
m.Equation(test_function(A)<10000)
m.Minimize(test_function(A))
m.solve()
# extract values to get a numerical solution of test_function
A_sol = [A[i].value[0] for i in range(4)]
print(test_function(A_sol))
# get the objective function value from the solver
print(m.options.OBJFCNVAL)
# print variables
print (A)

Результаты скрипта приведены ниже. Если вы используете print(test_function(A_sol)), он печатает символьное выражение c, которое Gekko использует для поиска решения. В вашем случае вас может заинтересовать решение цифр c, а не форма символов c.

# results
2499.999999993099
2500.0
[[14.90599615] [32.059495922] [32.059495922] [14.90599615]]

Оба m.options.OBJFCNVAL и вычисление выражения дают один и тот же результат, но немного отличаются, потому что точности станка.

2 голосов
/ 20 января 2020

Способ, которым вы определили нижние границы и целевую функцию, gekko выбирает десятичную с точностью чуть выше 0. Десятичная суть чуть выше нуля удовлетворяет всем заданным вами границам, и именно поэтому цель так низко. Кроме того, если вы сделаете целевую функцию отрицательной, это увеличит ее до 5000. Я не уверен, где вы получили минимальное и максимальное значения, которые вы ожидаете.

...