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

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

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. 第二次作业:Github的优点和缺点

    ---恢复内容开始--- GitHub的优势和劣势 简介: Github是一个代码托管平台和开发者社区,开发者可以在Github上创建自己的开源项目并与其他开发者协作编码.创业公司可以用它来托管软件项 ...

  2. Form认证的几点说明

    有的页面需要用户认证之后才可以进入,通常都是在Filter的OnActionExecuting方法中我们需要获取当前用户.有两种情况不必登录:1.用户是登录的,也就是认证过的.2.用户上次登录了,但没 ...

  3. [ACM_几何] The Deadly Olympic Returns!!! (空间相对运动之最短距离)

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28235#problem/B 题目大意: 有两个同时再空间中匀速运动的导弹,告诉一个时间以 ...

  4. CSS media queries

    最近在做一些页面打印时的特殊处理接触到了media queries,想系统学习一下,在MOZILLA DEVELOPER NETWORK看到一篇文章讲的很不错,结合自己的使用总结一下. CSS2/me ...

  5. C++函数指针

    然后,我在想C++函数指针到底有啥用呢.想了又想,我想出来一种,就是将函数地址(函数n)作为函数(函数1)的参数时,便可以在访问函数1的时候就决定了,在函数1里面调用的是哪一个函数(函数1,2,3,4 ...

  6. H5 调用摄像头

    WebRTC(Web Real-Time Communication,网页实时通信),是一个支持网页浏览器进行实时语音对话或视频对话的API. 1.getUserMedia 要播放摄像头的影像,首先需 ...

  7. PHP面向对象04_串行化

    oop04复习 2014-9-3 10:48:45 要点: --1.克隆对象 --2.__toString( ) --3. __call( ) --4.自动加载类 --5.对象串行化 1.克隆对象以及 ...

  8. lua表排序

    对于lua的table排序问题,一般的按照value值来排序,使用table.sort( needSortTable , func)即可(可以根据自己的需要重写func,否则会根据默认来:默认的情形之 ...

  9. C#并行编程-Task

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  10. mysql创建数据库指定编码uft8

    mysql创建数据库指定编码uft8 CREATE DATABASE IF NOT EXISTS my_db default character set utf8 COLLATE utf8_gener ...