当前位置: 首页 > news >正文

gurobi中引入松弛变量和剩余变量的用法

文章目录

  • 1. 松弛变量:用于“≤”不等式约束
    • 数学表达式
  • 2. 剩余变量:用于“≥”不等式约束
    • 数学表达式
  • 3. 目标函数中的松弛变量
    • 数学表达式
  • 4. Gurobi中的实现
    • 对于“≤”不等式的松弛变量:
    • 对于“≥”不等式的剩余变量:
  • 5. 总结

  • 在Gurobi中,松弛变量(Slack Variables)和剩余变量(Surplus Variables)广泛用于将不等式约束转换为等式约束,或者在目标函数中调整问题的可行性与最优性。例如,在线性规划(LP)中,某些求解方法(如单纯形法)要求所有的约束条件都是等式,此时可以通过引入松弛变量将不等式约束转换为等式。==
  • 单纯性法数学原理和思想可以参考【运筹学】单纯形法总结 ( 单纯形法原理 | 单纯形法流程 | 单纯形表 | 计算检验数 | 最优解判定 | 入基变量 | 出基变量 | 方程组同解变换 ) ★★★
  • 对于标准线性规划问题,具体数学表达和变换情况可以参考【运筹学】线性规划数学模型标准形式 ( 标准形式 | 目标函数转化 | 决策变量转化 | 约束方程转化 | 固定转化顺序 | 标准形式转化实例 ) ★★

1. 松弛变量:用于“≤”不等式约束

将“≤”类型的约束转换为等式约束,此时,松弛变量 s 表示约束的剩余“空间”,即在达到等式 b 时,当前的变量组合还差多少。

数学表达式

假设有一个不等式约束:
a 1 x 1 + a 2 x 2 ≤ b a_1x_1 + a_2x_2 \leq b a1x1+a2x2b
可以引入一个松弛变量 s ≥ 0 s \geq 0 s0,使其转换为等式:
a 1 x 1 + a 2 x 2 + s = b a_1x_1 + a_2x_2 + s = b a1x1+a2x2+s=b

2. 剩余变量:用于“≥”不等式约束

剩余变量类似于松弛变量,但用于将“≥”类型的约束转换为等式约束。剩余变量表示的是超过所需量的部分。

数学表达式

假设有一个不等式约束:
a 1 x 1 + a 2 x 2 ≥ b a_1x_1 + a_2x_2 \geq b a1x1+a2x2b
可以引入一个剩余变量 s ≥ 0 s \geq 0 s0,将其转换为等式:
a 1 x 1 + a 2 x 2 − s = b a_1x_1 + a_2x_2 - s = b a1x1+a2x2s=b
这里,剩余变量 s s s 表示超过要求的量。

3. 目标函数中的松弛变量

在某些优化问题中,可能会允许某些约束条件被“违反”,但需要引入惩罚措施。这时,松弛变量可以用于表示这种违约程度,并将其加入到目标函数中。

数学表达式

假设我们允许约束 a 1 x 1 + a 2 x 2 ≤ b a_1x_1 + a_2x_2 \leq b a1x1+a2x2b 被“违反”,可以引入一个松弛变量 s ≥ 0 s \geq 0 s0
a 1 x 1 + a 2 x 2 + s = b a_1x_1 + a_2x_2 + s = b a1x1+a2x2+s=b
然后将松弛变量 s s s 的惩罚项加入到目标函数中。例如,目标是最小化总成本:
Minimize  Z = c 1 x 1 + c 2 x 2 + p ⋅ s \text{Minimize } Z = c_1x_1 + c_2x_2 + p \cdot s Minimize Z=c1x1+c2x2+ps
其中, p p p 是松弛变量的惩罚系数,表示违反约束的代价。当问题的解空间非常紧张,或者为了确保可行解的存在时,我们可以允许约束条件的适度放松。此时通过目标函数中的惩罚项来权衡违约程度与最优解的关系。

4. Gurobi中的实现

无论是松弛变量还是剩余变量,它们在Gurobi中的实现方式是类似的。以下是具体的代码示例:

对于“≤”不等式的松弛变量:

from gurobipy import Model, GRB# 创建模型
m = Model()# 添加变量
x1 = m.addVar(name="x1")
x2 = m.addVar(name="x2")
s = m.addVar(name="slack", lb=0)  # 松弛变量# 添加约束:a1*x1 + a2*x2 <= b  =>  a1*x1 + a2*x2 + s = b
m.addConstr(2*x1 + 3*x2 + s == 10)# 设置目标函数
m.setObjective(x1 + 2*x2 + 1000*s, GRB.MINIMIZE)# 求解
m.optimize()# 输出结果
for v in m.getVars():print('%s %g' % (v.varName, v.x))print('Obj: %g' % m.objVal)

