Доступ к указанным c значениям в оптимальном решении GEKKO - PullRequest
3 голосов
/ 09 мая 2020

В продолжение вопроса, размещенного здесь ранее:

GEKKO - оптимизация в матричной форме

Я замечаю, что могу получить определенные c значения для q ( оптимальное решение), когда я ссылаюсь на них по отдельности:

q [0,1] = [2,5432017412] q [0,2] = [3,7228765674]

Я также могу добавить эти значения по отдельности:

q [0,1] [0] + q [0,2] [0] = 6.2660783086

Однако я не могу использовать функцию суммы для получения значений q. Например, (код: Вывод):

q[0].sum(): (((v1+v2)+v3)+v4)
sum(q[0,:]) : ((((0+v1)+v2)+v3)+v4)
q[0,:].sum(axis=0) : (((v1+v2)+v3)+v4)

Я не уверен, почему sum не может получить доступ к переменным внутри q. Нужно ли мне выполнять какие-либо промежуточные операции на выходе (например, q)? Спасибо,

1 Ответ

2 голосов
/ 09 мая 2020

В массиве numpy объекты gekko хранятся в каждой строке и столбце. Чтобы получить доступ к значению gekko для переменной x, вам нужно получить x.value[0]. Вы можете преобразовать матрицу q в матрицу numpy с помощью

# convert to matrix form
qr = np.array([[q[i,j].value[0] for j in range(4)] for i in range(4)])

Вот полная версия вашего кода, которая проверяет соответствие ограничениям строк и столбцов.

import numpy as np
import scipy.optimize as opt
from gekko import GEKKO
p= np.array([4, 5, 6.65, 12]) #p = prices
pmx = np.triu(p - p[:, np.newaxis]) #pmx = price matrix, upper triangular
m = GEKKO(remote=False)
q = m.Array(m.Var,(4,4),lb=0,ub=10)
# only upper triangular can change
for i in range(4):
    for j in range(4):
        if j<=i:
            q[i,j].upper=0 # set upper bound = 0
def profit(q):
    profit = np.sum(q.flatten() * pmx.flatten())
    return profit
for i in range(4):
    m.Equation(np.sum(q[i,:])<=10)
    m.Equation(np.sum(q[:,i])<=8)
m.Maximize(profit(q))
m.solve()
print(q)
# convert to matrix form
qr = np.array([[q[i,j].value[0] for j in range(4)] for i in range(4)])
for i in range(4):
    rs = qr[i,:].sum()
    print('Row sum ' + str(i) + ' = ' + str(rs))
    cs = qr[:,i].sum()
    print('Col sum ' + str(i) + ' = ' + str(cs))

Результатом этого сценария являются:

[[[0.0] [2.5432017412] [3.7228765674] [3.7339217013]]
 [[0.0] [0.0] [4.2771234426] [4.2660783187]]
 [[0.0] [0.0] [0.0] [0.0]]
 [[0.0] [0.0] [0.0] [0.0]]]
Row sum 0 = 10.000000009899999
Col sum 0 = 0.0
Row sum 1 = 8.5432017613
Col sum 1 = 2.5432017412
Row sum 2 = 0.0
Col sum 2 = 8.00000001
Row sum 3 = 0.0
Col sum 3 = 8.00000002

Имеется небольшое нарушение ограничений из-за допуска решателя. Вы можете настроить допуск решателя с помощью m.options.ATOL=1e-6 на что-то похожее на 1e-8, если вы хотите получить более точный ответ.

...