线性规划问题与单纯形法

2023-12-16 10:32

本文主要是介绍线性规划问题与单纯形法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


线性规划是运筹学中一个很重要的分支,本文通过一个实例简单的介绍一下什么是线性规划问题,以及单纯形法的计算步骤。


问题 : 在一个工厂中,有两种产品A与B,它们的单价分别为6元与7元。A产品需要2千克原料P与4千克原料Q,而B产品需要3千克P与1千克Q,且P原料总数为16千克,Q原料总数为12千克,设计一种方案,即需要分别生产多少单位A和B可以使得利润最大化?
问题出处 :《运筹学基础及其MATLAB应用》 – 李工农


我们分析上述问题,假设要生产x1单位A,x2单位B,那我们可以得到z = 6 * x1 + 7 * x2,所以我们的问题就转化为了怎样使得z最大。如果只按照上面这一式子求最大值,显然求不出来,故我们需要增加一些约束条件。因为P与Q原料是有限的,所以我们很容易得出2 * x1 + 3 * x2应该小与等于16,同时4 * x1 + 1 * x2应该小与等于12。此外,由于生产单位数不可能是负数,所以还应增加一约束条件x1 >= 0,x2 >= 0。我们将上面几个式子汇总一下,max表示求最大,s.t.(subject to)表示约束条件:
max z = 6 * x1 + 7 * x2
s.t.
2 * x1 + 3 * x2 <= 16
4 * x1 + 1 * x2 <= 12
x1,x2 >= 0

此时,我们再引入两个剩余参数x3与x4,目的是使得约束条件的前两个式子能够左右相等,由于前两个不等式左边恒小与等于右边,所以我们将x3与x4分别放到这两个式子左边,为了能够左右两边值相同,x3与x4必大于等于0。
max z = 6 * x1 + 7 * x2
s.t.
2 * x1 + 3 * x2 + x3 = 16
4 * x1 + 1 * x2 + x4 = 12
x1,x2,x3,x4 >= 0

上式就是一个标准的线性规划模型,现在给出线性规划的通俗定义,形如
max z = cTX
s.t.
Σ j = 1 n P j x j = b \Sigma{^n_{j=1}}P_jx_j = b Σj=1nPjxj=b
x j &gt; = 0 ( j = 1 , 2 , . . . , n ) x_j &gt;= 0 (j = 1,2,...,n) xj>=0(j=1,2,...,n)

这类模型的问题都可以划为线性规划的范畴。其中,cT等价于上面问题中的[6,7,0,0],称作价值系数,X表示[x1,x2,x3,x4]T,称作决策变量,b表示[16,12]T,称作资源系数,最后P表示[2,3,1,0 ;4,1,0,1],称作技术系数。另外我们称z为目标函数,我们需要求的便是目标函数的最优解。


到现在,我们已经大致明白了线性规划问题究竟是什么样的一个模型。然后,我们还需要知道一些线性规划中一些名词:

  • 可行解:满足全部约束条件的解
  • 可行域:可行解所构成的集合
  • 最优解:所有可行解对应的目标函数值中,最大的一个值所对应的解
  • 基:假设技术系数P是一个m x n的一个矩阵,其秩rank ( P ) = m,n >= m我们可以知道P中至少有m个线性无关的列向量,我们将这m个列向量组成一个新的矩阵,记作B,这就是一组基。例如问题中P = [2,3,1,0; 4,1,0,1],则我们可以挑出一组线性无关的列向量(基)[1,0; 0,1]
  • 基变量:基对应的X称作基变量 X B X_B XB,例如[1,0; 0,1]对应的基变量就是[x3, x4]
  • 非基:顾名思义P矩阵除去基后剩余的矩阵称作非基N,所以P = [B,N]
  • 非基变量 :X除去基变量后剩余的元素称作非基变量 X N X_N XN,X = [ X B , X N X_B,X_N XB,XN]
  • 基解:我们设PX=b(即约束条件中的第一个式子),其等价于(B,N)( X B T , X N T X^T_B,X^T_N XBT,XNT)T = b,化简等于 B X B + N X N = b BX_B + NX_N = b BXB+NXN=b。此时我们令非基变量 X N = 0 X_N = 0 XN=0,可得到 X B = B − 1 b X_B = B^{-1}b XB=B1b,这是我们称由基变量与非基
    变量合成的X,即( b T B − T , 0 b^TB^{-T},0 bTBT,0)是问题的一个基解,显然取基不同,基解也不尽相同
  • 基可行解:在基解中若满足X >= 0,称该基解为基可行解
  • 可行基:基可行解对应的基称作可行基

