【问题标题】:Gurobi linear constraintGurobi 线性约束
【发布时间】:2015-07-31 17:27:21
【问题描述】:

在 Python 中将此约束添加到 gurobi 的最简单方法是什么。

D 是一个给定的矩阵,具有正项(常数)。 b 是我的变量的向量。 T 和 K 是常数。

【问题讨论】:

  • 事实上,为了删除“最大值”,我只需要对 \sum_j D_{ij}b_j > T 的那些框求和。但是我不确定如何在 gurobi 中输入这个。

标签: python optimization constraints gurobi


【解决方案1】:

这是一种方法。请注意,由于 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")

希望这可以帮助您继续前进。

【讨论】:

  • 谢谢。有趣的是,在您的解决方案中,gurobi 可以在约束内处理“max”函数。我试图通过使用虚拟变量来分解它。
  • @WilmerE.Henao 请注意,是 Python 完成了所有工作。代码的 max() 部分是纯 Python 的。只有当我们来到 addConstr 时,我们才会调用 Gurobi 功能。
  • 我继续把它插在机器上。尽管 current_term = max(Rlim - current_term, 0.0),这条线给了我一个错误。 TypeError:不可排序的类型:float() > LinExpr()
  • 您遇到 Python 错误,因为您正在比较两种不同的类型。试试 type(Rlim) 看看它是什么类型。为了能够与 0.0 进行比较,您可能必须先执行 float(),然后再进行比较。
  • 不幸的是,这个解决方案存在致命缺陷。这行:
    current_term = max(current_term-T,0)
    取 gurobi 变量或 LinExpr 的最大值是没有意义的。为了纠正这个问题,我们可以添加额外的 gurobi 变量和约束,以便模型使用给定表达式的最大值。
    但是,在 Gurobi 7.0 中,现在支持 Max 约束。在此处查看我的解决方案。
【解决方案2】:

Gurobi 在 7.0 版中添加了对 Max、Min、Abs、And 和 Or 的支持。请参阅http://www.gurobi.com/documentation/7.0/refman/py_model_addgenconstrmax.html 的 model.addGenConstrMax 的 Gurobi 文档。

所以现在可以编写一个更直接的解决方案:

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

【讨论】:

  • 感谢您提请我注意。欢迎使用 stackoverflow!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多