线性规划问题与单纯形法

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

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

题目1254:N皇后问题

题目1254:N皇后问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 题目描述: N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。 你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。 输入

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

form表单提交编码的问题

浏览器在form提交后,会生成一个HTTP的头部信息"content-type",标准规定其形式为Content-type: application/x-www-form-urlencoded; charset=UTF-8        那么我们如果需要修改编码,不使用默认的,那么可以如下这样操作修改编码,来满足需求: hmtl代码:   <meta http-equiv="Conte