大M法(Big M Method)
前面一篇讲的单纯形方法的实现,但程序输入的必须是已经有初始基本可行解的单纯形表。
但实际问题中很少有现成的基本可行解,比如以下这个问题:
min f(x) = –3x1 +x2 + x3
s.t. x1 – 2x2 + x3 + x4=11
-4x1 + x2 + 2x3 - x5=3
-2x1+x3=1
xj>=0 , j=1,2,3,4,5
写成单纯形表就是
| x1 | x2 | x3 | x4 | x5 | b | |
| f | 3 | -1 | -1 | 0 | 0 | 0 |
| 1 | -2 | 1 | 1 | 0 | 11 | |
| -4 | 1 | 2 | 0 | -1 | 3 | |
| -2 | 0 | 1 | 0 | 0 | 1 |
很难找到秩为3的基阵,更不用说直接出现3阶单位阵了。在实际问题中,尤其是约束条件变多时,找到基阵甚至是判定A是否满秩都十分困难,因此在程序中引入大M法(Big M Method)来获得初始的基本可行解,这样我们能处理的问题就更加多样化了。
上篇已经说过,对于m*n的矩阵A来说,找到一个m*m 的满秩方阵就能得到基本可行解,但是在这么多列向量中怎样挑出m个线性无关的向量来组成一个满秩方阵呢?如果找起来麻烦的话,不如直接添加一个m阶单位阵来的方便!
大M法
大M法又称惩罚法,它是在目标函数中添加m个人工变量M*x(M是一个任意大的正数),同时在A矩阵中添加一个m阶单位矩阵。

这样一来新的A矩阵中就有了一个m*m满秩方阵,满足单纯形法求解的初始要求,但是若要得到最小值f(x),新添加的人工变量的值必然是0的,因为M可以是很大的数,如果Xn+1不为0,f(x)可能会很大,如果无法做到令人工变量取0值,那么原问题就无可行解。
需要注意的是,添加完人工变量之后,人工变量构成一组可行解的基变量,但单纯形初始矩阵要求基变量对应的检验数为0,故需要做行变换把基变量对应的检验数置0。
例如,本文开始引入的问题经过添加人工变量后变为
| x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | b | |
| f | 3 | -1 | -1 | 0 | 0 | -M | -M | -M | 0 |
| x6 | 1 | -2 | 1 | 1 | 0 | 1 | 0 | 0 | 11 |
| x7 | -4 | 1 | 2 | 0 | -1 | 0 | 1 | 0 | 3 |
| x8 | -2 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
再进行行变换把基变量x6,x7,x8对应的检验数置0,得到:
| x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | b | |
| f | 3-5M | -1-M | -1+4M | 0 | 0 | 0 | 0 | 0 | 0 |
| x6 | 1 | -2 | 1 | 1 | 0 | 1 | 0 | 0 | 11 |
| x7 | -4 | 1 | 2 | 0 | -1 | 0 | 1 | 0 | 3 |
| x8 | -2 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
进行完这步之后,就回到了单纯形法求解的基本问题,利用原来的算法继续计算就好了。
Matlab实现
BigM.m
function [ x,y ] = BigM( f,A,b )
%输入f是检验数的数组,1*n维
%输入A是约束矩阵, m*n维
%输入b是约束向量, 1*m维
%输出x是解向量
%输出y是最优解
%判断输入维数是否相符
%做初始单纯形表,加入M变量
[n,m]=size(A);%n行m列
M=10000;
S=[f -1*M*ones(1,n) 0;
A eye(n) b'];
format rat %将结果以分数表示
[n,m]=size(S);
%将人工变量的检验数置零
for k=1:n-1
S(1,:)=S(1,:)+S(k+1,:)*M;
end
%判断检验数 r<=0
r=find(S(1,1:m-1)>0);
len=length(r);
flag=0;
%有大于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));
%最大值所在列比值为正数且最小值br/a_rk
br=S(2:n,m)./S(2:n,j);
%把比值中的负数都变无穷
for p=1:length(br)
if(br(p)<0)br(p)=Inf;
end
end
[h,i]=min(br);%列向量比值最小值
% 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);
% %调试用,控制循环步数
% if(len>0)flag=flag+1;end
% if(flag==2)break;end
% S
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
测试程序:
f=[3 -1 -1 0 0];
A=[1 -2 1 1 0;
-4 1 2 0 -1;
-2 0 1 0 0 ];
b=[11 3 1 ];
[x,y]=BigM(f,A,b)
f=[5 2 3 -1];
A=[1 2 3 0 ;
2 1 5 0 ;
1 2 4 1 ];
b=[15 20 26];
[x,y]=BigM(f,A,b)
f=[5 10 0 0 0 ];
A=[1/14 1/7 1 0 0;
1/7 1/12 0 1 0;
1 1 0 0 1 ];
b=[1 1 8];
[x,y]=BigM(f,A,b)
[x,y]=Simplex(f,A,b)
计算结果:



