作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4156685.html

使用单纯型法来求解线性规划,输入单纯型法的松弛形式,是一个大矩阵,第一行为目标函数的系数,且最后一个数字为当前轴值下的 z 值。下面每一行代表一个约束,数字代表系数每行最后一个数字代表 b 值。

算法和使用单纯性表求解线性规划相同。

对于线性规划问题:

Max      x1 + 14* x2 + 6*x3

s . t .  x1 + x2 + x3 <= 4

    x1<= 2

    x3 <= 3

    3*x2 + x3 <= 6

    x1,x2,x3 >= 0

我们可以得到其松弛形式:

Max  x1 +  14*x2 + 6*x3
s.t.   x1 +  x2   + x3   + x4 = 4
    x1               + x5 = 2
            x3           + x6 = 3
         3*x2   + x3               + x7 = 6
    x1 , x2 , x3 , x4 , x5 , x6 , x7 ≥ 0

我们可以构造单纯性表,其中最后一行打星的列为轴值。

单纯性表
x1 x2 x3 x4 x5 x6 x7 b
c1=1 c2=14 c3=6 c4=0 c5=0 c6=0 c7=0 -z=0
1 1 1 1 0 0 0 4
1 0 0 0 1 0 0 2
0 0 1 0 0 1 0 3
0 3 1 0 0 0 1 6
      * * * *  

在单纯性表中,我们发现非轴值的x上的系数大于零,因此可以通过增加这些个x的值,来使目标函数增加。我们可以贪心的选择最大的c,再上面的例子中我们选择c2作为新的轴,加入轴集合中,那么谁该出轴呢?

其实我们由于每个x都大于零,对于x2它的增加是有所限制的,如果x2过大,由于其他的限制条件,就会使得其他的x小于零,于是我们应该让x2一直增大,直到有一个其他的x刚好等于0为止,那么这个x就被换出轴。

我们可以发现,对于约束方程1,即第一行约束,x2最大可以为4(4/1),对于约束方程4,x2最大可以为3(6/3),因此x2最大只能为他们之间最小的那个,这样才能保证每个x都大于零。因此使用第4行,来对各行进行高斯行变换,使得二列第四行中的每个x都变成零,也包括c2。这样我们就完成了把x2入轴,x7出轴的过程。变换后的单纯性表为:

单纯性表
x1 x2 x3 x4 x5 x6 x7 b
c1=1 c2=0 c3=1.33 c4=0 c5=0 c6=0 c7=-4.67 -z=-28
1 0 0.67 1 0 0 -0.33 2
1 0 0 0 1 0 0 2
0 0 1 0 0 1 0 3
0 1 0.33 0 0 0 0.33 2
    * * *    

继续计算,我们得到:

单纯性表
x1 x2 x3 x4 x5 x6 x7 b
c1=-1 c2=0 c3=0 c4=0 c5=-2 c6=0 c7=0 -z=-32
1.5 0 1 1.5 0 0 -0.5 3
1 0 0 0 1 0 0 2
0 0 1 0 0 1 0 3
0 1 0.33 0 0 0 0.33 2
    * * *    

此时我们发现,所有非轴的x的系数全部小于零,即增大任何非轴的x值并不能使得目标函数最大,从而得到最优解32.

整个过程代码如下所示:

 #include <cstdio>
#include <climits>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <vector>
#include <fstream>
#include <set>
using namespace std;
vector<vector<double> > Matrix;
double Z;
set<int> P;
size_t cn, bn; bool Pivot(pair<size_t, size_t> &p)//返回0表示所有的非轴元素都小于0
{
int x = , y = ;
double cmax = -INT_MAX;
vector<double> C = Matrix[];
vector<double> B; for( size_t i = ; i < bn ; i++ )
{
B.push_back(Matrix[i][cn-]);
} for( size_t i = ; i < C.size(); i++ )//在非轴元素中找最大的c
{
if( cmax < C[i] && P.find(i) == P.end())
{
cmax = C[i];
y = i;
}
}
if( cmax < )
{
return ;
} double bmin = INT_MAX;
for( size_t i = ; i < bn ; i++ )
{
double tmp = B[i]/Matrix[i][y];
if( Matrix[i][y] != && bmin > tmp )
{
bmin = tmp;
x = i;
}
} p = make_pair(x, y); for( set<int>::iterator it = P.begin() ; it != P.end() ; it++)
{
if( Matrix[x][*it] != )
{
//cout<<"erase "<<*it<<endl;
P.erase(*it);
break;
}
}
P.insert(y);
//cout<<"add "<<y<<endl;
return true;
} void pnt()
{
for( size_t i = ; i < Matrix.size() ; i++ )
{
for( size_t j = ; j < Matrix[].size() ; j++ )
{
cout<<Matrix[i][j]<<"\t";
}
cout<<endl;
}
cout<<"result z:"<<-Matrix[][cn-]<<endl;
} void Gaussian(pair<size_t, size_t> p)//行变换
{
size_t x = p.first;
size_t y = p.second;
double norm = Matrix[x][y];
for( size_t i = ; i < cn ; i++ )//主行归一化
{
Matrix[x][i] /= norm;
}
for( size_t i = ; i < bn && i != x; i++ )
{
if( Matrix[i][y] != )
{
double tmpnorm = Matrix[i][y];
for( size_t j = ; j < cn ; j++ )
{
Matrix[i][j] = Matrix[i][j] - tmpnorm * Matrix[x][j];
}
}
}
} void solve()
{
pair<size_t, size_t> t;
while()
{ pnt();
if( Pivot(t) == )
{
return;
}
cout<<t.first<<" "<<t.second<<endl;
for( set<int>::iterator it = P.begin(); it != P.end() ; it++ )
{
cout<<*it<<" ";
}
cout<<endl;
Gaussian(t);
}
} int main(int argc, char *argv[])
{
ifstream fin;
fin.open("./test");
fin>>cn>>bn;
for( size_t i = ; i < bn ; i++ )
{
vector<double> vectmp;
for( size_t j = ; j < cn ; j++)
{
double tmp = ;
fin>>tmp;
vectmp.push_back(tmp);
}
Matrix.push_back(vectmp);
} for( size_t i = ; i < bn- ; i++ )
{
P.insert(cn-i-);
}
solve();
}
/////////////////////////////////////
//glpk input:
///* Variables */
//var x1 >= 0;
//var x2 >= 0;
//var x3 >= 0;
///* Object function */
//maximize z: x1 + 14*x2 + 6*x3;
///* Constrains */
//s.t. con1: x1 + x2 + x3 <= 4;
//s.t. con2: x1 <= 2;
//s.t. con3: x3 <= 3;
//s.t. con4: 3*x2 + x3 <= 6;
//end;
/////////////////////////////////////
//myinput:
//8 5
//1 14 6 0 0 0 0 0
//1 1 1 1 0 0 0 4
//1 0 0 0 1 0 0 2
//0 0 1 0 0 1 0 3
//0 3 1 0 0 0 1 6
/////////////////////////////////////

