当前位置:   article > 正文

【Gurobi】学习笔记 | (二)Model Part1 适用于Python_gurobi model

gurobi model

在这里插入图片描述

本文章参考Gurobi官方手册,内容上为更适合入门者学习,有所删减。

Model是Gurobi中最重要的对象,其包含许多常用方法,包括optimize优化模型、printStats打印关于模型的统计信息、printAttr打印属性值、write将有关模型的信息写入文件、addVar添加新变量、addVars添加多个新变量、addMVar添加Numpy变量、addConstr添加新约束和addConstrs添加多个新约束等。

首先还是老规矩,提醒大家先调用gurobipy的库。

下载和调用gurobipy库

进入Python环境,下载名为“gurobi”的软件包,并且在每次使用Gurobi求解时,需要引入这个软件包。


from gurobipy import *

  • 1
  • 2
  • 3

Model()

  • 语句:Model( 'name', env=defaultEnv )
  • 功能:模型构造函数
  • 输入:新模型的名称、环境(有默认参数,可不输入)
  • 输出:新的模型对象,不包含任何变量和约束
  • 说明:新模型的名称将被存储为ASCII码的字符串,因此不允许出现非ASCII码字符,也不允许出现空格
# 示例

m = Model("NewModel") # 定义名为NewModel的模型对象
x0 = m.addVar() # 向模型对象中添加变量x0
# Model ( name="", env=defaultEnv ) 这是一般格式,env可以省略

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Model.addConstr()

  • 语句:Model.addConstr( TempConstr, name='' )
  • 功能:为模型添加约束
  • 输入:TempConstr作为第一个参数(下面有解释),第二个参数是可选参数,为约束名称
  • 输出:新的约束对象
  • 说明:新模型的名称将被存储为ASCII码的字符串,因此不允许出现非ASCII码字符,也不允许出现空格;一个约束只能有一个比较运算符,虽然1 <= x + y <= 2看起来很像一个约束,但是Model.addConstr()方法不会接受
# 示例

model.addConstr(x + y <= 2.0, "c1")
model.addConstr(x*x + y*y <= 4.0, "qc0")
model.addConstr(x + y + z == [1, 2], "rgc0")
model.addConstr(A @ t >= b)
model.addConstr(z == and_(x, y, w), "gc0")
model.addConstr(z == min_(x, y), "gc1")
model.addConstr((w == 1) >> (x + y <= 1), "ic0")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

TempConstr

  • 功能:Gurobi临时约束对象,用于创建各种不同类型的约束
    • 线性约束:(不)等号两端可以是线性表达式对象、变量对象或者常量,不能都是常量
    • 范围线性约束:“线性表达式 == [常量1, 常量2]”的形式,说明线性表达式的值在区间[常量1, 常量2]
    • 二次约束:(不)等号两端可以是二次表达式对象、线性表达式对象、变量对象或者常量,至少两端之一是二次表达式,否则就是线性约束
    • 线性矩阵约束:(不)等号两端至少有一个是线性矩阵表达式对象
    • 二次矩阵约束:(不)等号两端至少有一个是二次矩阵表达式对象
    • 绝对值约束:“x == abs_(y)”的形式,xy都是变量
    • 逻辑约束:“x == op_(y)”的形式,x是二值变量(即只有两种取值),y是二值变量、二值变量列表或者二值变量元组字典(tupledict,这个后面的内容里会提到,先有个印象就行);op_可以是and_或者 or_
    • 最大或最小约束:“x == op_(y)”的形式,x是变量对象,y可以是变量、变量和常量的列表、或者变量的元组字典;op_min_ 或者max_
    • 指示约束:“(x == b) >>(线性表达式)”的形式,符号>>两端的式子都需要用()括起来。x是二值变量,b01。例如,(x == 1) >> (y + w <= 5)中,当x等于1时,右端的线性约束y + w <= 5必须成立
  • 说明:这个类没有成员函数
# 示例

# 线性约束
x + y <= 1 + z
x + y == 5
# 范围线性约束
x + y + z == [1, 2]
# 二次约束
x*x + y*y <= 3
x*x + y*y <= z*z
# 线性矩阵约束
A @ x <= 1
A @ x == B @ y
# 二次矩阵约束
x @ Q @ y <= 3
x @ Q @ x <= y @ A @ y
# 绝对值约束
x == abs_(y)
# 逻辑约束
x == and_(y)
y == or_(y)
# 最大最小约束
x == min_(y)
x == max_(y)
# 指示约束
(x == 1) >> (y + w <= 5)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 在每一种情况下,一旦使用比较运算符创建一个临时约束对象,就要将这个对象传递给Model.addConstr方法
# 示例