了解了这些名词后,我们正式引入单纯形法解决这类问题。以下列出了单纯形法的基本步骤:

  1. 先找出一个基可行解,称作初始基可行解
  2. 判断该基可行解是否是最优解
  3. 若判断为最优解算法终止,否则更换基可行解,返回第二步

我们通过解决最初提出的问题更详细的描述一下单纯形法。

  1. 初始条件为P = [2,3,1,0 ; 4,1,0,1],c = (6,7,0,0)T,b = [16,12]T,X = [x1,x2,x3,x4]T
  2. 先找基B,我们可以很容易的发现一对线性无关的单位向量[1,0 ; 0,1],令其为B,N为[2,3 ; 4,1],由于 B X B + N X N = b BX_B + NX_N = b BXB+NXN=b,其中, X B = [ x 3 , x 4 ] T , X N = [ x 1 , x 2 ] T X_B = [x_3,x_4]^T ,X_N = [x_1,x_2]^T XB=[x3,x4]T,XN=[x1,x2]T,令 X N = 0 X_N = 0 XN=0,可以得到 X B = [ 16 , 12 ] T X_B = [16,12]^T XB=[16,12]T,X = [0,0,16,12]T,由于X >= 0,故该解是一个基可行解
  3. 我们由约束方程组可以得到:
    ( 1 ) x 3 = 16 − 2 ∗ x 1 − 3 ∗ x 2 (1)x_3 = 16 - 2 * x_1 - 3 * x_2 (1)x3=162x13x2
    ( 2 ) x 4 = 12 − 4 ∗ x 1 − x 2 (2)x_4 = 12 - 4 * x_1 - x_2 (2)x4=124x1x2
    将(1)式与(2)式代入目标函数可得:
    ( 3 ) z = 6 ∗ x 1 + 7 ∗ x 2 + 0 ∗ x 3 + 0 ∗ x 4 = 6 ∗ x 1 + 7 ∗ x 2 (3)z = 6 * x_1 + 7 * x_2 + 0 * x_3 + 0 * x_4 = 6 * x_1 + 7 * x_2 (3)z=6x1+7x2+0x3+0x4=6x1+7x2
    x 1 与 x 2 x_1与x_2 x1x2不在为0,且逐渐增大时,z也会随之增加,故不是最优解。其实,我们判断是否是最优解就是通过看目标函数中非基变量的系数是否有大于0的数来区分的,只要有大于0的数,增加相应的变量肯定会增加目标函数的值。
  4. 更换基,此时我们需要确定换入元素与换出元素。换入元素我们选择目标函数中系数最大的对应元素,即 x 2 x_2 x2,由于 x 1 x_1 x1仍是非基变量,所以令其为0,我们可将(1)(2)式变为:
    ( 4 ) x 3 = 16 − 3 ∗ x 2 &gt; = 0 (4)x_3 = 16 - 3 * x_2 &gt;= 0 (4)x3=163x2>=0
    ( 5 ) x 4 = 12 − x 2 &gt; = 0 (5)x_4 = 12 - x_2 &gt;= 0 (5)x4=12x2>=0
    我们选择令 x 3 与 x 4 x_3与x_4 x3x4等于0时所解得的 x 2 x_2 x2最小的那个变量作为换出变量,即 x 3 x_3 x3。由(1)式可得 ( 6 ) x 2 = 16 3 − 2 3 ∗ x 1 − 1 3 ∗ x 3 (6)x_2 = {16\over 3} - {2\over 3} * x_1 - {1\over 3} * x_3 (6)x2=31632x131x3,将(6)式代入(2)式可得:
    ( 6 ) x 2 = 16 3 − 2 3 ∗ x 1 − 1 3 ∗ x 3 (6)x_2 = {16\over 3} - {2\over 3} * x_1 - {1\over 3} * x_3 (6)x2=31632x131x3
    ( 7 ) x 4 = 20 3 − 10 3 ∗ x 1 + 1 3 ∗ x 3 (7)x_4 = {20\over 3} - {10\over 3} * x_1 + {1\over 3} * x_3 (7)x4=320310x1+31x3
  5. 将(6)(7)式代入目标函数中可得:
    ( 8 ) z = 6 ∗ x 1 + 7 ∗ ( 16 3 − 2 3 ∗ x 1 − 1 3 ∗ x 3 ) = 112 3 + 4 3 ∗ x 1 − 7 3 ∗ x 3 (8)z = 6 * x_1 + 7 * ({16\over 3} - {2\over 3} * x_1 - {1\over 3} * x_3) = {112\over 3} + {4\over 3} * x_1 - {7\over 3} * x_3 (8)z=6x1+7(31632x131x3)=3112+34x137x3,令 x 1 与 x 3 x_1与x_3 x1x3等于0可以得到一组解,按照第3步的判定规则我们认为该解也不是最优解
  6. 参照第四步的换基规则确定换出元素与换入元素分别是 x 4 与 x 1 x_4与x_1 x4x1,且通过(6)(7)式可以得到:
    ( 9 ) x 2 = 4 + 1 5 ∗ x 4 − 2 5 ∗ x 3 (9)x_2 = 4 + {1\over 5} * x_4 - {2\over 5} * x_3 (9)x2=4+51x452x3
    ( 10 ) x 1 = 2 − 3 10 ∗ x 4 + 1 10 ∗ x 3 (10)x_1 = 2 - {3\over 10} * x_4 + {1\over 10} * x_3 (10)x1=2103x4+101x3
  7. 将(9)(10)式代入目标函数中可得:
    ( 11 ) z = 40 − 11 5 ∗ x 3 − 2 5 ∗ x 4 (11)z = 40 - {11\over 5} * x_3 - {2\over 5} * x_4 (11)z=40511x352x4,令 x 3 与 x 4 x_3与x_4 x3x4等于0可以得到一组解,按照第3步的判定规则我们认为该解是最优解。最优解为[2,4,0,0],值为40。

