单纯形方法(Simplex Method)
最近在上最优理论这门课,刚开始是线性规划部分,主要的方法就是单纯形方法,学完之后做了一下大M算法和分段法的仿真,拿出来与大家分享一下。单纯形方法是求解线性规划问题的一种基本方法。
线性规划就是在一系列不等式约束下求目标函数最大值或最小值的问题,要把数学中的线性规划问题用计算机来解决,首先要确定一个标准形式。
将所给的线性规划问题化为标准形式:
s.t.是英文subject to 的简写,意思是受约束,也就是说第一个方程受到后面两个方程的约束。对于求最大值问题可以将目标函数加负号转换为最小值问题。
对于求最大值问题可以将目标函数加负号转换为最小值问题。
其他的问题就是将实际问题中的不等式约束改为等式约束,主要方法是引进松弛变量和剩余变量,以及将自有变量转换为非负变量。
①对于不等式,引入松弛变量将其变为等式形式如下:
②对于不等式,引入剩余变量将其变为等式形式如下:
③若变量为自有变量(可取正、负或零,符号无限制),则引入两个非负变量将其表示如下:
关于线性规划问题的解:
确定了标准形式,我们就针对这个标准形式讨论一下线性规划问题的解。线性规划问题的解能满足标准形式中约束条件的向量X的值,但只有最优解才能使目标函数值最小。
对于上文中的标准形式,约束矩阵A是一个m*n维矩阵,且m<n,所以一定可以从A中找到一个满秩m*m矩阵。这个矩阵就称作矩阵A的一个基阵,矩阵A就可以写作 [B N] , 相应的解 x 也可以写成 x=(xB,xN)’,那么 Ax=b 就变为,左式两端同乘B矩阵的逆,得到
。由此引出下列名词:
基阵:非奇异矩阵(满秩矩阵、可逆矩阵)B
基向量:基阵B由m个线性无关的向量组成,称之为基向量
基变量:向量xB各分量,与基向量对应的xB中的m个分量成为基变量
非基变量:向量xN各分量
基本解:令xN各分量为0,由得到的解
称为基阵B对应的基本解
基本可行解:当成立时,称基本解为基本可行解,因为只有满足所有分量不小于0,才符合标准形式中的约束条件(最后一条
)。
单纯形表
如上图所示,在做单纯形表时,我们要找到这么一个满秩矩阵B,而且要通过行变换把它化为单位阵,同时把这个单位阵上方对应的向量c中元素变为0。也就是说,在标准的单纯形表中,在表的第一行中,基变量对应的元素全为0,非基变量对应的元素称之为检验数。这时便找到了此问题的一个基本可行解,此时单纯形表最右边一列的各数从上到下为此基本解对应的目标函数值f和基本解的基变量的值b’(非基变量为0)。
举个例子:
S |
X1(非基变量) |
X2(非基变量) |
X3 |
X4 |
X5 |
|
f |
5(检验数) |
10(检验数) |
0 |
0 |
0 |
0(目标函数值) |
X3 |
1/14 |
1/7 |
1 |
0 |
0 |
1(基变量X3值) |
X4 |
1/7 |
1/12 |
0 |
1 |
0 |
1(基变量X4值) |
X5 |
1 |
1 |
0 |
0 |
1 |
8(基变量X5值) |
这是一个已经变换好的单纯形表,红色部分是b’,也就是此时基本可行解中基变量分别为X3,X4,X5,他们的值分别为1,1,8,对应的基本可行解就是(0,0,1,1,8)。可以看出,此时目标函数值为0。
单纯形方法基本步骤:
初始的单纯形表已经给出了线性规划问题的一个基本可行解,接下来要做的就是判断这个解是否是最优解,如果是的话不用继续找啦,如果不是的话就找一个比这个解更好的解,再进行判断,直到找到最优解。但有的问题是没有最优解的,所以还要判定问题是否无解。
1) 将所给的线性规划问题化为标准形式。
2)找出一个初始的基阵B,作出单纯形表,作为程序的输入(A,C,f,b’)。
3)测试所有的检验数,记录检验数中的正数,若全部小于等于0,则已经找到最优解,计算终止。否则转至4)。
4)测试所有为正的检验数,若在单纯性表中,其所在的列中其他元素全部小于等于0,则此问题无最优解,计算终止,否则转至5)。
5)找出检验数中的最大值,此最大值元素所在列为A(i,:),令约束条件中约束向量b与A(i,:)的比值为向量r,向量r中为正的最小值为h,计算过程如下图。
S单纯形表 |
X1 |
X2 |
X3 |
X4 |
X5 |
|
f |
5 |
10(最大值) |
0 |
0 |
0 |
0 |
X3 |
1/14 |
1/7 |
1 |
0 |
0 |
1 |
X4 |
1/7 |
1/12 |
0 |
1 |
0 |
1 |
X5 |
1 |
1 |
0 |
0 |
1 |
8 |
表格中黄色部分组成的向量点除(对应元素相除)红色部分,得到向量(7,12,8),那么7就是我们要找的那个元素,此时记录元素大小h和坐标(i,j),注意是在S表中行号和列号,此处是2和2(如果有多个相等的最小值则任取一个即可)。
这个元素1/7就是所谓的转轴元(或称基本元),找到他之后要围绕他进行一系列的行变换,称之为换基。步骤如下:
①使转轴元变为1,方法很简单,就是让本行所有元素同时除以转轴元1/7。
②把转轴元所在列的其他元素都变为0,做法是通过一个循环,遍历每一个行(自身所在行除外),每行中与转轴元同列的元素为a,令每行减去转轴元所在行的第a倍即可。转至3)。
理论部分到此为止,如有疏漏欢迎留言(参考书目为黄平的《最优化理论》)
matlab仿真程序编写:
Simplex.m
%Simplex Method
function [x,y]=Simplex(f,A,b)
%输入f是检验数的数组,1*n维
%输入A是约束矩阵, m*n维
%输入b是约束向量, 1*m维
%输出x是解向量
%输出y是最优解
%判断输入维数是否相符
%做初始单纯形表
format rat %将结果以分数表示
S=[f 0;A b'];
[n,m]=size(S);
%判断检验数 r<=0
r=find(f>0);
len=length(r);
%有大于0的检验数则进入循环
while(len)
%检查非负检验数所对列向量元素是否都小于等于0
for k=1:length(r)
d=find(S(:,r(k))>0);
if(length(d)+1==2)
error('无最优解!!!')
%break;
end
end
%找到检验数中最大值
[Rk,j]=max(S(1,1:m-1));
%b与最大值所在列的比值
rb=S(2:n,m)./S(2:n,j);
%把比值中的负数都变无穷
for p=1:length(rb)
if(rb(p)<0)
rb(p)=Inf;
end
end
[h,i]=min(rb);%列向量比值最小值
% i+1为转轴元行号(在S中),j为转轴元列号
i=i+1;
%进行换基,转轴元置1
S(i,:)=S(i,:)./S(i,j);
%转轴元所在列其他元素都置0
for k=1:n
if(k~=i)
S(k,:)=S(k,:)-S(i,:)*S(k,j);
end
end
%判断检验数 r<=0
r=find(S(1,1:m-1)>0);
len=length(r);
end
%检验数全部非正,找到最优解
%非基变量置0
x=zeros(1,m-1);
for i=1:m-1
%找到基变量
j=find(S(:,i)==1);%每列中1的个数
k=find(S(:,i)==0);%每列中0的个数
if((length(j)+1==2)&&(length(k)+1==n))
%i为基本元列号,j是行号
x(i)=S(j,m);
end
end
y=S(1,m);%最优解
S
end
下面附带一个测试程序(test.m):
clear all
clc
f=[4 3 0 0 0];
A=[1 1 1 0 0;
1 2 0 1 0;
3 2 0 0 1];
b=[50 80 140];
[x,y]=Simplex(f,A,b)
f=[1 1 0 0];
A=[-2 1 1 0;
1 -1 0 1];
b=[4 2];
[x,y]=Simplex(f,A,b)
仿真结果如下:
单纯形方法(Simplex Method)的更多相关文章
- ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)
在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...
- Python魔术方法-Magic Method
介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...
- .NET 扩展方法(Extention Method)的要点
扩展方法Extention Method的主要介绍在:http://msdn.microsoft.com/zh-cn/library/bb383977(v=vs.100).aspx. 扩展方法的意义在 ...
- Atitit java方法引用(Method References) 与c#委托与脚本语言js的函数指针
Atitit java方法引用(Method References) 与c#委托与脚本语言js的函数指针 1.1. java方法引用(Method References) 与c#委托与脚本语言js ...
- 35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n); (2)编写一个类:ClassA来实现接口InterfaceA,实现int method(int n)接口方 法时,要求计算1到n的和; (3)编写另一个类:ClassB来实现接口InterfaceA,实现int method(int n)接口 方法时,要求计算n的阶乘(n
35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n): (2)编写一个类:ClassA来实现接口InterfaceA,实现in ...
- JVM的堆(heap)、栈(stack)和方法区(method)
JVM主要由类加载器子系统.运行时数据区(内存空间).执行引擎以及与本地方法接口等组成.其中运行时数据区又由方法区Method Area.堆Heap.Java stack.PC寄存器.本地方法栈组成. ...
- 牛顿方法(Newton-Raphson Method)
本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ 牛顿方法是一种求解等式的非常有效的数值分析方法. 1. 牛顿方法 假设\(x_0\)是等式的 ...
- (方法调配)Method Swizzling
一.概念 方法调配:因为Objective-C是运行时语言,也就是说究竟会调用何种方法要在运行期才能解析出来.那么我们其实也可以在运行时改变选择子名称.这样我们既不需要查看到源代码,又没有必要去重写子 ...
- [转]JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题: 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(h ...
随机推荐
- android 如何结束一个线程
总结: 1 不推荐直接调用onstop()强制结束,,因为不安全 2 run()比较短暂,执行完毕会自动停止 3 在run()设置一个flag标识,满足条件才执行; 4 通过sleep()捕获异常,在 ...
- TJ/T808 终端通讯协议设计与实现(码农本色)
由于公司项目涉及到相关技术,对于平常写WEB的技术人员来说对这人来说比较默生:为了让下面的技术人员更好地对这个协议的实施,所以单独针对这个协议进行了分析和设计,以更于后期更好指导相关开发工作.由于自己 ...
- DataTables 控件使用和心得 (1) - 入门
什么是DataTables DataTables是一个基于HTML/CSS/JavaScript的前端列表组件. 基于JQuery 开源并且免费(除特殊支持服务) 主要特色: 高性能,响应式,功能完整 ...
- jQuery+ASP.NET MVC基于CORS实现带cookie的跨域ajax请求
这是今天遇到的一个实际问题,在这篇随笔中记录一下解决方法. ASP.NET Web API提供了CORS支持,但ASP.NET MVC默认不支持,需要自己动手实现.可以写一个用于实现CORS的Acti ...
- WKInterfaceImage 无法更新图片的问题
最近涉及到AppleWatch的相关项目,但有个奇怪问题无法解决,而且无法理解: 根据不同的用户操作,需要修改播放器的专辑图片. 不知道跟我的项目需求是不是有关系:我需要轮询共享空间,以拿取同步数据, ...
- openseadragon.js与deep zoom java实现艺术品图片展示
openseadragon.js 是一款用来做图像缩放的插件,它可以用来做图片展示,做展示的插件很多,也很优秀,但大多数都解决不了图片尺寸过大的问题. 艺术品图像展示就是最简单的例子,展示此类图片一般 ...
- 用DirectX实现魔方(一)
关于魔方 魔方英文名字叫做Rubik's Cube,是由匈牙利建筑学教授和雕塑家Ernő Rubik于1974年发明,最初叫做Magic Cube(这大概也是中文名字的来历吧),1980年Ideal ...
- Bootstrap~多级导航(级联导航)的实现
回到目录 在bootstrap官方来说,导航最多就是两级,两级以上是无法实现的,大叔找了一些第三方的资料,终于找到一个不错的插件,使用上和效果上都还不错,现在和大家分享一下 插件地址:http://v ...
- Nodejs·理解Buffer
Node里面的Buffer其实就是用于网络请求.文件读取等等操作,而且是分配在堆外,不会占用堆内的内存,这也是因为本来V8的内存就很小,如果读取大文件,那就...... 之前有看过Logstash的B ...
- Yii2框架RESTful API教程(一) - 快速入门
前不久做一个项目,是用Yii2框架写一套RESTful风格的API,就去查了下<Yii 2.0 权威指南 >,发现上面写得比较简略.所以就在这里写一篇教程贴,希望帮助刚接触Yii2框架RE ...