文章目录
- Gurobi 变量声明:全面指南与示例
- gurobi声明变量的数学含义
- 整数变量(Integer Variable)
- 定义
- 数学表示
- 示例
- 二元变量(Binary Variable)
- 定义
- 数学表示
- 示例
- 连续变量(Continuous Variable)
- 定义
- 数学表示
- 示例
- 半连续变量(Semi-Continuous Variable)
- 定义
- 数学表示
- 示例
- 1. 正数区间的半连续变量
- 2. 负数区间的半连续变量
- 3. 跨越负数和正数区间的半连续变量
- 总结
- 半整数变量(Semi-Integer Variable)
- 定义
- 数学表示
- 示例
- Gurobi 变量类型和代码解析
- 1. Gurobi 变量类型概述
- 2. Gurobi 中变量的声明
- 2.1 声明单个变量
- 2.1.1 声明连续变量(Continuous Variable)
- 2.1.2 声明二元变量(Binary Variable)
- 2.1.3 声明整数变量(Integer Variable)
- 2.1.4 声明半连续变量(Semi-continuous Variable)
- 2.1.5 声明半整数变量(Semi-integer Variable)
- 2.2 批量变量声明
- 2.2.1 声明一维数组变量
- 2.2.2 声明二维数组变量
- 2.2.3 使用字典方式声明变量
- 2.2.4 使用条件表达式声明变量
- 2.3 多种变量类型的混合声明
- 3. Gurobi 变量的特殊属性设置
- 3.1 设置初始值(Start Value)
- 3.2 设置目标系数(Objective Coefficient)
- 3.3 设置变量优先级(Branching Priority)
- 3.4 设置变量标签(Tagging Variables)
Gurobi 变量声明:全面指南与示例
Gurobi 是一个功能强大的优化求解器,在其 Python 接口中,变量声明是模型构建的重要步骤。基于官方 Python 帮助文档,Gurobi 中变量的所有类型及声明方式.
gurobi声明变量的数学含义
整数变量(Integer Variable)
定义
整数变量是指取值只能为整数的变量。
数学表示
设
x
x
x 为一个整数变量,则:
x
∈
Z
x \in \mathbb{Z}
x∈Z
这意味着
x
x
x 的取值必须是整数,如$ -2, -1, 0, 1, 2, …)。
示例
假设某公司只能雇佣整数数量的工人,设
x
x
x 为工人数,则:
x
∈
Z
x \in \mathbb{Z}
x∈Z
在 Gurobi 中,这可以通过以下代码来实现:
x = model.addVar(vtype=GRB.INTEGER, name="x")
该代码声明了一个名称为 x
的整数变量。
二元变量(Binary Variable)
定义
二元变量是一种特殊的整数变量,它只能取 0 或 1 两个值,通常用于表示某个选择或决策(如开/关、是/否)。
数学表示
设
y
y
y 为一个二元变量,则:
y
∈
{
0
,
1
}
y \in \{0, 1\}
y∈{0,1}
这意味着
y
y
y 只能取值 0 或 1。
示例
假设某公司决定是否启动一个项目,设
y
y
y 为项目启动决策变量,则:
y
∈
{
0
,
1
}
y \in \{0, 1\}
y∈{0,1}
在 Gurobi 中,这可以通过以下代码来实现:
y = model.addVar(vtype=GRB.BINARY, name="y")
该代码声明了一个名称为 y
的二元变量。
连续变量(Continuous Variable)
定义
连续变量可以在给定的区间内取任何实数值。
数学表示
设
z
z
z 为一个连续变量,其取值范围为
[
l
,
u
]
[l, u]
[l,u],则:
z
∈
[
l
,
u
]
z \in [l, u]
z∈[l,u]
这意味着
z
z
z 可以在
l
l
l 到
u
u
u 之间取任意值。
示例
假设某公司可以生产任意数量的产品(可以是小数),设
z
z
z 为生产数量,则:
z
∈
[
0
,
∞
)
z \in [0, \infty)
z∈[0,∞)
在 Gurobi 中,这可以通过以下代码来实现:
z = model.addVar(vtype=GRB.CONTINUOUS, lb=0, name="z")
该代码声明了一个名称为 z
的连续变量,并设置其下限为0。
半连续变量(Semi-Continuous Variable)
定义
半连续变量要么取值为零,要么在一个指定的区间内取值,无论这个区间是正的、负的还是跨越负数和正数。
数学表示
设
x
x
x 为一个半连续变量,其取值范围为
[
l
,
u
]
[l, u]
[l,u],则:
x
∈
{
0
}
∪
[
l
,
u
]
x\in \{0\}\cup [l,u]
x∈{0}∪[l,u]
这意味着
x
x
x 可以取值为 0,或者取值在
l
l
l 到
u
u
u 之间(无论
l
l
l 和
u
u
u 是否为正或负)。
示例
1. 正数区间的半连续变量
如果 l l l 和 u u u 都为正数(如 l = 100 l = 100 l=100, u = 500 u = 500 u=500),则该半连续变量要么为 0,要么在 [100, 500] 之间。
x = model.addVar(vtype=GRB.SEMICONT, lb=100, ub=500, name="x")
2. 负数区间的半连续变量
如果 l l l 和 u u u 都为负数(如 l = − 500 l = -500 l=−500, u = − 100 u = -100 u=−100),则该半连续变量要么为 0,要么在 [-500, -100] 之间。
x = model.addVar(vtype=GRB.SEMICONT, lb=-500, ub=-100, name="x")
3. 跨越负数和正数区间的半连续变量
如果 l l l 为负数且 u u u 为正数(如 l = − 100 l = -100 l=−100, u = 100 u = 100 u=100),则该半连续变量要么为 0,要么在 [-100, 100] 之间。
x = model.addVar(vtype=GRB.SEMICONT, lb=-100, ub=100, name="x")
总结
半连续变量的区间范围不受限于正数,也可以是负数或跨越负数和正数的区间。关键是半连续变量要么取值为0,要么取值于指定区间内。
半整数变量(Semi-Integer Variable)
定义
半整数变量要么取值为零,要么在一个特定的整数区间内取值。
数学表示
设
y
y
y 为一个半整数变量,其取值范围为
[
l
,
u
]
[l, u]
[l,u],则:
y
∈
{
0
}
∪
{
l
,
l
+
1
,
…
,
u
}
y \in \{0\} \cup \{l, l+1, \dots, u\}
y∈{0}∪{l,l+1,…,u}
这意味着
y
=
0
y = 0
y=0 或
l
≤
y
≤
u
l\le y\le u
l≤y≤u 且
y
y
y 为整数。
示例
假设某公司只能购买特定数量的设备,购买数量要么为 0,要么为 10 到 50 之间的整数个。设变量
y
y
y 表示购买数量,则:
y
∈
{
0
}
∪
{
10
,
11
,
…
,
50
}
y \in \{0\} \cup \{10, 11, \dots, 50\}
y∈{0}∪{10,11,…,50}
在 Gurobi 中,这可以通过以下代码来实现:
y = model.addVar(vtype=GRB.SEMIINT, lb=10, ub=50, name="y")
该代码声明了一个名称为 y
的半整数变量,要求其取值为 0 或在 10 到 50 之间的整数。
Gurobi 变量类型和代码解析
1. Gurobi 变量类型概述
在 Gurobi 中,变量的类型通过 vtype
参数指定,以下是 Gurobi 支持的变量类型:
- : 连续变量,可以取任意实数值。默认类型。
- : 二元变量,只能取0或1。
- : 整数变量,只能取整数值。
- : 半连续变量,可以取0,或者在一个给定范围内取连续值。
- : 半整数变量,可以取0,或者在一个给定范围内取整数值。
2. Gurobi 中变量的声明
在 Gurobi 中,变量声明主要通过 ()
(声明单个变量)或 ()
(批量声明变量)方法来实现
2.1 声明单个变量
2.1.1 声明连续变量(Continuous Variable)
x = model.addVar(vtype=GRB.CONTINUOUS, name="x")
-
解释: 声明一个连续变量
x
,它可以取任意实数值。 - vtype=: 指定变量类型为连续变量(默认类型,可以省略)。
-
name=“x”: 为变量命名为
x
,便于后续引用。
示例:声明一个表示生产数量的连续变量 x
,并设置下限为0,上限为无穷大(默认上限)。
x = model.addVar(lb=0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="x")
# 变量 x 表示生产数量,下限为 0,上限为无穷大,是一个连续变量。
2.1.2 声明二元变量(Binary Variable)
z = model.addVar(vtype=GRB.BINARY, name="z")
-
解释: 声明一个二元变量
z
,它只能取值0或1。 - vtype=: 指定变量类型为二元变量。
-
name=“z”: 为变量命名为
z
。
示例:声明一个表示是否选择某个项目的二元变量 z
。
z = model.addVar(vtype=GRB.BINARY, name="z")
# 变量 z 表示是否选择某个项目,z 只能取值 0 或 1。
2.1.3 声明整数变量(Integer Variable)
y = model.addVar(vtype=GRB.INTEGER, name="y")
-
解释: 声明一个整数变量
y
,它只能取整数值。 - vtype=: 指定变量类型为整数变量。
-
name=“y”: 为变量命名为
y
。
示例:声明一个表示车辆数量的整数变量 y
,并设置上下限。
y = model.addVar(lb=0, ub=10, vtype=GRB.INTEGER, name="y")
# 变量 y 表示车辆数量,下限为 0,上限为 10,是一个整数变量。
2.1.4 声明半连续变量(Semi-continuous Variable)
sc = model.addVar(vtype=GRB.SEMICONT, lb=10, name="sc")
-
解释: 声明一个半连续变量
sc
,它可以取值0,或者在给定范围内取连续值。 - vtype=: 指定变量类型为半连续变量。
- lb=10: 指定变量取值的下限为10(非零时)。
-
name=“sc”: 为变量命名为
sc
。
示例:声明一个表示生产线最小开工量的半连续变量 sc
,要么为0,要么在10到100之间取值。
sc = model.addVar(vtype=GRB.SEMICONT, lb=10, ub=100, name="sc")
# 变量 sc 表示生产线最小开工量,取值为 0,或者在 10 到 100 之间取连续值。
2.1.5 声明半整数变量(Semi-integer Variable)
si = model.addVar(vtype=GRB.SEMIINT, lb=1, name="si")
-
解释: 声明一个半整数变量
si
,它可以取值0,或者在给定范围内取整数值。 - vtype=: 指定变量类型为半整数变量。
- lb=1: 指定变量取值的下限为1(非零时)。
-
name=“si”: 为变量命名为
si
。
示例:声明一个表示机器运转次数的半整数变量 si
,要么为0,要么在1到50之间取整数值。
si = model.addVar(vtype=GRB.SEMIINT, lb=1, ub=50, name="si")
# 变量 si 表示机器运转次数,取值为 0,或者在 1 到 50 之间取整数值。
每个变量的声明主要包括类型、上下界、还有命名
2.2 批量变量声明
批量声明变量可以使用 ()
方法。该方法允许创建多个变量,并支持多维数组、字典等不同的数据结构。
2.2.1 声明一维数组变量
x = model.addVars(5, vtype=GRB.CONTINUOUS, name="x")
-
解释: 声明一个包含5个连续变量的数组
x
,每个变量的下标从0到4 - vtype=: 指定变量类型为连续变量。
-
name=“x”: 为变量数组命名为
x
。
示例:声明5个连续变量 x[0]
到 x[4]
,用于表示不同产品的产量。
x = model.addVars(5, vtype=GRB.CONTINUOUS, lb=0, name="x")
# 变量 x[0] 到 x[4] 表示不同产品的产量,是连续变量,每个变量的下限为 0。
2.2.2 声明二维数组变量
x = model.addVars(3, 4, vtype=GRB.BINARY, name="x")
-
解释: 声明一个3x4的二元变量矩阵
x
。 - vtype=: 指定变量类型为二元变量。
-
name=“x”: 为变量矩阵命名为
x
。
示例:声明一个3x4的二元变量矩阵 x[i, j]
,用于表示不同资源在不同时间的使用情况
x = model.addVars(3, 4, vtype=GRB.BINARY, name="x")
# 变量 x[i, j] 表示不同资源在不同时间的使用情况,是一个 3x4 的二元变量矩阵。
2.2.3 使用字典方式声明变量
x = model.addVars([1, 2, 3], ['A', 'B'], vtype=GRB.INTEGER, name="x")
-
解释: 声明一个键为
(1, 'A')
等组合的整数变量字典x
。 - vtype=: 指定变量类型为整数变量。
-
name=“x”: 为变量字典命名为
x
。
示例:声明一个变量字典 x[i, j]
,其中 i
为1到3的整数,j
为 ‘A’ 或 ‘B’。
x = model.addVars([1, 2, 3], ['A', 'B'], vtype=GRB.INTEGER, name="x")
# 变量字典 x[i, j] 包含 i 为 1 到 3,j 为 'A' 或 'B' 的整数变量。
在代码 x = ([1, 2, 3], ['A', 'B'], vtype=, name="x")
中, 方法用于创建多个变量。参数
[1, 2, 3]
和 ['A', 'B']
分别表示变量的索引集合,Gurobi 会根据这两个集合生成所有可能的组合变量。
- 所有可能的组合类型如下:
-(1, 'A')
-(1, 'B')
-(2, 'A')
-(2, 'B')
-(3, 'A')
-(3, 'B')
- 解释:
Gurobi 会基于索引集合[1, 2, 3]
和['A', 'B']
生成一个 Cartesian Product(笛卡尔积),即将每一个第一个集合中的元素与第二个集合中的每个元素组合起来。
因此,创建了 6 个整数变量,每个变量的索引组合分别是 (1, 'A')
, (1, 'B')
, (2, 'A')
, (2, 'B')
, (3, 'A')
, (3, 'B')
。
- 在代码中的表示:
x[1, 'A'] # 对应组合 (1, 'A')
x[1, 'B'] # 对应组合 (1, 'B')
x[2, 'A'] # 对应组合 (2, 'A')
x[2, 'B'] # 对应组合 (2, 'B')
x[3, 'A'] # 对应组合 (3, 'A')
x[3, 'B'] # 对应组合 (3, 'B')
这些变量都是整数变量 (vtype=
),在模型中被创建并以 “x” 为前缀命名。
2.2.4 使用条件表达式声明变量
x = model.addVars(3, 3, vtype=GRB.BINARY, name="x", ub=lambda i, j
### 2.2.4 使用条件表达式声明变量(续)
在使用 `addVars()` 批量声明变量时,可以通过条件表达式来动态设置变量的属性,例如上下限等。以下是通过 `lambda` 表达式动态设置变量上限的示例。
```python
x = model.addVars(3, 3, vtype=GRB.BINARY, name="x", ub=lambda i, j: 1 if i != j else 0)
-
解释: 声明一个 3x3 的二元变量矩阵
x
,并根据条件动态设置上限(即ub
参数)。 -
lambda i, j: 1 if i != j else 0: 这是一个 lambda 表达式,表示如果
i != j
,则变量上限为 1;否则上限为 0。 - vtype=: 指定变量类型为二元变量。
-
name=“x”: 为变量矩阵命名为
x
。
示例:声明一个 3x3 的二元变量矩阵 x[i, j]
,其中变量 x[i, j]
在 i != j
时可以取值 0 或 1;在 i == j
时,变量只能取值 0。
x = model.addVars(3, 3, vtype=GRB.BINARY, name="x", ub=lambda i, j: 1 if i != j else 0)
# 变量 x[i, j] 是一个 3x3 的二元变量矩阵,当 i != j 时,变量 x[i, j] 可以取值 0 或 1;当 i == j 时,变量 x[i, j] 只能取值 0。
2.3 多种变量类型的混合声明
有时,你可能需要在同一个模型中混合使用不同类型的变量。通过 addVars()
方法,可以同时声明多个类型的变量。
vars = model.addVars(
[(i, j) for i in range(3) for j in range(2)],
vtype=[GRB.BINARY, GRB.INTEGER],
name="vars"
)
-
解释: 通过
addVars()
方法声明一组包含 3x2 个变量的集合,变量类型为二元和整数混合。 - vtype=[, ]: 指定了变量类型的列表,第一个变量为二元变量,第二个变量为整数变量,以此类推。
-
name=“vars”: 为变量集合命名为
vars
。
示例:假设你在解决一个包含不同决策类型的问题,声明一组变量,前两个变量为二元变量(表示某些选择),剩下的为整数变量(表示某些计数)。
vars = model.addVars(
[(i, j) for i in range(3) for j in range(2)],
vtype=[GRB.BINARY, GRB.INTEGER],
name="vars"
)
# 变量集合 vars[i, j] 包含 3x2 个变量,第一个变量是二元变量,第二个变量是整数变量,以此类推。
3. Gurobi 变量的特殊属性设置
除了 vtype
之外,Gurobi 还允许你为变量设置其他一些属性,例如下限 (lb
)、上限 (ub
)、初始值 (start
)、目标系数 (obj
)、变量优先级 (branchpriority
)、标签 (tag
) 等
3.1 设置初始值(Start Value)
x = model.addVar(vtype=GRB.CONTINUOUS, name="x", start=5.0)
-
解释: 声明一个连续变量
x
,并设置其初始值为 5.0。 -
start=5.0: 为变量
x
设置初始值 5.0,表示优化器在开始求解时将x
的值初始化为 5.0。
示例:在求解过程中,优化器会首先尝试使用变量的初始值,这有助于加速求解,特别是当初始值接近最优解时。
x = model.addVar(vtype=GRB.CONTINUOUS, name="x", start=5.0)
# 声明一个连续变量 x,并将其初始值设置为 5.0,优化器将从此初始值开始求解。
3.2 设置目标系数(Objective Coefficient)
x = model.addVar(vtype=GRB.CONTINUOUS, name="x", obj=1.0)
-
解释: 声明一个连续变量
x
,并设置其在线性目标函数中的系数为 1.0 -
obj=1.0: 变量
x
的目标系数为 1.0,表示在目标函数中,x
的贡献是其值乘以1.0。
示例:在求解最大化利润的问题中,目标系数可以用于表示每个变量对总利润的贡献。
x = model.addVar(vtype=GRB.CONTINUOUS, name="x", obj=1.0)
# 声明一个连续变量 x,并将其目标系数设置为 1.0,表示 x 在目标函数中的贡献。
3.3 设置变量优先级(Branching Priority)
x = model.addVar(vtype=GRB.BINARY, name="x", branchpriority=10)
-
解释: 声明一个二元变量
x
,并设置其分支优先级为 10 -
branchpriority=10: 变量
x
的分支优先级为 10,值越大,优化器在分支定界过程中越优先考虑该变量
示例:在某些复杂问题中,设置分支优先级可以帮助优化器更快找到最优解。
x = model.addVar(vtype=GRB.BINARY, name="x", branchpriority=10)
# 声明一个二元变量 x,并将其分支优先级设置为 10,表示在求解过程中优化器将优先处理此变量。
3.4 设置变量标签(Tagging Variables)
x = model.addVar(vtype=GRB.CONTINUOUS, name="x", tag="important")
-
解释: 声明一个连续变量
x
,并为其添加标签important
。 -
tag=“important”: 变量
x
的标签为important
,标签可以用于后续操作中对变量进行分类和筛选。
示例:在大型模型中,标签可以帮助识别特定组的变量,便于后续分析和操作。
x = model.addVar(vtype=GRB.CONTINUOUS, name="x", tag="important")
# 声明一个连续变量 x,并为其添加标签 important,用于后续分类和筛选。