大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 ...
随机推荐
- javascript Xml兼容性随笔
一.前言 (function (window) { if (!window.jasen) { window.jasen = {}; } if (!window.jasen.core) { window ...
- OC中的自动引用计数
目录: 1,自动引用计数的定义 2,强引用和弱引用 3,类比手动引用 4,循环引用 5,CoreFoundation 内容: 自动引用计数的定义: (Automatic Reference Count ...
- 旺信UWP倒计时
Bug数量: 2016/3/8: 34 2016/3/9: 40(一堆新Bug到来) 2016/3/10: 21(邀请用户内测,一大波虫子即将到来) 2016/3/11: 10(预期的一大波Bug还没 ...
- 开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit是一个开源项目,使用它可以将代码即时的编译成机器码,也就是所谓的jit技术. 初次接触这个项目,编写了一个demo,学习它的使用方法. 现将编写的demo以及调试jit生成的机器码的过程总 ...
- java提高篇(十八)-----数组之一:认识JAVA数组
噢,它明白了,河水既没有牛伯伯说的那么浅,也没有小松鼠说的那么深,只有自己亲自试过才知道!道听途说永远只能看到表明现象,只有亲自试过了,才知道它的深浅!!!!! 一.什么是数组 ...
- IOS 推送-客户端处理推送消息
IOS 推送-客户端处理推送消息 1.推送调用顺序 APN push的消息到达后,UIApplicationDelegate有两个方法和处理消息有关: 1)application:didReceive ...
- Objective-C 随机数
有个项目要给客户发送随机验证码, 试了下这样可以 srand(time()); code = [NSString stringWithFormat: - )) + ];
- 将不确定变为确定~transactionscope何时提升为分布式事务?(sql2005数据库解决提升到MSDTC的办法)
回到目录 对于transactionscope不了解的同学,可以看我的相关文章 第二十六回 将不确定变为确定~transactionscope何时提升为分布式事务? 第二十七回 将不确定变为确 ...
- Atitit 数据存储的分组聚合 groupby的实现attilax总结
Atitit 数据存储的分组聚合 groupby的实现attilax总结 1. 聚合操作1 1.1. a.标量聚合 流聚合1 1.2. b.哈希聚合2 1.3. 所有的最优计划的选择都是基于现有统计 ...
- Atitit 常用比较复杂的图像滤镜 attilax大总结
Atitit 常用比较复杂的图像滤镜 attilax大总结 像素画滤镜 水彩油画滤镜 素描滤镜 梦幻镜 特点是中央集焦,周围景物朦化微带光晕,使人产生如入梦境的感觉.常用于拍摄婚纱.明星照,也用于其它 ...