第二次培训0118优化建模Word格式文档下载.docx
《第二次培训0118优化建模Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《第二次培训0118优化建模Word格式文档下载.docx(16页珍藏版)》请在冰豆网上搜索。
05
美赛的题目也体现了这种变化,例如:
1991年的Steiner树问题,1992年的应急电力恢复问题,1993年的倒煤台的操作方案问题和最优堆肥问题,1994年的混凝土地板问题和通信网络问题,1995年的AluachaBalaclava学院问题,1996年的竞赛答卷评阅问题,1997年的Velociraptor问题和为有效讨论进行充分的混合分组问题,1998年的MRI扫描问题,1999年的不合法的聚会场所的问题。
44:
22
可以看出这类问题利用传统的规划理论难以直接解决,我们要使用一些方法做必要的简化和变换才可以化为规划问题进行解决,由于获得最优解比较困难,一些试探性的算法得到了大量的应用,灵敏性分析的工作变得更加重要。
45:
27
2000年以后的美赛问题中纯优化问题变得少了很多,我们看到的只有2002年的风和喷水池问题,2005年的公路收费亭的设置,2007年的不公正的选区划分,2009年的能源与手机。
这是否意味着优化问题已经失宠了呢?
48:
21
我想不是这样,其实绝大多数问题都可以划归为优化问题,我们需要把优化作为模型研究的第一工具,不是学完了,而是还有很多知识正在发展,完善中。
50:
现在之所以纯优化问题出得少了,是因为我们现在看问题的视野宽了,以往都是片面地研究一个对象某方面的特性,而现在都要对对象做全方面地研究,从一个系统的方面去解决问题,
51:
14
这样考虑的因素大幅度增加了,传统的优化模型的弱点在于目标函数都是单值函数,主要是因为数值有自然序的规则,向量甚至集合的排序很难,没有了序就没有办法体现出优化的涵义,
51
我们需要把多种因素的影响统一对应到一个数值上,比如:
利润和费用,但是有些相互矛盾的因素或者是不容易量化的因素就无法统一进来了。
53:
24
优化的研究者已经在研究集值映射的优化理论,但是实际的算法很少,所以应用不广,另一方面的选择就是用优化模型来研究系统的某一方面特性,从全局的模型变为局部模型来使用。
54:
17
另外,近几年实验方法越来越得到了重视,传统的优化理论在实验控制和实验评估方面发挥了巨大的作用。
数学中国站长(75822904)
19:
56:
49
接下来,我们来回顾一下优化建模的一些基本理论,为了节省时间,我捡干的说。
59:
01
与最大、最小、最长、最短等等有关的问题都是优化问题,其实发现优化问题并不难,就是要在问题中找“最(most)”字,当然有些问题并不会直接说最什么什么,但意思中可能会隐含这种想法。
20:
00:
21
对于优化建模来说我们要按照下面的五个步骤来做:
1、确定目标,2、确定决策向量,3、确定目标与决策向量之间的函数关系,4、确定问题的最优取向,5、确定决策向量的约束范围。
03:
18
接下来我针对这五个步骤分别谈谈。
所谓的目标就是对问题进行优化建模的最终目的。
要想确定目标可以寻找“最”字,通常将它前面的核心名词确定为目标。
当然很多问题的目标并不一定,比如说投资组合问题,我们既可以把利润当做目标也可以把风险当做目标。
05:
52
所谓决策就是人对所有与目标相关的未知因素的一种选择。
它可以用来对应目标的一种状态。
06:
27
决策向量是决策的数学化,是用向量的方式对决策的一种表示。
07:
12
最优决策向量:
使得目标达到最优的决策向量。
通常我们把它称做优化问题的最优解。
它所对应的目标值称做最优值。
53
确定决策向量是优化建模的关键,我们需要找到与目标相关的所有因素。
在运输问题中影响运输费用目标的就是从某一个产地运往所有销地的产品的数量,不同的数量值对应着不同的目标值,这就是我们需要做的决策。
08:
48
所谓的目标函数是目标与决策向量之间的函数关系。
目标函数的确定依赖于问题中所蕴含的客观规律。
09:
38
容易处理的目标函数主要是凸函数,因为凸函数的局部极小(大)点就是全局极小(大)点,而局部极小点我们可以利用一阶导数信息来判定,这样就有了一个有效判定最优解的方法了。
11:
00
什么是凸函数呢?
二维和三维的凸函数我们可以从函数图像上来判定,就是向着坐标方向看函数图像向你凸出出来的就是凸函数。
12:
03
高维的凸函数需要数学的定义:
首先定义凸集。
n
凸集:
设S是n维空间中的一个点集。
若对任意n维向量X1Î
S,X2Î
S,且X1¹
X2,以及任意实数l(0£
l£
1),有
X=lX1+(1-l)X2Î
S
则称S为n维空间中的一个凸集(Convex
Set)。
点X称为点X1和X2的凸组合。
30
13:
17
下图中第一行的三个集合都是凸集,第二行的三个集合不是凸集。
28
14:
34
形象地说,凸集就是任意两点间的线段都在集合中的集合。
15:
07
有了凸集的概念我们就可以定义凸函数了。
凸函数:
函数图像的上方以函数图像为边界的区域组成的集合为凸集的函数是凸函数。
42
大量问题中的函数可能不是凸函数,对于这些问题的求解会比较困难,非常容易陷入局部最优解无法动弹。
比如下图中所示的几个目标函数的情况。
17:
图c中的最优解的洞非常小,就像高尔夫球进洞的难度差不多,很多算法都会陷入局部最优解,但我们看到局部最优解其实距离全局最优解还有很远,这样的局部最优解意义不大,所以很多非凸优化的求解是需要一些技巧的,
18:
02
改造函数的不良性质使其更容易处理,通常的做法有光滑化、线性化、函数逼近、局部扰动等。
所谓最优取向是使得目标达到最优的目标函数的下降方向。
对于数值型的目标来说,可以从实际问题的要求判断出目标函数的最优取向,通常是最大或者最小。
29
对于向量型的目标来说,最优取向不一定代表目标函数的最大或最小值,通常意味着一个均衡的值。
11
在一些情况下,决策向量的取值会受到一定的限制。
使得决策向量的取值不再是整个空间而仅仅是整个空间的一个子集,把这个集合称做约束范围。
建模的时候,要确定约束范围需要考虑题目的要求,我们有的时候建立一个优化模型是一个问题要求对应模型的一个约束条件。
21:
51
也有一些约束范围要根据所获得的数据的情况来建立,例如2007年不公正的选区划分的问题,
22:
35
我们如果获得了选民的收入的分布情况的数据,就可以根据这个数据构造一个约束条件,要求平均收入差距不要太大,这个要求题目中是没有的,完全根据获得的数据来。
23:
15
通过上面的分析我们可以总结出优化模型的基本形式:
24:
13
25:
04
如果是线性规划模型又可以写成下面的矩阵形式:
数学中国(291269111)
27:
1015(364168326)
28:
怎么看不到图片了从发下可以吗?
36
1021(875425260)
45
没有视频
啊?
58
我发图片达到上限了,图片由数学中国来发
29:
对于优化问题的求解我们来借助一下软件,因为很多问题的规模是比较大的,不借助软件求解工作是无法完成的。
我们这里来介绍一个优化问题使用最广泛的软件——lingo。
20
请遵守培训纪律,不要讲话,有问题私聊我!
30:
网上已经有很多介绍lingo软件的课件和书籍,我想很多网友都学习过,但是还有很多同学遇到lingo编程问题感觉触头,一些模型建立好了,但无法写出lingo代码,甚至不知道如何下手。
我这里通过一个小例子来告诉大家lingo代码该如何写,虽然是入门的例子,但是我觉得编程这个东西只要入了门,就什么都好办了,也许你马上就会成为lingo高手了。
46
我找了一个网上最常见的小例子,编了lingo程序,和大家分享一下。
31
1.我的食谱由四种食品组成:
果仁巧克力,冰淇淋,可乐,奶酪.一块果仁巧克力价格为50
美分,一杯冰淇淋价格为20美分,
一瓶可乐价格为30美分,
一快奶酪价格为80美分.我每天的营养最低需求:
500
卡路里,6
盎司巧克力,10
盎司糖,
8
盎司脂肪.
四种食品的营养成分如下表:
卡路里
巧克力(盎司)
糖(盎司)
脂肪(盎司)
果仁巧克力(块)
400
3
2
巧克力冰淇淋(杯)
200
4
可乐(瓶)
150
0
4
1
奶酪(块)
5
试列出一份最节俭的食谱。
43
我们首先对问题分析一下,完成上面优化建模的五个步骤的工作。
1、该问题的目标是什么?
答:
食谱中饮食的成本
2、决策向量是什么?
果仁巧克力,冰淇淋,可乐,奶酪的数量
3、目标函数是什么?
一个线性函数。
4、最优取向是?
最低
5、限制条件都有?
满足每天卡路里,巧克力,糖,脂肪的最低需求
40:
06
接下来我们来编写程序,首先我们看到决策变量是果仁巧克力,冰淇淋,可乐,奶酪的数量,可以用一个四维的向量来表示,我们可以用x1,x2,x3,x4来表示。
这样我们就可以写程序了,看看下面的程序:
41:
25
22
这就是lingo的代码,
说明一下我使用的是数学中国论坛里面提供的lingo11的免安装版,非常好用的。
43:
大家看到这个代码是不是很简单,其实就是把模型又写了一遍,
每一行的最后用一个分号结束,以!
号开始,以;
号结束的是注释部分,显示为绿色,非常醒目。
Lingo的变量名以字母开头,不能超过8个字符,变量名和关键字都不区分大小写,目标函数在第一行,第二行起是约束条件。
56
然后点击工具条上的按钮
05
19
即可运行程序。
47
比如这个程序的运行结果是:
46:
47:
可以看到模型的一些信息:
线性规划模型,得到了全局最优解,计算迭代了2步,耗去时间0秒(小于1秒)
接下来我们对程序改进一下,因为我们定义的变量可能有点多,或许以后很多程序变量会更多,这样定义会很麻烦,
别着急,lingo也支持数组,在lingo中叫做集(set)。
集部分是LINGO模型的一个可选部分。
在LINGO模型中使用集之前,必须在集部分事先定义。
集部分以关键字“sets:
”开始,以“endsets”结束。
52:
16
一个模型可以没有集部分,或有一个简单的集部分,或有多个集部分。
一个集部分可以放置于模型的任何地方,但是一个集及其属性在模型约束中被引用之前必须定义了它们。
我们来看看使用set以后模型的变化。
这个代码中的mat叫做集的名字,x叫做集的属性,x
(1),x
(2)等就对应了我们前面的四个变量,这里是数组的四个成员。
55:
如果学过面向对象编程的同学可以把mat认为成类的定义,x认为成类的一个实例。
两个斜杠中间的1..4表示这个集的成员列表,成员是1到4这样的四个,就和C语言定义数组一样的,数组名后面要说明有几个成员。
57:
09
当然lingo的集要比数组的含义广得多,这个成员列表也可以不用数字表示,可以用有具体意义的字符,这样更加好标识成员的含义。
比如可以定义一个名为students的集,它具有成员John、Jill、Rose和Mike,属性有sex和age:
sets:
students/John
Jill,
Rose
Mike/:
sex,
age;
endsets
58:
这个代码的改进使用了集,但是代码长度并没有得到缩短,反而增加了,难道集没有什么用吗?
不是!
集的使用使得我们定义变量变得更容易了,特别对于大型的问题。
01:
其实集的使用还有更多的好处,你们有没有注意到线性规划模型的矩阵形式,想想前面的矩阵形式是不是很简单?
02:
我们可以把lingo中的模型也写成矩阵形式呀!
40
首先我们先从目标函数下手,这个矩阵形式中的内积如何在lingo中表示呢?
对了,内积是一种多项和的形式,有没有求和的内部函数呢?
当然有了,它就是@sum。
我们再改进一下程序:
04:
这次改进我们使用了@sum函数来表示内积,@sum函数的使用很简单,注意括号里面的东西,分号前面的是集的名字加上括号里面的循环变量,我们习惯都用i,j这样的变量。
分号后面就是具体的求和中每一项的形式,我这里是内积所以是两项相乘。
首先定义了mat集的两个实例x,c。
这是为了后面做内积的准备,另外c的值我们是知道的,为了方便我们这里使用了data来引入参数的值,其实写法很简单,以data:
开头,以enddata结束,中间书写参数的值,对于一维数组写成一行,二维的就写成多行,每个元素用空格或者逗号分割,每个赋值最后加一个分号,注意二维数组的只在最后一行的结尾加上分号。
另外系数矩阵怎么实现呢?
54
呵呵,用二维数组来表示矩阵呀。
这样就可以进一步把模型矩阵化了。
我们来看进一步的改进:
这里面把系数矩阵单独定义为了一个新的集的实例,这个集的名字是m,它是两个mat集组成的一个二维的数组,我们把它叫做派生集,这里就像我们所说笛卡尔集一样。
57
接下来我们来简化模型的约束条件,把每个约束条件都写成内积的形式,
14
这里面我们看到了二维数组和一维数组相乘的写法,和数学的写法很像的。
10:
39
还能不能更简化呢?
能不能把它写成一个矩阵的约束条件呢?
光是内积的形式,如果约束条件多的话代码量太大了呀!
没有问题,我们可以使用@for函数。
请看新的改进:
这里面我们把右边变量也定义成了数组。
怎么样?
是不是线性规划的矩阵形式了?
这里面的@for函数的使用方法和@sum函数基本一样,需要注意的就是分号前面仍然要添加的是集的名字而不是集的属性。
另外我们也可以把原模型中保证巧克力需求的约束单独写出来,因为它只有两项。
可以参考下面的形式:
我们可以看到@for函数和@sum函数都是可以使用条件做筛选的,比如我们这里面x有四个分量,而aa只有两个,我们可以对集mat做筛选,只使用它的前两个成员,在集名字的后面用一个竖线再写上条件表达式,我们这里是i小于等于2。
讲到这里大家应该可以入门了,以后咱们尽量将模型以矩阵的形式去表示就很容易转化为Lingo的代码了。
16:
我们在建立优化模型的时候尽量避免建立非线性规划模型,因为前面已经说了这样的模型很容易遇到局部最优解,就像姜启源老师的《数学模型》书第四章的原油采购与加工问题中的三个方法比较就很说明问题。
有的时候非线性的影响可能使我们寻找最优的路子一无所获,比如我们下面的例子,
求解一个非线性方程(方程和规划其实是等价的,lingo也是可以求解方程的呀,其实lingo可以把模型中所有未知的变量值都找到,如果不信你可以把data中的某个数值去掉,可以使用两个逗号来表示,lingo就会把它当作变量来求解的。
):
代码只有两行,很简单。
但是居然没有可行解找到,是不是真的没有可行解呢?
其实不是,是lingo的算法的问题。
这个方程的非线性太强,找到一个点非常困难。
我们可以帮帮lingo,使用init来告诉lingo从什么点开始比较好。
我们告诉lingo从(0.2,1)这个点开始找,所以lingo很快找到了解(0.45,1.3)。
我们也要注意观察LINGO求解模型结束后的返回状态:
Global
Optimum(全局最优)