model.addConstr(x + y == 1)
model.addConstr(x + y == [1, 2])
model.addConstr(x*x + y*y <= 1)
model.addConstr(A @ x <= 1)
model.addConstr(x @ A @ x <= 1)
model.addConstr(x == abs_(y))
model.addConstr(x == or_(y, z))
model.addConstr(x == max_(y, z))
model.addConstr((x == 1) >> (y + z <= 5))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Model.addConstrs()

  • 语句:Model.addConstrs ( generator, name="" )
  • 功能:添加多个约束
  • 输入:Python生成器,例如(x[i] <= 1 for i in range(4))作为第一个参数,第二个参数是可选参数,为约束名称
  • 输出:一组约束,Constr对象的一个字典
  • 说明:m.addConstrs((x[i] <= 1 for i in range(4)), name='c')这个式子意味着同时添加4个约束,其中第一个约束与变量x[0]有关,即x[0] <= 1,该约束名为c[0],以此类推;约束名可以省略,但如果给定约束名称参数,那生成器表达式就一定要放在括号里
# 示例

m.addConstrs((x[i,j] == 0 	for i in range(4)
							for j in range(4)
							if i != j), name='c')
# 第一个约束是 x[0,1] == 0, name='c[0,1]'

model.addConstrs(x.sum(i, '*') <= capacity[i] for i in range(5))
model.addConstrs(x[i] + x[j] <= 1 for i in range(5) for j in range(5))
model.addConstrs(x[i]*x[i] + y[i]*y[i] <= 1 for i in range(5))
model.addConstrs(x.sum(i, '*') == [0, 2] for i in [1, 2, 4])
model.addConstrs(z[i] == max_(x[i], y[i]) for i in range(5))
model.addConstrs((x[i] == 1) >> (y[i] + z[i] <= 5) for i in range(5))

# 上面这几个约束都没有带括号,是因为他们并没有名称参数

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Model.addGenConstrXxx()

上面我们介绍了基本约束的构造,Gurobi接受一些额外的约束类型,我们将其统称为一般(函数)约束。这些问题通常不会由求解器直接处理。相反,它们是通过预先转换为从上面列出的基本类型中选择的约束(和变量)。在某些情况下,产生的约束或原始约束在数学上是等价的;在其他情况下,它们是近似。如果这些约束出现在您的模型中,但是如果您更喜欢自己使用基本的约束类型来重新构造它们,那么您当然可以这样做。但是,请注意,Gurobi有时可以利用模型中其他约束中包含的信息来构建比您可能创建的更有效的公式。

上面这段话不理解也没关系,大致意思就是,有一些函数约束,Gurobi也能直接构造,比如ln(x) <= 5,我们前面学过的构造方式里并没有包括这种约束。在求解上,可能是等价求解,也有可能是近似求解。如果你很牛,可以自己通过基本的约束形式把这类约束表征出来,当然也可以,但是Gurobi既然帮我们考虑了,那我们可就直接拿来用了哈哈哈哈。

Model.addGenConstrMax()

  • 语句:addGenConstrMax ( resvar, vars, constant=None, name="" )
  • 功能:构造一个最大值约束(是不是感觉上面学过,没错,你也可以用max_函数来构造)
  • 输入:resvar一个变量,其值将等于其他变量的最大值;vars变量列表或变量的tupledict字典;constant在最大操作中的常数,浮点数,是个可选参数;name老朋友就不多介绍了
# 示例

# x5 = max(x1, x3, x4, 2.0)
model.addGenConstrMax(x5, [x1, x3, x4], 2.0, "maxconstr")
# overloaded forms 下面两种哪个都行,是不是感觉上面的方法更简单呢
model.addConstr(x5 == max_([x1, x3, x4], constant=2.0), name="maxconstr")
model.addConstr(x5 == max_(x1, x3, x4, constant=2.0), name="maxconstr")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Model.addGenConstrMin()

和上面的方法一样,就不介绍了

Model.addGenConstrAbs()

  • 语句:addGenConstrAbs ( resvar, argvar, name="" )
  • 功能:添加一个绝对值约束,当然也可以使用abs_函数来定义这个约束
  • 输入:argvar将要取绝对值的变量
# 示例

# x5 = abs(x1)
model.addGenConstrAbs(x5, x1, "absconstr")
# overloaded form
model.addConstr(x5 == abs_(x1), name="absconstr")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Model.addGenConstrAnd()

  • 语句:addGenConstrAnd ( resvar, vars, name="" )
  • 功能:等同于and_函数定义的约束,vars变量列表中的变量必须都为1时,其值才为1,否则为0
