Я пытаюсь привести проблему CVXPY к Python API Gurobi.
Проблема CVXPY заключается в следующем (я опускаю предыдущие определения переменных, поскольку они являются вторичными для моей проблемы. Проверьте комментарии на предмет их типов и форм.):
import cvxpy as cp
import numpy as np
"""
ma, mx, mb, my: type=int
radius: type=float
meas: type=numpy.ndarray, shape=(3, 3)
detp: type=numpy.ndarray, shape=(18, 10000)
state_vecs: type=numpy.ndarray, shape=(3, 3)
weights: type=cvxpy.expressions.variable.Variable, shape=(10000,)
d: type=cvxpy.expressions.variable.Variable, shape=(1,)
"""
ma, mx, mb, my, meas, radius, detp, state_vecs = # Previously defined
weights = cp.Variable(detp.shape[1])
d = cp.Variable(1)
dot = np.inner(state_vecs, meas).flatten()
# Attention to this line:
behaviors = 0.5 * (1 + d * dot / radius)
constrs = [behaviors == detp @ weights, d >= 0, d <= 1, sum(weights) == 1, weights >= 0]
prob = cp.Problem(cp.Maximize(d), constrs)
prob.solve(solver=cp.GUROBI, verbose=True)
Это работает хорошо, но для больших случаев CVXPY съедает всю память и занимает много времени, прежде чем вызвать решатель.
Я сейчас пытаюсь перевести это на API Gurobi:
import gurobipy as gp
import numpy as np
"""
ma, mx, mb, my: type=int
radius: type=float
meas: type=numpy.ndarray, shape=(3, 3)
detp: type=numpy.ndarray, shape=(18, 10000)
state_vecs: type=numpy.ndarray, shape=(3, 3)
weights: type=gurobipy.MVar, shape=(10000,)
d: type=gurobipy.Var, has no attribute shape
"""
ma, mx, mb, my, meas, radius, detp, state_vecs = # Previously defined
prob = gp.Model("LPMModel")
weights = prob.addMVar(shape=detp.shape[1])
d = prob.addVar()
prob.setObjective(d, GRB.MAXIMIZE)
dot = np.inner(state_vecs, meas).flatten()
# So far so good, but now:
behaviors = 0.5 * (1 + d * dot / radius)
prob.addConstr(behaviors == detp @ weights)
prob.addConstr(weights >= 0)
prob.addConstr(weights.sum() == 1)
prob.addConstr(d >= 0)
prob.addConstr(d <= 1)
prob.optimize()
Строка после комментария это то, что меня беспокоит. Я намерен умножить каждый элемент dot
на переменную оптимизации d
, которая должна быть максимально увеличена. Интерпретатор выплевывает следующий стек ошибок:
TypeError Traceback (most recent call last)
var.pxi in gurobipy.Var.__mul__()
TypeError: only size-1 arrays can be converted to Python scalars
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
linexpr.pxi in gurobipy.LinExpr.__imul__()
TypeError: only size-1 arrays can be converted to Python scalars
During handling of the above exception, another exception occurred:
GurobiError Traceback (most recent call last)
<ipython-input-135-5b4ee6d552a9> in <module>
----> 1 grb = lpm.grb_local_model(st)
~/lpm.py in grb_local_model(state_vecs, detp, meas, verb)
97
98 dot = np.inner(state_vecs, meas).flatten()
---> 99 behaviors = 0.5 * (1 + d * dot / radius)
100
101 prob.addConstr(behaviors == detp @ weights)
var.pxi in gurobipy.Var.__mul__()
linexpr.pxi in gurobipy.LinExpr.__imul__()
linexpr.pxi in gurobipy.LinExpr.__mul__()
linexpr.pxi in gurobipy.LinExpr._mul()
GurobiError: Invalid argument to LinExpr multiplication
И это моя проблема.
Что я упускаю?
(Любые предложения по улучшению кода в другом месте также приветствуются.)