解决线性规划问题 if 条件

   不论用什么求解器,数学规划模型中一般不支持直接输入 if ... else 条件,也就是说在编写模型代码时,if..else 条件判断中不能含有模型变量。遇到有变量需要做 if 判断的时候,需要做线性化处理。

       线性化的方法很多,既可以通过引入中间变量(辅助变量)的方式实现,一般就是加上大M和一个01变量来实现,也可以直接调用 Gurobi 的 Indicator 约束实现。gurobi原厂也提供了一个示范案例,可以参考 https://support.gurobi.com/hc/en-us/articles/4414392016529-How-do-I-model-conditional-statements-in-Gurobi-

一、举例:

原问题:

  如果 x>y则z=w1;否则 z=w2;

(1)首先,考虑引入0和1变量b:

\\x\geqslant y\Leftrightarrow b=1 \\ x < y\Leftrightarrow b =0

目的是为了实现:当b = 1 时,x ≥ y

(2)  引入大M实现第一步的公式:

x \ge y + 0.001 - M(1-b)\\                                              约束(1)

            约束(2)

b \in \{0,1\}         

同理接下来继续实现:

\\b=1 \rightarrow z = w_1                                              约束(3)

\\ b=0 \rightarrow z = w_2                                              约束(4)

转为:

\\ w_1-M\cdot (1-b)\le z \le w_1 + M\cdot (1-b) \\ w_2-M\cdot b\le z \le w_2 + M\cdot b\\

最判断转为:

x \ge y + 0.001 - M(1-b)\\

x \le y + M\\

 \\ w_1-M\cdot (1-b)\le z \le w_1 + M\cdot (1-b) \\ w_2-M\cdot b\le z \le w_2 + M\cdot b\\

b \in \{0,1\}

 groubi的可以通过指标约束(indicator constraints)实现约束(3)和约束(4):

变量及其上下限:

x,y,z,w1,w2 均为实数,其中

x、y∈[0,5],z,w1,w2无上下限约束

约束为上述的约束(1)~ 约束(4)

二、Gurobi Indicator 用法
Gurobi Indicator 约束用来表达 z = f >> ax<=b 这样的逻辑条件。其中 
(1)z 需要是 0/1 变量, f 是 0/1 (True/False)数值, >> 左边 不能是其他表达式 
(2)>> 右边需要是线性表达式,不能是二次或者广义约束表达式。如果是二次或者广义表达式,可以引入中间变量=二次或者广义表达式放在约束中,然后用中间变量替换,使得 >> 右边是线性表达式。

约束和变量在gurobi中的构建代码:

import gurobipy as gp
 from gurobipy import GRB # 创建一个新模型
m = gp.Model( "test" ) # 创建变量
x = m.addVar(ub= 10 , vtype=GRB.CONTINUOUS, name= "x" ) 
y = m.addVar(ub= 5 , vtype=GRB.CONTINUOUS, name= "y" ) 
z = m.addVar(vtype=GRB.CONTINUOUS, name= "z" ) 
w1 = m.addVar(vtype=GRB.CONTINUOUS, name= "w1" ) 
w2 = m.addVar(vtype=GRB.CONTINUOUS, name= "w2" ) 
b = m.addVar(vtype=GRB.BINARY, name= "b")





# 常量
eps = 0.0001 
M = 10 + eps # x 和 y 上可能给定的最小边界

# 建模如果 x > y,则 b = 1,否则 b = 0 
m.addConstr(x >= y + eps - M * ( 1 - b), name= "bigM_constr1" ) 
m.addConstr(x <= y + M * b, name= "bigM_constr2" ) # 添加指标约束
m.addConstr((b == 1 ) >> (z == w1 ), name= "indicator_constr1" ) 
m.addConstr((b == 0 ) >> (z == w2), name= "indicator_constr2" ) 



# 请继续构建模型的其余部分# ..

参考:https://support.gurobi.com/hc/en-us/articles/4414392016529-How-do-I-model-conditional-statements-in-Gurobi-