单纯形法C++实现的更多相关文章

  1. BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记】

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Stat ...

  2. BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]

    传送门 题意: 长为$n$的序列,第$i$位至少$b_i$,$m$种区间使$[l_i,r_i]+1$代价为$a_i$ 求满足的最小花费 复习单纯形法重做一遍 原始问题$m$个变量$n$个约束,$a_{ ...

  3. 智能优化 之 下山单纯形法 C++

    单纯形法简介在其他网站上都可以查到,我就不多说了 我们主要说方法 它主要解决的是局部最优解的问题 利用多边形进行求解的,若有n个变量,则利用n+1边形 我们这里以两个变量为例,求解第三维度的最优解 例 ...

  4. 单纯形法MATALAB实现

    参考单纯形法的步骤,MATALAB中的实现如下(求极小值): 注:对于极大值的求解,只需要对目标函数添加负号,求解出来的\(X\),再带入原目标函数即可. function [ X, z ] = si ...

  5. BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记看另一篇吧】

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Stat ...

  6. 能用的单纯形法python代码

    网上找了一些代码,发现有一些是不能用的,出现错误说集合为空 1.网上出现了好多次,但是不能用的,只能部分模型能用,比如例子中所示 原链接:https://www.jianshu.com/p/b233c ...

  7. POJ1275 Cashier Employment[差分约束系统 || 单纯形法]

    Cashier Employment Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7997   Accepted: 305 ...

  8. BZOJ 3112: [Zjoi2013]防守战线 [单纯形法]

    题目描述 战线可以看作一个长度为n 的序列,现在需要在这个序列上建塔来防守敌兵,在序列第i 号位置上建一座塔有Ci 的花费,且一个位置可以建任意多的塔,费用累加计算.有m 个区间[L1, R1], [ ...

  9. BZOJ 3550: [ONTAK2010]Vacation [单纯形法]

    有3N个数,你需要选出一些数,首先保证任意长度为N的区间中选出的数的个数<=K个,其次要保证选出的数的个数最大. 好像都是费用流... 单纯性裸题呀... 注意每个数最多选1次 #include ...

随机推荐

  1. iOS开发——网络编程Swift篇&(三)同步Get方式

    同步Get方式 // MARK: - 同步Get方式 func synchronousGet() { //创建NSURL对象 var url:NSURL! = NSURL(string: " ...

  2. SQL Server 2012 Express LocalDB

    微软最新推出的 SQL Server 2012 Express LocalDB 是一种 SQL Server Express 的运行模式,特别适合用在开发环境使用,也内置在 Visual Studio ...

  3. Mac电脑没有声音,苹果电脑没有声音怎么办

      对于使用 Windows 系统电脑的小伙伴来说,可能有很多人会遇到电脑没有声音的问题.苹果 Mac 电脑也会出现没有声音的问题,不过相对较少.这里以我遇到的一个没有声音的问题为例,简单介绍处解决的 ...

  4. C++_直接插入排序(纯C版)

    //用于比较大小 int compared(const void *key1,const void *key2) { cout<<"enter compare"< ...

  5. hdu1051 Wooden Sticks

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1051 大意:求最少升序序列的个数. #include <cstdio> #include &l ...

  6. MII接口全家福

    转载:http://blog.chinaunix.net/uid-24148050-id-131084.html 简介:    MII是英文Medium Independent Interface的缩 ...

  7. Linux shell 脚本攻略之文件查找与文件列表

    摘自:<Linux shell 脚本攻略>

  8. ORACLE 导入导出操作

    1.导入命令: imp userId/psw@orcl full=y  file=D:\data\xxx.dmp ignore=y 2.导出命令 exp userId/psw@orcl file=d: ...

  9. 对x264_macroblock_cache_load的理解

    X264版本: 2004/06/03 函数作用: 将编码该宏块所需的信息加载到mb.pic.mb.cache两个结构体中,记录相邻宏块的存在性. 函数过程: 初始化坐标信息,这些坐标信息将在下面用作下 ...

  10. Mac 10.9 自带apache2虚拟目录设置

    花了好几天时间做这个事,终于成功,把正确的做法记录一下. 如果是第一次使用apache,可以先执行sudo apachectl start,然后在浏览器里打开http://localhost看看效果, ...