大M法(Big M Method)的更多相关文章
- 自适应阈值二值化之最大类间方差法(大津法,OTSU)
最大类间方差法是由日本学者大津(Nobuyuki Otsu)于1979年提出的,是一种自适应的阈值确定的方法,又叫大津法,简称OTSU.它是按图像的灰度特性,将图像分成背景和目标2部分.背景和目标之间 ...
- 大津法---OTSU算法
简介: 大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出.从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景 ...
- 自适应阈值分割—大津法(OTSU算法)C++实现
大津法是一种图像灰度自适应的阈值分割算法,是1979年由日本学者大津提出,并由他的名字命名的.大津法按照图像上灰度值的分布,将图像分成背景和前景两部分看待,前景就是我们要按照阈值分割出来的部分.背景和 ...
- 大O法时间复杂度计算
困惑的点——log,如何计算得出? ① 上限:用来表示该算法可能有的最高增长率. ② 大O表示法:如果某种算法的增长率上限(最差情况下)是f(n),那么说这种算法“在O(f(n))中”.n为输入规模. ...
- OSTU大津法图像分割
OSTU图像分割 最大类间方差法,也成大津法OSTU,它是按图像的灰度特性,将图像分成背景和目标2部分.背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分 ...
- 运筹学笔记12 大M法
引入M,其中M是一个充分大的正数.由此,目标函数也改变为zM. 如此构造的线性规划问题我们记作LPM,称之为辅助线性规划问题,也即在原来的线性规划问题的基础上,改造了其等式约束条件,然后有对目标函数施 ...
- 简单工厂法( Factory Method)
工厂方法 (Factory Method) Define an interface for creating an object ,but let subclasses decide which cl ...
- 关于大O法的几点解释
大O表示法指出算法有多快.例如,假设列表包含n个元素.简单查找需要检查每个元素,因此需要执行n次操作.使用大O表示法,这个运行时间为O(n).主要单位不是秒啊,大O表示法值得并非以秒为单位的速度,而是 ...
- OTSU大津法对图像二值化
OTSU算法 (1)原理: 对于图像I(x,y),前景(即目标)和背景的分割阈值记作T,属于背景的像素个数占整幅图像的比例记为ω0,其平均灰度μ0:前景像素个数占整幅图像的比例为ω1,其平均灰度为μ1 ...
随机推荐
- 第二次作业:Github的优点和缺点
---恢复内容开始--- GitHub的优势和劣势 简介: Github是一个代码托管平台和开发者社区,开发者可以在Github上创建自己的开源项目并与其他开发者协作编码.创业公司可以用它来托管软件项 ...
- Form认证的几点说明
有的页面需要用户认证之后才可以进入,通常都是在Filter的OnActionExecuting方法中我们需要获取当前用户.有两种情况不必登录:1.用户是登录的,也就是认证过的.2.用户上次登录了,但没 ...
- [ACM_几何] The Deadly Olympic Returns!!! (空间相对运动之最短距离)
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28235#problem/B 题目大意: 有两个同时再空间中匀速运动的导弹,告诉一个时间以 ...
- CSS media queries
最近在做一些页面打印时的特殊处理接触到了media queries,想系统学习一下,在MOZILLA DEVELOPER NETWORK看到一篇文章讲的很不错,结合自己的使用总结一下. CSS2/me ...
- C++函数指针
然后,我在想C++函数指针到底有啥用呢.想了又想,我想出来一种,就是将函数地址(函数n)作为函数(函数1)的参数时,便可以在访问函数1的时候就决定了,在函数1里面调用的是哪一个函数(函数1,2,3,4 ...
- H5 调用摄像头
WebRTC(Web Real-Time Communication,网页实时通信),是一个支持网页浏览器进行实时语音对话或视频对话的API. 1.getUserMedia 要播放摄像头的影像,首先需 ...
- PHP面向对象04_串行化
oop04复习 2014-9-3 10:48:45 要点: --1.克隆对象 --2.__toString( ) --3. __call( ) --4.自动加载类 --5.对象串行化 1.克隆对象以及 ...
- lua表排序
对于lua的table排序问题,一般的按照value值来排序,使用table.sort( needSortTable , func)即可(可以根据自己的需要重写func,否则会根据默认来:默认的情形之 ...
- C#并行编程-Task
菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...
- mysql创建数据库指定编码uft8
mysql创建数据库指定编码uft8 CREATE DATABASE IF NOT EXISTS my_db default character set utf8 COLLATE utf8_gener ...