为了能更直观,更快速的计算,可以将上述内容做成如下一张表格(单纯形表):

c j c_j cj6700 θ \theta θ
c B c_B cB X B X_B XBbx1x2x3x4
0 x 3 x_3 x3162[3]10 16 3 {16\over 3} 316
0 x 4 x_4 x412410112
σ j = c j − Σ i = 1 m c i a i j \sigma_j = c_j - \Sigma^m_{i=1}c_ia_{ij} σj=cjΣi=1mciaij6700
7 x 2 x_2 x2 16 3 {16\over 3} 316 2 3 {2\over 3} 321 1 3 {1\over 3} 3108
0 x 4 x_4 x4 20 3 {20\over 3} 320[ 10 3 {10\over 3} 310]0- 1 3 {1\over 3} 3112
σ j = c j − Σ i = 1 m c i a i j \sigma_j = c_j - \Sigma^m_{i=1}c_ia_{ij} σj=cjΣi=1mciaij 4 3 {4\over 3} 340- 7 3 {7\over 3} 370
7 x 2 x_2 x2401 2 5 {2\over 5} 52- 1 5 {1\over 5} 51
6 x 1 x_1 x1210- 1 10 {1\over 10} 101 3 10 {3\over 10} 103
σ j = c j − Σ i = 1 m c i a i j \sigma_j = c_j - \Sigma^m_{i=1}c_ia_{ij} σj=cjΣi=1mciaij00- 11 5 {11\over 5} 511- 2 5 {2\over 5} 52

在这张表中,[]中的值称作旋转主元,其横向对应的变量为换出变量,纵向对应的为换入变量。在每次迭代中,最小的 θ 与 最 大 的 σ \theta与最大的\sigma θσ指向一个旋转主元。 σ \sigma σ的计算是由 c j − Σ i = 1 m c i a i j {c_j - \Sigma^m_{i=1}c_ia_{ij}} cjΣi=1mciaij计算得来的,举个例子,在第二次迭代中, σ 1 = 6 − 7 ∗ 2 3 − 0 ∗ 10 3 {\sigma_1 = 6 - 7 * {2\over 3} - 0 * {10\over 3}} σ1=67320310。而 θ \theta θ的计算是b中元素分别除以最大 σ \sigma σ所在列的元素。对于每次基变换其实只需要对增广矩阵[b,P]进行行列变换即可,其目的是使得换入变量所在列与之前其他单位向量继续能够构成单位矩阵。最后评判是否是最优解只需要看非基变量的 θ \theta θ是否有大与零。


MATLAB源码点击此处下载

这篇关于线性规划问题与单纯形法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500148

相关文章

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

如何解决Spring MVC中响应乱码问题

《如何解决SpringMVC中响应乱码问题》:本文主要介绍如何解决SpringMVC中响应乱码问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC最新响应中乱码解决方式以前的解决办法这是比较通用的一种方法总结Spring MVC最新响应中乱码解