# 示例

# x5 = and(x1, x3, x4)
model.addGenConstrAnd(x5, [x1, x3, x4], "andconstr")
# overloaded forms
model.addConstr(x5 == and_([x1, x3, x4]), "andconstr")
model.addConstr(x5 == and_(x1, x3, x4), "andconstr")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Model.addGenConstrOr()

  • 语句:addGenConstrOr ( resvar, vars, name="" )
  • 功能:与or_函数定义的约束一致
# 示例

# x5 = or(x1, x3, x4)
model.addGenConstrOr(x5, [x1, x3, x4], "orconstr")
# overloaded forms
model.addConstr(x5 == or_([x1, x3, x4]), "orconstr")
model.addConstr(x5 == or_(x1, x3, x4), "orconstr")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Model.addGenConstrNorm()

  • 语句:addGenConstrNorm ( resvar, vars, which, name="" )
  • 功能:向量范数约束
  • 输入:resvar一个变量,其值将等于其他变量的最大值;vars变量列表或变量的tupledict字典或一维的MVarwhich范数级别,浮点数;name老朋友就不多介绍了
# 示例

 x5 = 2-norm(x1, x3, x4)
model.addGenConstrNorm(x5, [x1, x3, x4], 2.0, "normconstr")

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrIndicator()

我觉得这个参数太多,不如自己建立指示符约束来的舒服

Model.addGenConstrPWL()

  • 语句:addGenConstrPWL ( xvar, yvar, xpts, ypts, name="" )
  • 功能:分段线性约束
  • 输入:xvar变量x;yvar变量y;xpts定义分段线性函数点的x,必须是单调非递减序列;ypts与前一个参数意义一致
# 示例

gc = model.addGenConstrPWL(x, y, [0, 1, 2], [1.5, 0, 3], "myPWLConstr")

  • 1
  • 2
  • 3
  • 4

Model.addGenConstrPoly()

  • 语句:addGenConstrPoly ( xvar, yvar, p, name="", options="" )
  • 功能:构建多项式函数约束
  • 输入:p多项式函数的系数,从最高幂的系数开始,options是个可选参数,因为多项式是根据分段线性约束近似来的,这个参数能够对近似约束进行限制
# 示例

# y = 2 x^3 + 1.5 x^2 + 1
gc = model.addGenConstrPoly(x, y, [2, 1.5, 0, 1])

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrExp()

  • 语句:addGenConstrExp ( xvar, yvar, name="", options="" )
  • 功能:构建自然指数函数约束
  • 与上一个方法很像,就不多赘述了,直接看示例
# 示例

# y = exp(x)
gc = model.addGenConstrExp(x, y)

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrExpA()

  • 语句:addGenConstrExpA ( xvar, yvar, a, name="", options="" )
  • 功能:构建指数函数约束
  • 输入:a很显然是底数啦
# 示例

# y = 3^x
gc = model.addGenConstrExpA(x, y, 3.0, "expa")

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrLog()

  • 语句:addGenConstrLog ( xvar, yvar, name="", options="" )
  • 功能:构建ln函数
# 示例

# y = ln(x)
gc = model.addGenConstrLog(x, y)

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrLogA()

  • 语句:addGenConstrLogA ( xvar, yvar, a, name="", options="" )
  • 功能:构建log函数,是不是构建方式都理解了哈哈哈哈和前面都是一样的
# 示例

# y = log10(x)
gc = model.addGenConstrLogA(x, y, 10.0, "log10", "FuncPieces=-1 FuncPieceError=1e-5")

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrLogistic()

  • 语句:addGenConstrLogistic ( xvar, yvar, name="", options="" )
  • 功能:构建逻辑函数,其约束为 y = 1 1 + e − x y = \frac{1}{1+e^{-x}} y=1+ex1
# 示例

# y = 1 / (1 + exp(-x))
gc = model.addGenConstrLogistic(x, y)

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrPow()

  • 语句:addGenConstrPow ( xvar, yvar, a, name="", options="" )
  • 功能:构建幂指数约束
# 示例

# y = x^3.5
gc = model.addGenConstrPow(x, y, 3.5, "gf", "FuncPieces=1000")

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrSin()

  • 语句:addGenConstrSin ( xvar, yvar, name="", options="" )
  • 功能:构建sin函数
# 示例

# y = sin(x)
gc = model.addGenConstrSin(x, y)

  • 1
  • 2
  • 3
  • 4
  • 5

Model.addGenConstrCos()

和上面一样

Model.addGenConstrTan()

和上面一样

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/1015637
推荐阅读
相关标签
  

闽ICP备14008679号