MatLab线性规划

前言

1.使用MatLab求解线性规划需要安装Optimization Toolbox附加功能
2.本文总结了教材《数学建模算法与应用(司守奎)》第1章的内容,详情请参考教材
3.本文总结了二维线性规划问题,如何使用MatLab快速解决,教材对于这部分问题推荐使用Lingo,但其实MatLab也可以解决
如果不需要复习教材《数学建模算法与应用(司守奎)》第1章,请直接跳到目录最后一节

MatLab线性规划标准形式

min f(x)
A·x <= b
Aeq·x = beq
lb <= x <= ub

对标准形式的解释

x:决策变量,所有直接或间接影响"价值"的变量都是决策变量
f:价值向量,描述决策变量对"价值"影响权重的变量
A和b:线性不等式约束,A是一个矩阵,b是一个列向量
Aeq和beq:线性等式约束,Aeq是一个矩阵,beq是一个列向量
lb和ub:决策变量的下界向量和上界向量,代表决策变量的取值范围,为列向量

对于最大化价值的线性规划问题max f(x),有以下转化公式:

max f(x) = min -f(x)

例:求x + 3y的最大值,相当于求-x - 3y的最小值

MatLab求解线性规划的函数

>>  linprog(f, A, b, Aeq, beq, lb, ub);

linprog()函数返回最佳决策变量和最佳决策变量对应的最小价值

该函数的参数可以不写完整,以下都是合法的调用格式

[x, fval] = linprog(f, A, b);
[x, fval] = linprog(f, A, b, Aeq, beq);
[x, fval] = linprog(f, A, b, Aeq, beq, lb, ub);

注意
1.当没有线性不等式约束,但有线性等式约束时,要在A和b位置传入空矩阵

[x, fval] = linprog(f, [], [], Aeq, beq);

2.如果决策变量下界为0,使用zeros()函数快速生成下界向量lb
zeros(m, n) 生成m * n的全0矩阵

lb = zeros(n, 1);
[x, fval] = linprog(f, A, b, Aeq, beq, lb, ub);

3.使用inf()函数快速生成上界向量ub
inf(m, n) 生成m * n的全inf矩阵
Inf是正无穷大

ub = inf(n, 1);
[x, fval] = linprog(f, A, b, Aeq, beq, lb, ub);

带有绝对值的线性规划

min f(|x|)
A · x <= b

对于带有绝对值的线性规划,需要去绝对值,转换为等价的线性规划

去绝对值的方法

对决策变量作线性变换:

x = u - v
|x| = u + v
(u, v >= 0)

线性变换后得到的新决策变量:

x’ = [u; v]

转化后的等效线性规划:

min f(u + v) = [f, f] x’
A · (u - v) <= b即[A, -A] · x’ <= b
x’ >= 0

解决带绝对值的线性规划的伪码描述

设有n个决策变量,去绝对值后的新决策变量有2n个,且新决策变量必有下界0(u, v >= 0)

f = [...];					//初始化价值向量
A = [...]; b = [...]		//初始化线性不等式约束
Aeq = [...]; beq = [...]	//初始化线性不等式约束
f = [f; f];					//价值向量被延长一倍
A = [A, -A];
Aeq = [Aeq, -Aeq];			//约束矩阵被延长一倍
//为什么延长的价值向量不带符号,而延长的约束矩阵带符号,这是由上文"转化后的等效线性规划"决定的
lb = zeros(2n, 1);			//新决策变量必有下界0,注意新决策变量有2n个

二维线性规划

形式如下的线性规划,被称为二维线性规划

min ∑xij, i <= m && j <= n

对于二维动态规划,决策变量是二维的,所以价值向量变成了价值矩阵,约束矩阵等也相应地进行了升维
Lingo可以很方便对二维动态规划进行处理,MatLab不行,所以要把m * n的二维线性规划,转换成等价的l(l = m * n)变量的一维线性规划(保持决策变量数量不变)

MatLab处理时可以使用以下技巧,把二维线性规划转化为一维线性规划:
前文提到:数学建模第二天,MatLab矩阵入门
矩阵元素的编址有下标编址序号编址两种,实际上序号编址方式,就是在逻辑上对矩阵降维打击,把矩阵当成向量进行访问,矩阵的下标编址和序号编址是一一对应的,这使我们可以很方便进行转换

例:把2 * 3的价值矩阵A转换成等价价值向量

>> A = A(:);

同理,对于每一个线性不等式约束和线性等式约束,我们都采用A = A( : );指令,进行降维
当数据量不大时,也可以手动输入线性约束矩阵

注意:要降维的矩阵,初始化时要初始化成矩阵的转置
例:某线性规划有决策变量有5 * 4 =20个,初始化其价值矩阵max z = 1.15x(4, 1) + 1.4x(2, 3) + 1.25x(3, 2) + 1.06x(5, 4),并将其转换为价值向量

>> f = zeros(4, 5);
>> f(1, 4) = 1.15;
>> f(3, 2) = 1.4;
>> f(2, 3) = 1.25;
>> f(4, 5) = 1.06;
>> f = f(:);

可以看出,价值矩阵应该是5 * 4的,但我们将其初始化为4 * 5的转置矩阵,这样做是因为MatLab中的矩阵是以列向量为单位进行存储和寻访的,初始化为转置矩阵保证了寻访顺序的一致

对于约束矩阵,对每一行都进行一次降维处理,具体的处理方式和价值矩阵同理

例:初始化m * n个决策变量的约束矩阵,设一共有c个约束方程
伪码描述:

//初始化约束矩阵
>> A = zeros(c, m * n);
//对每个约束方程对应的行向量都要进行降维
for cnt = 1:c
	//初始化行向量
	>> row = zeros(n, m);
	//赋初值
	>> row(j1, i1) = ...;
	>> row(j2, i2) = ...;
	...
	//降维行向量
	>> row = row(:);
	//更新约束矩阵第cnt行的系数
	A(cnt, :) = row;
end

虽然写的是循环结构,但实际上row赋初值的过程是没办法用循环结构实现的
当线性规划的所有参数都降维后就可以直接调用linprog()函数了

最后,如果想让最佳决策值向量恢复为矩阵,则需要进行升维:

>> mat = zeros(m,  n);
>> row = zeros(1, n);
>> for i = 1:m
>>    for j = 1:n
>>        row(j) = x((i - 1) * n + j);
>>    end
>>    mat(i, :) = row;
>> end
>> mat

或者调用reshape函数进行向量升维:

>> mat = reshape(mat, m, n);
  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值