<think>好的,我现在需要帮用户解决如何使用MATLAB编写线性规划问题的代码。首先,我得回想一下线性规划的基本概念以及MATLAB中的相关函数。线性规划通常包括目标函数、不等式约束、等式约束,以及变量的上下界。MATLAB中常用的函数是linprog,对吧? 接下来,用户可能需要一个结构清晰的步骤说明,所以我要分步骤讲解。首先,应该介绍线性规划的一般形式,比如目标函数是min c'*x,然后不等式约束A*x ≤ b,等式约束Aeq*x = beq,还有变量的下界lb和上界ub。这样用户能明确各个参数的含义。 然后,我需要解释linprog函数的调用方式。正确的语法应该是x = linprog(c, A, b, Aeq, beq, lb, ub)。不过要注意,如果某个约束不存在,应该用空矩阵[]代替。比如如果没有等式约束,Aeq和beq的位置就写[]。这点很重要,容易出错,必须提醒用户。 接下来,最好给出一个具体的例子,这样用户更容易理解。比如,假设要最小化目标函数f = -3x1 - 2x2,满足不等式x1 + x2 ≤ 4,x1 - x2 ≤ 2,x1 ≥ 0,x2 ≥ 0。这时候需要将系数向量c设为[-3; -2],不等式矩阵A为[1 1; 1 -1],对应的b是[4; 2]。而lb是[0; 0],没有等式约束和上界,所以Aeq, beq, ub都用[]。这样用户就能看到如何将问题转化为MATLAB代码。 然后,展示代码示例,包括参数的赋值和调用linprog的过程。同时,需要提到如何获取解和最优值,比如输出x的值和计算目标函数的值。这里需要注意,linprog返回的是解x,而目标函数的最小值是c'*x,但原来的目标函数可能有符号变化,比如例子中的最大化问题转化为最小化后的处理。 此外,可能还需要提醒用户一些常见问题,比如目标函数是最大化的话需要转化为最小化,因为linprog默认求最小值。这时候系数c要取相反数。还有,约束的方向是否一致,如果原问题有≥的约束,需要乘以-1调整方向。 最后,要检查LaTeX格式是否正确,所有行内数学公式用$...$,独立公式用$$...$$。确保代码部分语法正确,比如使用正确的矩阵符号和运算符。同时,用中文清晰解释每一步,结构分明,让用户能够一步步跟随操作。</think>以下为使用MATLAB解决线性规划问题的分步说明及代码示例: --- ### 一、线性规划标准形式 线性规划问题需转化为以下标准形式: $$ \min_{x} \,\, c^T x $$ 约束条件: $$ \begin{cases} A \cdot x \leq b \\ Aeq \cdot x = beq \\ lb \leq x \leq ub \end{cases} $$ 其中: - $c$为目标函数系数向量 - $A$, $b$为不等式约束矩阵和向量 - $Aeq$, $beq$为等式约束矩阵和向量 - $lb$, $ub$为变量下界和上界 --- ### 二、MATLAB代码步骤 #### 1. 定义参数 ```matlab c = [-3; -2]; % 目标函数系数(注意min问题需保留符号) A = [1, 1; 1, -1]; % 不等式约束矩阵 b = [4; 2]; % 不等式约束右侧向量 Aeq = []; % 无等式约束时设为空矩阵 beq = []; lb = [0; 0]; % 变量下界 ub = []; % 无上界时设为空矩阵 ``` #### 2. 调用`linprog`函数求解 ```matlab [x, fval] = linprog(c, A, b, Aeq, beq, lb, ub); ``` #### 3. 输出结果 ```matlab disp('最优解:'); disp(x); disp('目标函数最小值:'); disp(fval); ``` --- ### 三、案例演示 **问题描述**: 最大化 $f = 3x_1 + 2x_2$,满足: $$ \begin{cases} x_1 + x_2 \leq 4 \\ x_1 - x_2 \leq 2 \\ x_1 \geq 0, x_2 \geq 0 \end{cases} $$ **MATLAB代码转换**: 1. 最大化转最小化:目标函数改为 $\min -3x_1 -2x_2$ 2. 参数设置与上述代码一致 **运行结果**: ``` 最优解: 3 1 目标函数最小值: -11 ``` 实际最大值为 $11$(取$-fval$) --- ### 四、注意事项 1. **约束方向**:所有不等式必须为 $\leq$ 形式,若原始约束为 $\geq$ 需乘以 $-1$ 2. **变量边界**:未指定上界时用`ub = []`,类似处理下界 3. **结果验证**:建议使用`exitflag`检查求解状态: ```matlab [x, fval, exitflag] = linprog(...); if exitflag == 1 disp('求解成功'); else disp('无可行解'); end ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值