解决线性规划问题 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-

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 很抱歉,我不太确定您所指的“单纯形法解决线性规划问题”的问题。不过,单纯形法是一种经典的线性规划求解方法,主要分为两个阶段:第一阶段是将原始问题转化为标准型问题;第二阶段是通过一系列的单纯形运算来逐步优化目标函数值,直至找到最优解。 具体来说,单纯形法在每一次迭代中都会找到一个非基变量(即当前最优解中为0的变量),并将其作为入基变量(即从0变为正数)。接着,通过在约束条件中找到对应的限制最紧的变量(即使得目标函数值增加最小的变量),将其作为出基变量(即从正数变为0),从而更新最优解。 如果该迭代中无法找到合适的非基变量作为入基变量,则说明已经找到了最优解,问题得到解决。 如果您有其他问题或需要进一步的解释,请告诉我,我将尽力为您提供帮助。 ### 回答2: 单纯形法是一种常用的解决线性规划问题的方法,可以通过编写相关的代码来实现。 单纯形法的基本思路是通过不断的迭代,找到合适的解。以下是一种简化的单纯形法的代码示例: 1. 定义一个函数simplex_method(),接收线性规划的目标函数和约束条件作为输入。 2. 初始化初始基变量基底向量、非基变量向量、基变量值等参数。 3. 进入迭代过程,循环执行以下步骤直到满足终止条件: a. 根据基变量值和目标函数确定非基变量的取值。 b. 计算目标函数值。 c. 检查是否满足约束条件,如果满足则结束迭代,得到最优解。 d. 如果不满足约束条件,则根据离开变量和进入变量规则找到要交换的变量。 e. 更新基变量值,继续下一次迭代。 4. 返回最优解。 这只是一个简化的单纯形法代码示例,实际实现过程中需要考虑更多的细节和优化。例如,需要处理边界条件、非可行解的情况,以及选择合适的进入变量和离开变量等等。 总之,单纯形法是解决线性规划问题的一种有效方法,编写相关的代码可以帮助我们自动化地求解这类问题,提高计算效率。 ### 回答3: 单纯形法是一种常用的求解线性规划问题的算法。下面我将给出一个简单的单纯形法代码示例。 首先,我们需要导入numpy库,用于矩阵运算。代码如下: ```python import numpy as np ``` 然后,我们定义一个函数simplex来实现单纯形法的求解过程。该函数接收一个二维数组A、一个一维数组b和一个一维数组c作为输入,分别表示线性规划问题中的系数矩阵、约束条件和目标函数。 ```python def simplex(A, b, c): m, n = A.shape # 添加人工变量 c = np.hstack((c, np.zeros(n))) A = np.hstack((A, np.eye(m))) # 构建初始单纯形表 B = np.arange(n, n + m) N = np.arange(n) T = np.concatenate((B, N)) Ab = np.hstack((A[:, B], b.reshape((m, 1)))) cB = c[B] cN = c[N] while True: # 计算单纯形法的乘子 B_inv = np.linalg.inv(A[:, B]) y = np.dot(cB, B_inv) # 计算进入变量 delta = np.dot(y, A[:, N]) - cN if np.all(delta >= 0): # 单纯形法结束 break q = np.argmax(delta) # 计算离开变量 d = np.dot(B_inv, A[:, N[q]]) # 检查是否无界 if np.all(d <= 0): # 无界解 return None p = np.argmin(np.where(d > 0, Ab[:, -1] / d, np.inf)) # 更新基变量和非基变量 B[p], N[q] = N[q], B[p] # 更新单纯形表 Ab[p, :] /= d[p] for i in range(m): if i != p: Ab[i, :] -= Ab[p, :] * d[i] cB = c[B] cN = c[N] # 提取基变量的解 x = np.zeros(n) for i, bi in enumerate(B): x[bi] = Ab[i, -1] return x ``` 最后,我们可以使用该函数来求解一个线性规划问题。代码示例如下: ```python A = np.array([[2, 1, -1], [1, -1, 1]]) b = np.array([2, 5]) c = np.array([1, 2, -3]) x = simplex(A, b, c) print("最优解:", x) ``` 在上述代码中,输入的系数矩阵A、约束条件b和目标函数c分别表示如下线性规划问题: ``` max: c^T * x A * x <= b x >= 0 ``` 程序会输出最优解x的值。注意,如果问题无界,则程序会输出None。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值