这段Gurobi代码表示一个线性优化问题。将其对应的数学表达式写为一个标准的线性规划问题。该数学问题可以总结为以下形式:
Minimize  Z = x 1 + 2 x 2 + 1000 s Subject to  2 x 1 + 3 x 2 + s = 10 x 1 ≥ 0 , x 2 ≥ 0 , s ≥ 0 \begin{align*} \text{Minimize } & \quad Z = x_1 + 2x_2 + 1000s \\ \text{Subject to } & \quad 2x_1 + 3x_2 + s = 10 \\ & \quad x_1 \geq 0, \quad x_2 \geq 0, \quad s \geq 0 \end{align*} Minimize Subject to Z=x1+2x2+1000s2x1+3x2+s=10x10,x20,s0
其中, x 1 x_1 x1 x 2 x_2 x2是决策变量,(s) 是松弛变量。决策变量 (x_1) 和 (x_2) 也默认是非负的(在Gurobi中默认情况下变量是非负的), (s) 是松弛变量,它必须是非负的。在这个问题中,松弛变量 (s) 用来将原本的“≤”约束转换为等式,同时它在目标函数中具有较大的惩罚系数 (1000),表明我们希望尽量减少 (s) 的值。
在这里插入图片描述

对于“≥”不等式的剩余变量:

from gurobipy import Model, GRB# 创建模型
m = Model()# 添加变量
x1 = m.addVar(name="x1")
x2 = m.addVar(name="x2")
s = m.addVar(name="surplus", lb=0)  # 剩余变量# 添加约束:a1*x1 + a2*x2 >= b  =>  a1*x1 + a2*x2 - s = b
m.addConstr(2*x1 + 3*x2 - s == 10)# 设置目标函数
m.setObjective(x1 + 2*x2 + 1000*s, GRB.MINIMIZE)# 求解
m.optimize()# 输出结果
for v in m.getVars():print('%s %g' % (v.varName, v.x))print('Obj: %g' % m.objVal)

Gurobi代码表示了一个线性优化问题,使用了剩余变量(Surplus Variable)来处理“≥”类型的不等式约束。我们可以将其对应的数学表达式写为一个标准的线性规划问题。该数学问题可以总结为以下形式:
Minimize  Z = x 1 + 2 x 2 + 1000 s Subject to  2 x 1 + 3 x 2 − s = 10 x 1 ≥ 0 , x 2 ≥ 0 , s ≥ 0 \begin{align*} \text{Minimize } & \quad Z = x_1 + 2x_2 + 1000s \\ \text{Subject to } & \quad 2x_1 + 3x_2 - s = 10 \\ & \quad x_1 \geq 0, \quad x_2 \geq 0, \quad s \geq 0 \end{align*} Minimize Subject to Z=x1+2x2+1000s2x1+3x2s=10x10,x20,s0

其中, x 1 x_1 x1 x 2 x_2 x2是决策变量,(s) 是松弛变量。决策变量 (x_1) 和 (x_2) 也默认是非负的(在Gurobi中默认情况下变量是非负的), (s) 是松弛变量,它必须是非负的。 在约束条件中,松弛变量用于将“≤”约束转换为等式,剩余变量用于将“≥”约束转换为等式。在这个问题中,剩余变量 (s) 用来将原本的“≥”约束转换为等式。同时,(s) 在目标函数中具有较大的惩罚系数 (1000),表明我们希望尽量减少 (s) 的值,即希望尽可能满足或超过原本的“≥”约束。在目标函数中,某些优化问题中,可能会允许某些约束条件被“违反”,但需要引入惩罚措施。这时,松弛变量可以用于表示这种违约程度,并将其加入到目标函数中。

在这里插入图片描述

5. 总结

  • 在约束条件中,松弛变量用于将“≤”约束转换为等式,剩余变量用于将“≥”约束转换为等式。
  • 在目标函数中,可能会允许某些约束条件被“违反”,需要引入惩罚措施。这时,松弛变量可以用于表示这种违约程度。

http://www.mrgr.cn/news/6823.html

相关文章:

  • 《断点回归的非参数估计及 Stata 实现》
  • C++ | Leetcode C++题解之第365题水壶问题
  • function call学习之2
  • 基于calico部署k8s集群k8s-1.23.6
  • JAVA之MAC详解以及子线程MDC传递
  • 探索厦门凯酷全科技有限公司抖音小店的实用魅力
  • Redis篇三:在Ubuntu下安装Redis
  • 用序列模型(GPT Bert Transformer等)进行图像处理的调研记录
  • 完美洗牌的秘密(四)——(反)完美洗牌第三定理
  • java nio AsynchronousChannel
  • Spring Boot 的 JDBC API 和 Spring Data JPA
  • 【超入門】用ComfyUI快速套用AnimateDiff工作流生成AI動畫
  • kubernetes k8s Secret 概述与配置讲解
  • 【docker综合篇】关于我用docker搭建了6个应用服务的事
  • Django后端架构开发:构建在线云媒资系统思路解析
  • 编译一个ROS包
  • Qt C++ 屏幕录制 保存mp4
  • DAMA CDGP:论述题真题解析之数据安全篇
  • python进阶语法---异常处理
  • 【访问者模式】设计模式系列:解锁复杂对象结构的秘密武器