前面一篇讲的单纯形方法的实现,但程序输入的必须是已经有初始基本可行解的单纯形表。

但实际问题中很少有现成的基本可行解,比如以下这个问题:

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)的更多相关文章

  1. 自适应阈值二值化之最大类间方差法(大津法,OTSU)

    最大类间方差法是由日本学者大津(Nobuyuki Otsu)于1979年提出的,是一种自适应的阈值确定的方法,又叫大津法,简称OTSU.它是按图像的灰度特性,将图像分成背景和目标2部分.背景和目标之间 ...

  2. 大津法---OTSU算法

    简介: 大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出.从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景 ...

  3. 自适应阈值分割—大津法(OTSU算法)C++实现

    大津法是一种图像灰度自适应的阈值分割算法,是1979年由日本学者大津提出,并由他的名字命名的.大津法按照图像上灰度值的分布,将图像分成背景和前景两部分看待,前景就是我们要按照阈值分割出来的部分.背景和 ...

  4. 大O法时间复杂度计算

    困惑的点——log,如何计算得出? ① 上限:用来表示该算法可能有的最高增长率. ② 大O表示法:如果某种算法的增长率上限(最差情况下)是f(n),那么说这种算法“在O(f(n))中”.n为输入规模. ...

  5. OSTU大津法图像分割

    OSTU图像分割 最大类间方差法,也成大津法OSTU,它是按图像的灰度特性,将图像分成背景和目标2部分.背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分 ...

  6. 运筹学笔记12 大M法

    引入M,其中M是一个充分大的正数.由此,目标函数也改变为zM. 如此构造的线性规划问题我们记作LPM,称之为辅助线性规划问题,也即在原来的线性规划问题的基础上,改造了其等式约束条件,然后有对目标函数施 ...

  7. 简单工厂法( Factory Method)

    工厂方法 (Factory Method) Define an interface for creating an object ,but let subclasses decide which cl ...

  8. 关于大O法的几点解释

    大O表示法指出算法有多快.例如,假设列表包含n个元素.简单查找需要检查每个元素,因此需要执行n次操作.使用大O表示法,这个运行时间为O(n).主要单位不是秒啊,大O表示法值得并非以秒为单位的速度,而是 ...

  9. OTSU大津法对图像二值化

    OTSU算法 (1)原理: 对于图像I(x,y),前景(即目标)和背景的分割阈值记作T,属于背景的像素个数占整幅图像的比例记为ω0,其平均灰度μ0:前景像素个数占整幅图像的比例为ω1,其平均灰度为μ1 ...

随机推荐

  1. javascript Xml兼容性随笔

    一.前言 (function (window) { if (!window.jasen) { window.jasen = {}; } if (!window.jasen.core) { window ...

  2. OC中的自动引用计数

    目录: 1,自动引用计数的定义 2,强引用和弱引用 3,类比手动引用 4,循环引用 5,CoreFoundation 内容: 自动引用计数的定义: (Automatic Reference Count ...

  3. 旺信UWP倒计时

    Bug数量: 2016/3/8: 34 2016/3/9: 40(一堆新Bug到来) 2016/3/10: 21(邀请用户内测,一大波虫子即将到来) 2016/3/11: 10(预期的一大波Bug还没 ...

  4. 开源项目asmjit——调用自定义方法demo以及windbg调试

    asmjit是一个开源项目,使用它可以将代码即时的编译成机器码,也就是所谓的jit技术. 初次接触这个项目,编写了一个demo,学习它的使用方法. 现将编写的demo以及调试jit生成的机器码的过程总 ...

  5. java提高篇(十八)-----数组之一:认识JAVA数组

          噢,它明白了,河水既没有牛伯伯说的那么浅,也没有小松鼠说的那么深,只有自己亲自试过才知道!道听途说永远只能看到表明现象,只有亲自试过了,才知道它的深浅!!!!! 一.什么是数组      ...

  6. IOS 推送-客户端处理推送消息

    IOS 推送-客户端处理推送消息 1.推送调用顺序 APN push的消息到达后,UIApplicationDelegate有两个方法和处理消息有关: 1)application:didReceive ...

  7. Objective-C 随机数

    有个项目要给客户发送随机验证码, 试了下这样可以 srand(time()); code = [NSString stringWithFormat: - )) + ];

  8. 将不确定变为确定~transactionscope何时提升为分布式事务?(sql2005数据库解决提升到MSDTC的办法)

    回到目录 对于transactionscope不了解的同学,可以看我的相关文章 第二十六回   将不确定变为确定~transactionscope何时提升为分布式事务? 第二十七回   将不确定变为确 ...

  9. Atitit  数据存储的分组聚合 groupby的实现attilax总结

    Atitit  数据存储的分组聚合 groupby的实现attilax总结 1. 聚合操作1 1.1. a.标量聚合 流聚合1 1.2. b.哈希聚合2 1.3. 所有的最优计划的选择都是基于现有统计 ...

  10. Atitit 常用比较复杂的图像滤镜 attilax大总结

    Atitit 常用比较复杂的图像滤镜 attilax大总结 像素画滤镜 水彩油画滤镜 素描滤镜 梦幻镜 特点是中央集焦,周围景物朦化微带光晕,使人产生如入梦境的感觉.常用于拍摄婚纱.明星照,也用于其它 ...