Линейное ограничение Гуроби

Как проще всего добавить это ограничение в gurobi в Python.

D — заданная матрица с положительными элементами (константа). b - вектор моих переменных. T и K являются заданными константами.

уравнение ограничения


person Wilmer E. Henao    schedule 19.05.2015    source источник
comment
На самом деле, чтобы удалить максимум, мне нужно суммировать только те поля, где \sum_j D_{ij}b_j › T . Но тогда я не уверен, как ввести это в gurobi.   -  person Wilmer E. Henao    schedule 19.05.2015


Ответы (2)


Gurobi добавил поддержку Max, Min, Abs, And и Or в версии 7.0. См. документ Gurobi для model.addGenConstrMax по адресу http://www.gurobi.com/documentation/7.0/refman/py_model_addgenconstrmax.html.

Таким образом, теперь можно закодировать более простое решение:

Dmatrix = [[1,2], [3,4], [5,6]]                                          
m = grb.Model("test_max_constraint")

M = 3
N = 2

T = 20.0 #Const
K = 15 #Const

b = {}
for j in range(N):
    b[j] = m.addVar(name='b_'+str(j))

maxterm = {}
sumterm = {}
for i in range(M):
    maxterm[i] = m.addVar(name='maxvar_'+str(i))
    sumterm[i] = m.addVar(name='sumvar_'+str(i))

m.update() #integrate the b variables

#By looping twice, explicity create the individual terms
for i in range(M):
    sum_terms = 0
    for j in range(N):
        sum_terms += Dmatrix[i][j]*b[j]
    m.addConstr(sumterm[i] == sum_terms, 'sumterm' + str(i))
    m.addGenConstrMax(maxterm[i], [sumterm[i]], T, 'maxTsum' + str(i))

m.addConstr(grb.quicksum([maxterm[i] for i in range(M)]) >= K,  "Maxterms_GT_K_Constraint")

m.update()
m.write('gurmax.lp')

Получается модель:

\ Model test_max_constraint
\ LP format - for model browsing. Use MPS format to capture full model detail.
Minimize

Subject To
 sumterm0: - b_0 - 2 b_1 + sumvar_0 = 0
 sumterm1: - 3 b_0 - 4 b_1 + sumvar_1 = 0
 sumterm2: - 5 b_0 - 6 b_1 + sumvar_2 = 0
Maxterms_GT_K_Constraint: maxvar_0 + maxvar_1 + maxvar_2 >= 15
Bounds
General Constraints
 maxTsum0: maxvar_0 = MAX ( sumvar_0 , 20 )
 maxTsum1: maxvar_1 = MAX ( sumvar_1 , 20 )
 maxTsum2: maxvar_2 = MAX ( sumvar_2 , 20 )
End
person Rich L    schedule 23.01.2017
comment
Спасибо, что обратили на это мое внимание. И добро пожаловать в stackoverflow! - person Wilmer E. Henao; 26.01.2017

Вот один из способов сделать это. Обратите внимание, что, поскольку термин max() немного сложен, я не использую понимание списка, полагаясь вместо этого на цикл по индексам. (У меня нет Gurobi под рукой, чтобы проверить следующее.)

from gurobipy import *

Dmatrix = [[1,2], [3,4], [5,6]]
mod = Model("test_max_constraint")

M = 3
N = 2

T = 20 #Const
K = 15 #Const

for j in range(N):
    b[j] = model.addVar(name='b_'+str(j))

mod.update() #integrate the b variables

#By looping twice, explicity create the individual terms
maxterms = []
for i in range(M):
    current_term = 0
    for j in range(N):
        current_term += Dmatrix[i][j]*b[j]
    current_term = max(current_term-T,0)

    maxterms.append(current_term)
#A list called 'maxterms' is now ready. Add a constraint summing over these terms.

mod.addConstr( quicksum(maxterms) > K,  "Maxterms_GT_K_Constraint")

Надеюсь, это поможет вам двигаться вперед.

person Ram Narasimhan    schedule 19.05.2015
comment
Спасибо. Интересно видеть в вашем решении, что gurobi может обрабатывать функцию max в рамках ограничения. Я пытался разложить его с помощью фиктивных переменных. - person Wilmer E. Henao; 20.05.2015
comment
@WilmerE.Henao Обратите внимание, что всю работу выполняет Python. Раздел кода max() — это чистый Python. Только когда мы доходим до addConstr, мы вызываем функциональность Gurobi. - person Ram Narasimhan; 20.05.2015
comment
Я пошел дальше и подключил его к машине. Эта строка выдает ошибку, хотя current_term = max(Rlim - current_term, 0.0). TypeError: неупорядоченные типы: float() › LinExpr() - person Wilmer E. Henao; 21.05.2015
comment
Вы получаете ошибку Python, потому что сравниваете два разных типа. Попробуйте type(Rlim), чтобы увидеть, какой это тип. Чтобы иметь возможность сравнивать с 0.0, вам, возможно, придется сначала выполнить float(), а затем сравнить. - person Ram Narasimhan; 21.05.2015
comment
К сожалению, это решение фатально ошибочно. Эта строка:‹br/›current_term = max(current_term-T,0)‹br/› не имеет смысла брать максимальное значение переменной gurobi или LinExpr. Чтобы исправить это, мы можем добавить дополнительные переменные и ограничения gurobi, чтобы модель использовала максимальное значение данного выражения. ‹br/› Однако в Gurobi 7.0 теперь поддерживается ограничение Max. Смотрите мое решение здесь. - person Rich L; 24.01.2017