LP线性规划求解 之 单纯形 算法
LP线性规划求解 之 单纯形 算法
认识-单纯形
- 核心: 顶点旋转
随机找到一个初始的基本可行解
不断沿着可行域旋转(pivot)
重复2,直到结果不能改进为止
案例-过程
以上篇的case2的松弛型为例.
\(min \ y = -x1-x2\)
s.t.
\(50x1 + 20x2 + a1 = 2000 \\ -1.5x1+x2 + a2 =0 \\ x1-x2+a3=0 \\ x1,x2,a1,a2,a3 >=0\\ 其中a1,a2,a3为松弛变量\)
即:
基本变量(松弛): a1, a2, a3
非基本变^量: x1, x2
\(min \ y=-x1-x2\\ s.t.\)
\(a1 = 2000-50 x1-20 x2 \\ a2 = 1.5x1 -x2 \\ a3 = -x1+x2 \\ x1,x2,a1,a2,a3 >=0\)
基本可行解即将右边非基本变量设置为0, 计算左边基本变量(松弛)的值
令: x1, x2为0, 即基本可行解为:
\(x^t = (0,0,2000,0,0)^t, 目标值y= (-x1-x2) = 0\)
旋转(pivot)流程
替入变量: 当前目标函数中第一个系数为负的非基本变量(松弛)为替入变量
替出变量: 最严格约束里的基本变量为替出变量
即:
x1 是目标函数中第一个系数为负数(替入变量), 计算x1在各条件下的约束值
case1: x1 = 40
case2: x1 = \(\infty\)
case3: x1 = 0
得到条件3为最严格约束, 即对应的a3为替出变量.
即由 \(a3 = -x1+x2 \ 得 x1 = x2-a3\)
对原目标及约束中的x1进行替换即:
\(min \ y = -2x2+a3 \\ s.t.\)
\(x1 = x2-a3 \\ a1 = 2000-50(x2-a3) - 20x2 = 2000 - 70x2 + 50a3 \\ a2 = 1.5(x2 - a3) - x2 = 0.5x2 - 1.5a3\)
然后旋转,令右边变量为0, 即:
\(x = (0,0,0,2000,0)^t, 目标y=0\)
发现目标值y没有变小, 于是再继续转
目标中第一为负的是x2, 其在各条件下的约束值为
case1: \(x2 =\infty\)
case2: \(x2 = \frac {2000}{70}\)
case3: \(x2 = \infty\)
得到条件2为最严格约束, 即对应的a1为替出变量.
即由\(a1 = 2000-70x2+50a3 \ 得 \ x2 = \frac {2000 + 50a3 -a1}{70}\)
对原目标的x2作替换即:
\(min \ y = \frac{-4000}{70} - \frac{3}{7} a3 + \frac{1}{35}xa1 \\ s.t.\)
\(x1 =\frac{2000}{70} - \frac{2}{7}a3- \frac{1}{70}a1 \\ x2 = \frac {2000 + 50a3 -a1}{70} \\ a2 = \frac {1000}{70} - \frac {16}{14}a3 - \frac {1}{140}a1\)
然后再旋转, 令右边的变量为0, 即:
\(x = (\frac {200}{70}, \frac {2000}{70}, 0, \frac{1000}{70},0), 目标 \ y = - \frac{4000}{70}\)
然后再继续旋转...
....
当目标函数没有系数为负, 即说明无法再通过旋转继续减小目标函数, 此时收敛,即停止旋转, 此时的基本解即为最优解.
最后得 \(x = (25,37,5,12.5,0,0), 达到最优解目标 \ min \ y = -62.5\)
单纯形算法步骤(参考网上)
将LP的目标函数及约束转为标准型
转换为松弛型 (即将不等于转为等于)
找到一个基本可行解, 寻找目标的替入变量, 约束的替出变量, 替换目标函数, 不断旋转
重复步骤3, 直到目标系数中没有系数为负数的项, 收敛, 即结束算法
(附) Python代码实现
- 是搬运大佬的代码, 自己有很多也尚未看明白, 只作个笔记, 当然还是为了copy
- 个人觉得这个大佬的代码,追求简洁但严重丢失了可读性, PEP8呢
- 注释 是后面加的, 当然,原来的版本也基本没啥注释, 很是任性
import numpy as np
class Simplex(object):
def __init__(self, obj, max_mode=False):
self.max_mode = max_mode # 默认是求min,如果是max目标函数要乘-1
self.mat = np.array([[0] + obj]) * (-1 if max_mode else 1)
def add_constraint(self, a, b):
self.mat = np.vstack([self.mat, [b] + a]) #矩阵加入约束
def solve(self):
m, n = self.mat.shape # 矩阵里有1行目标函数,m - 1行约束,应加入m-1个松弛变量
temp, B = np.vstack([np.zeros((1, m - 1)), np.eye(m - 1)]), list(range(n - 1, n + m - 1)) # temp是一个对角矩阵,B是个递增序列
mat = self.mat = np.hstack([self.mat, temp]) # 横向拼接
#判断目标函数里是否还有负系数项
while mat[0, 1:].min() < 0:
# 在目标函数里找到第一个负系数的变量,找到替入变量
col = np.where(mat[0, 1:] < 0)[0][0] + 1
row = np.array([mat[i][0] / mat[i][col] if mat[i][col] > 0 else 0x7fffffff for i in
range(1, mat.shape[0])]).argmin() + 1 # 找到最严格约束的行,也就找到替出变量
if mat[row][col] <= 0: return None # 若无替出变量,原问题无界
mat[row] /= mat[row][col] #替入变量和替出变量互换
ids = np.arange(mat.shape[0]) != row
# 对i!= row的每一行约束条件,做替入和替出变量的替换
mat[ids] -= mat[row] * mat[ids, col:col + 1]
B[row] = col #用B数组记录替入的替入变量
return mat[0][0] * (1 if self.max_mode else -1), {B[i]: mat[i, 0] for i in range(1, m) if B[i] < n} #返回目标值,对应x的解就是基本变量为对应的bi,非基本变量为0
"""
minimize -x1 - 14x2 - 6x3
st
x1 + x2 + x3 <=4
x1 <= 2
x3 <= 3
3x2 + x3 <= 6
x1 ,x2 ,x3 >= 0
answer :-32
"""
t = Simplex([-1, -14, -6])
t.add_constraint([1, 1, 1], 4)
t.add_constraint([1, 0, 0], 2)
t.add_constraint([0, 0, 1], 3)
t.add_constraint([0, 3, 1], 6)
print(t.solve())
print(t.mat)
调参侠求解LP
这里以为case2作为例子, 化为minimize标准型哦.
\(min \ z = -x1 - x2 \\ s.t.\)
\(x1-x2<0 \\ -1.5x1 + x2 <= 0 \\ 50x1+20x2 <= 2000 \\ x1,x2 >=0\)
api: from scipy.optimize import linprog
我一般都是用pycharm来看源码的api文档, 这样会印象深刻一下.
c: 目标函数(minimize)的系数, 1D-array
A_ub: 左边不等号相关的系数矩阵 2D-array
b_ub: 即A_up中的对应行的右边值 1D-array
A_eq: 左边等号相关的系数矩阵 2D-array
b_eq: 即A_eq中的对应行的右边值 1D-array
bounds: sequence
- (min, max) pairs for each element in "X"
from scipy.optimize import linprog
import numpy as np
# 1. 目标函数系数
c = np.array([-1, -1])
# 2. 不等号
A_ub = np.array([[-1.5, 1], [50, 20]])
b_ub = np.array([0, 2000])
# 3. 等号(此题没有A_eq, b_eq)
# 4. bounds
limit_1, limit_2 = (0, None), (0, None)
# 5. solve: default "simplex"
ret = linprog(c, A_ub, b_ub, bounds(limit_1, limit_2))
print(ret)
fun: -62.5
message: 'Optimization terminated successfully.'
nit: 2
slack: array([0., 0.])
status: 0
success: True
x: array([25. , 37.5])
LP线性规划求解 之 单纯形 算法的更多相关文章
- 线性规划之单纯形算法矩阵描述与python实现
声明 本文为本人原创,转载请注明出处.本文仅发表在博客园,作者LightningStar. 问题描述 所有的线性规划问题都可以归约到标准型的问题,规约过程比较简单且已经超出本文范围,不再描述,可以参考 ...
- LP线性规划初识
认识LP 线性规划(Linear Programming) 特指目标函数和约束条件皆为线性的最优化问题. 目标函数: 多个变量形成的函数 约束条件: 由多个等式/不等式形成的约束条件 线性规划: 在线 ...
- Excel与Google Sheets中实现线性规划求解
很久没更新过APS系列文章了,这段时间项目工作确实非常紧,所以只能抽点时间学习一下运筹学的入门知识,算是为以后的APS项目积累点基础.看了一些运筹学的书(都是科普级别的)发现原来我目前面对的很多排产. ...
- 对偶理论、拉格朗日对偶问题、LP线性规划对偶性质
Lagrange 对偶问题 定义其的对偶问题: Lagrange函数 考虑线性规划问题 若取集合约束D={x|x≥0},则该线性规划问题的Lagrange函数为 线性规划的对偶问题为: 对偶定理原问题 ...
- [转]利用excel进行线性规划求解
利用线性回归方法求解生产计划 方法一: 1.建立数学模型: 设变量:设生产拉盖式书桌x台,普通式书桌y台,可得最大利润 确定目标函数及约束条件 目标函 ...
- 使用python scipy.optimize linprog和lingo线性规划求解最大值,最小值(运筹学学习笔记)
1.线性规划模型: 2.使用python scipy.optimize linprog求解模型最优解: 在这里我们用到scipy中的linprog进行求解,linprog的用法见https://doc ...
- PCB仿真软件与电磁场求解器的算法
1. 简介 目前商业化的PCB仿真软件主要有: Cadence公司的Sigrity.Ansys公司的SIwave/HFSS.CST公司的CST.Mentor公司的HyperLynx.Polor公司的S ...
- 使用excel结合线性规划求解Holt-Winters参数
其实上面这个是Holt-Winters无季节趋势模型, 上面的S(t)对应下面的a(t)——截距(平滑值) b(t)仍然对应b(t)——趋势,T对应k. ...
- 单纯形算法 matlab
%单纯形 %目标函数标准化 % min x1-3x2+2x3 %输入参量 N=[3 -1 2;-2 4 0;-4 3 8]; B=eye(3); A=[N B]; cn=[1;-3;2]; cb=ze ...
随机推荐
- browserslist详解
https://www.jianshu.com/p/d45a31c50711 https://juejin.im/post/5b8cff326fb9a019fd1474d6 https://githu ...
- webpack中路径的理解
webpack 前端打包工具, 开发人员要面对的路径主要是: 打包前的路径(开发环境路径)和打包后的路径(生产环境路径) 在webpack.config.js中配置的output.path, outp ...
- [RN] React Native 中使用 stickyHeaderIndices 实现 ScrollView 的吸顶效果
React Native中,ScrollView组件可以使用 stickyHeaderIndices 轻松实现 sticky 效果. 例如下面代码中: <ScrollView showsVert ...
- NOIP2013-2014提高组题目浅析
1.前言 迎接NOIP的到来...在这段闲暇时间,决定刷刷水题.这里只是作非常简单的一些总结. 2.NOIP2014 <1> 生活大爆炸之石头剪刀布(模拟) 这是一道考你会不会编程的题目. ...
- 三天精通Vue--Vue的常用语法
Vue的介绍 官网教程:https://cn.vuejs.org/v2/guide/installation.html 掘金:https://juejin.im/ cdn(在线的网络连接资源):htt ...
- Salesforce 开发整理(二)报表开发学习
Salesforce提供了强大的报表功能,支持表格.摘要.矩阵以及结合共四种形式,本文探讨在站在开发的角度要如何理解报表. 一:查询报表基本信息报表在Sales force中是Report对象,基本的 ...
- 2018-2019-2 20165313 《网络对抗技术》 Exp 9 Web安全基础
一.实验要求 本实践的目标理解常用网络攻击技术的基本原理,做不少于7个题目,共3.5分.包括(SQL,XSS,CSRF).Webgoat实践下相关实验. 二.实验问题回答 (1)SQL注入攻击原理,如 ...
- Android的开机启动流程
1.Android的开机启动流程 Android的层次框架图,如下所示: 图片清晰地展示了Android的五层架构,从上到下依次是:应用层.应用框架层.库层.运行时层以及Linux内核层.Androi ...
- Linux内核kobject结构体分析
1.前言 Linux内核中有大量的驱动,而这些驱动往往具有类似的结构,根据面向对象的思想,可以将共同的部分提取为父类,而这个父类就是kobject,kobject结构体中包含了大量设备的必须信息,而三 ...
- SQL Server ----- 备份数据库 生成(.bak)文件
转移数据库 备份数据库 选中数据库 进入后界面如图 选择合适位置进行备份 注意:选择配置好保存位置的 成功后出现 如果出现错误. 还有一种可能是哪个文件夹中已经有了一个 把文件家中的那个删了 还原 ...