《运筹学》系列文章:
现实的世界已经很复杂了,模型就是这个世界的简单刻画,没有必要再将模型建的很复杂!
—— 某一《数值分析》授课老师
这篇博客的主要作用是记录一些理解线性规划与单纯型法的一些关键的点!
线性地理解世界我想是最简单的方式,我们把人分成好人与坏人、把食物分成好吃的和难吃的、把工具分成耐用的和不经用的。如果某人做了一件好事,那么他就离好人更近一步;如果他做了一件坏事,那么他就变得更坏。如果做了三件好事,那么这个人肯定比做了一件好事的人为人更好。
1. 理解线性
好在我们不是数学系的学生,我觉得用自然语言直观理解即可。
我们知道对于一元函数,形如y = kx + b
,他是一条直线;对于二元函数,形如z = ax + by + c
他是一个面。所以在若干个自变量的表达式中,不会形成一个“弯曲”结构时,它就是一个线性的结构。那么怎么样才不会形成一个弯曲结构呢?一般在表达式中只有乘法和加法,而不出现三角函数,对数函数,指数函数,幂函数时则会形成一种线性结构,如y = x^2
或者y=2^x
,此时就不是线性。所以如果你有n个自变量那么形如,下面这种形式就是一种线性结构:
y = k1 x1 + k2 x2 +k3 x3 + ... + kn x1 + b
其中 ki i = 1,2,3 ... n 和b 是常数
2. 贯穿第二章的例1
资源\产品 | 产品1(每件获利2元) | 产品2每件获利(3元) | 现有条件 |
---|---|---|---|
设备 | (需消耗)1 台时/件 | 2 台时/件 | 8 台时 |
原材料A | (需消耗) 4 kg/件 | 0 | 16 kg |
原材料B | (需消耗) 0 | 4 kg/件 | 12kg |
设备的台时是个什么概念? 我们可以理解为可供调度的机器人的工作量,比如现有的条件是8台时,就是说工厂有八个机器人可用,每个机器人可以用一个小时。或者你也可以理解为有一个机器人,他可以工作八个小时。这个实际的应用场景我们是很容易写成这个线性规划的目标函数和约束条件的,也就是很容易把这个现实的问题转化为一个数学上的问题。我们学习《运筹学》主要注重的是如何求解的过程。
那么我们不禁要问用来转化这个实际问题到数学问题的那个表格是如何得到的?为什么产品1每件可获利2元?为什么可以简单地用4kg /件的原材料A来制作产品1?我引用一下我们授课教师的话:
那是一个数学建模的过程,我们现在学的不是数学建模,而是如何去求解数学问题。这个数学问题是来自课本中已经把实际问题转化为数学问题之后的问题。
3.求解这个问题
那么我们现在来求解这个问题吧!当自变量个数小于等于2时,我们可以用图解法来求解。但实际的问题肯定不会这么简单。为了求解这个问题,用一种很成熟的方法:单纯形法。
化标准形
在应用这个方法时,我们要将这个问题中的目标函数、约束条件和自变量的约束转化成标准形式。这个标准形式就是目标函数一定是要取最大值,约束条件一定要取等号,决策变量一定要非负。标准型是你运用的前提条件。那为什么要转化成一个标准型呢?这里我讲一个笑话:数学家当消防员
一天,数学家觉得自己已受够了数学,于是他跑到消防队去宣布他想当消防员.消防队长说:“您看上去不错,可是我得先给您一个测试.”
消防队长带数学家到消防队后院小巷,巷子里有一个货栈,一只消防栓和一卷软管.消防队长问:“假设货栈起火,您怎么办?”数学家回答:“我把消防栓接到软管上,打开水龙,把火浇灭.”
消防队长说:“完全正确!最后一个问题:假设您走进小巷,而货栈没有起火,您怎么办?”数学家疑惑地思索了半天,终于答道:“我就把货栈点着.”消防队长大叫起来:“什么?太可怕了!您为什么要把货栈点着?”数学家回答:“这样我就把问题化简为一个我已经解决过的问题了.”
化标准型就能转化为已经解决过得问题了。
线性规划解的特点
下面罗列线性规划的一些结论,毕竟我们不是数学系的学生:
- 化为标准型后,基可行解和可行域的顶点是一一对应的。
- 如果一个线性规划问题存在最优解,则其最优解必然可在可行域的顶点处达到,也就是必然在基可行解处达到
单纯形法利用了上面的这些特点,被开发了出来,我们直接学习这个成熟的模型即可。
那么如何手工来求解这些模型,我们利用单纯形表进行表上作业。
单纯形法表上作业
课本P39给出了计算的一个详细的例子。
相信写完这个例子之后,不知大家有没有这样一种感觉:这些步骤都好机械啊,我完全可以写一个程序叫计算机帮我算算就行了。 下面我们就来写一下程序!
4. 编程
在写程序之前首先我们要选择利用哪种程序设计语言,我推荐用Matlab,当然你可以用python,R。他们都可以进行矩阵操作。不过这里还有一个更好的选择,就是Matlab的开源替代品Octave。它至少有三大令你不能不用的理由:
- 开源,你可以在发表文献的时候声明一下即可。有些文章就是因为一些软件的版权问题而被撤稿。
- 安装包小,而且安装简单。Matlab的话,安装包太大了,而且找个破解版也比较头疼。
- 绝大部分Matlab命令它是兼容的。
4.1 安装:
下面我们来安装Octave来进行编程。进入其官网 ,点击下载我是MAC操作系统,需要点击Octave wiki 然后Installing a Mac OS X Bundle 即可。Windos 操作系统的话就更加方便了。直接下载.exe文件。
之后一步一步根据提示点击即可。
4.2 编程
将Octave打开,相信大家不陌生吧,它的GUI界面和Matlab还有Rstudio非常的像。我们新建一个脚本,调整一下字体大小。
编写单纯形法我总结了有两种思路:
- 因为表上作业的一些步骤相对比较机械,所以我们可以根据单纯性表法进行编程。
- 利用单纯形法的矩阵描述。其中需要指出的是,课本P63页有些问题在原文“x1的系数向量P1=()”处少了一些东西。如下图所示,注意:如果改正的话,程序的迭代会出错。
下面我们来看一下代码:
不过在编写之前我们得先浏览一下最基本的用法:这个网站总结的不错。
代码被放置与github之上,欢迎阅读与测试!
代码主要包含三大部分内容:
-
内置函数、化标准型与图解法
位于
Main.m
文件:练习使用GLPK开源包,直接计算还有编写化标准型的代码:
- 根据单纯形表法表上作业,将机械的求解用程序解决,位于
simplex_method1.m
文件中。
- 利用矩阵的描述,也就是改进的单纯形法来编写的子程序,位于
simplex_method.m
文件中。
5. 对偶问题
在对偶问题的提出上,课本P64页的说明不如上课老师讲的根据有实际意义:
我们来重新根据老师的讲解来复习一遍:假设有一天作为厂长的你不准备自己生产了,而是准备将厂内的设备租赁出去,将原材料A和B卖出去。问:如何进行定价才能更好!我们不妨设价格为 y1, y2 ,y3
资源\产品 | 产品1(每件获利2元) | 产品2每件获利(3元) | 现有条件 | 价格 |
---|---|---|---|---|
设备 | (需消耗)1 台时/件 | 2 台时/件 | 8 台时 | y1 台时/元 |
原材料A | (需消耗) 4 kg/件 | 0 | 16 kg | y2 kg/元 |
原材料B | (需消耗) 0 | 4 kg/件 | 12kg | y3 kg/元 |
那首先对你自己来说,你租出去,卖出去的价格一定要比自己生产时高。这样你才能有利可图,否则还不如自己生产。
于是就有:
y1 + 4y2 >=2 ; 2y1 + 4 y3 >=3其次,你不能漫天要价,你要让对方觉得你的定价是你在现有条件下以所定价格全部卖出后总的价格尽可能的低。
于是就有:
min w = 8y1+16y1+12y1
毕竟买卖得让双方都感觉很公平才行。
6. 灵敏度分析
对于任何数学建模之后得到的模型,灵敏度都是一个很重要的指标,也很有现实的意义。
比如产品1每件获利2元,我们现在不是一般在谈论“实体经济不景气”,这个价格会在一定范围内波动。在这种情况下,我们该如何重新规划我们的生产。