【366】通过 python 求解 QP 问题

参考: 9.3 凸优化 · 如何在 Python 中利用 CVXOPT 求解二次规划问题

参考: Quadratic Programming - Official website

步骤如下:

  • 首先安装 cvxopt library
  • 将问题化成标准 QP 问题, 得到 P/q/G/h/A/b
  • 直接利用自带函数求解即可
    cvxopt.solvers.qp(P, q[, G, h[, A, b[, solver[, initvals]]]])

1、二次规划问题的标准形式

上式中,x为所要求解的列向量,xT表示x的转置

接下来,按步骤对上式进行相关说明:

  • 上式表明,任何二次规划问题都可以转化为上式的结构,事实上用cvxopt的第一步就是将实际的二次规划问题转换为上式的结构,写出对应的PqGhAb
  • 目标函数若为求max,可以通过乘以−1,将最大化问题转换为最小化问题
  • Gx≤b表示的是所有的不等式约束,同样,若存在诸如x≥0的限制条件,也可以通过乘以−1转换为的形式
  • Ax=b表示所有的等式约束

2、以一个标准的例子进行过程说明

例子中,需要求解的是x,y,我们可以把它写成向量的形式,同时,也需要将限制条件按照上述标准形式进行调整,用矩阵形式表示,如下所示:

  • 如上所示,目标函数和限制条件均转化成了二次规划的标准形式,这是第一步,也是最难的一步,接下来的事情就简单了
  • 对比上式和标准形式,不难得出:

接下来就是几行简单的代码,目的是告诉计算机上面的参数具体是什么

from cvxopt  import solvers, matrix
P = matrix([[1.0,0.0],[0.0,0.0]])   # matrix里区分int和double,所以数字后面都需要加小数点
q = matrix([3.0,4.0])
G = matrix([[-1.0,0.0,-1.0,2.0,3.0],[0.0,-1.0,-3.0,5.0,4.0]])
h = matrix([0.0,0.0,-15.0,100.0,80.0])

sol = solvers.qp(P,q,G,h)   # 调用优化函数solvers.qp求解
print sol[‘x‘]  # 打印结果,sol里面还有很多其他属性,读者可以自行了解

    pcost       dcost       gap    pres   dres
 0:  1.0780e+02 -7.6366e+02  9e+02  1e-16  4e+01
 1:  9.3245e+01  9.7637e+00  8e+01  1e-16  3e+00
 2:  6.7311e+01  3.2553e+01  3e+01  6e-17  1e+00
 3:  2.6071e+01  1.5068e+01  1e+01  2e-16  7e-01
 4:  3.7092e+01  2.3152e+01  1e+01  2e-16  4e-01
 5:  2.5352e+01  1.8652e+01  7e+00  8e-17  3e-16
 6:  2.0062e+01  1.9974e+01  9e-02  6e-17  3e-16
 7:  2.0001e+01  2.0000e+01  9e-04  6e-17  3e-16
 8:  2.0000e+01  2.0000e+01  9e-06  9e-17  2e-16
Optimal solution found.
[ 7.13e-07]
[ 5.00e+00]
  • 看了上面的代码,是不是觉得很简单。因为难点不在代码,而是在于将实际优化问题转化为标准形式的过程
  • 在上面的例子中,并没有出现等号,当出现等式约束时,过程一样,找到A,b,然后运行代码 sol = solvers.qp(P,q,G,h,A,b) 即可求解

扩展:上述定义各个矩阵参数用的是最直接的方式,其实也可以结合Numpy来定义上述矩阵

from cvxopt import solvers, matrix
import numpy as np

P = matrix(np.diag([1.0,0]))  #  对于一些特殊矩阵,用numpy创建会方便很多(在本例中可能感受不大)
q = matrix(np.array([3.0,4]))
G = matrix(np.array([[-1.0,0],[0,-1],[-1,-3],[2,5],[3,4]]))
h = matrix(np.array([0.0,0,-15,100,80]))
sol = solvers.qp(P,q,G,h)

     pcost       dcost       gap    pres   dres
 0:  1.0780e+02 -7.6366e+02  9e+02  1e-16  4e+01
 1:  9.3245e+01  9.7637e+00  8e+01  1e-16  3e+00
 2:  6.7311e+01  3.2553e+01  3e+01  6e-17  1e+00
 3:  2.6071e+01  1.5068e+01  1e+01  2e-16  7e-01
 4:  3.7092e+01  2.3152e+01  1e+01  2e-16  4e-01
 5:  2.5352e+01  1.8652e+01  7e+00  8e-17  3e-16
 6:  2.0062e+01  1.9974e+01  9e-02  6e-17  3e-16
 7:  2.0001e+01  2.0000e+01  9e-04  6e-17  3e-16
 8:  2.0000e+01  2.0000e+01  9e-06  9e-17  2e-16
Optimal solution found.

  

原文地址:https://www.cnblogs.com/alex-bn-lee/p/10350205.html

时间: 2024-08-06 04:47:53

【366】通过 python 求解 QP 问题的相关文章

Python求解非线性方程

原文地址:http://blog.csdn.net/ville_zeng/article/details/25370053,转载请注明出处! 昨晚一朋友问了我道数学题:已知弧长l=156,弦长d=140,求半径R和夹角a. 我试了下,方程比较好列,但是求解的话就比较费劲了,心想要是用Matlab的话也就瞬间的事儿,可电脑没安装Matlab,然后想到Python的一个数学库scipy,研究下,是可以解决的. 方程如下: ·      cos(a) = 1 - d^2 / (2*R^2) ·    

python 求解线性方程组

Python线性方程组求解 求解线性方程组比较简单,只需要用到一个函数(scipy.linalg.solve)就可以了.比如我们要求以下方程的解,这是一个非齐次线性方程组: 3x_1 + x_2 - 2x_3 = 5 x_1 - x_2 + 4x_3 = -2 2x_1 + 3x_3 = 2.5 import numpy as np from scipy.linalg import solve a = np.array([[3, 1, -2], [1, -1, 4], [2, 0, 3]]) b

Python求解数组重新组合求最小值(优酷)

题目描述:题目:含有n个元素的整型数组,将这个n个元素重新组合,求出最小的数,如(321,3,32,) 最小数为321323 题目分析: 将数组中所有元素填充到个数相等,填充的数字为最后一位的数字,如这个case所示,填充之后为{321,333,322},然后按大小排序, 排序之后将填充的数字去掉,然后拼接之后的数字就为最小数,即排序之后为{321,322,333},去掉填充数字为{321,32,3},即为321323 Python实现 def mergeMinValue(lst): #生成字符

Python求解登楼梯问题(京东2016笔试题)

问题:假设一段楼梯共15个台阶,小明一步最多能上3个台阶,那么小明上这段楼梯一共有多少种方法? 解析:从第15个台阶上往回看,有3种方法可以上来(从第14个台阶上一步迈1个台阶上来,从第13个台阶上一步迈2个台阶上来,从第12个台阶上一步迈3个台阶上来),同理,第14个.13个.12个台阶都可以这样推算,从而得到公式f(n) = f(n-1) + f(n-2) + f(n-3),其中n=15.14.13.....5.4.然后就是确定这个递归公式的结束条件了,第一个台阶只有1种上法,第二个台阶有2

Python求解啤酒问题(携程2016笔试题)

问题描述:一位酒商共有5桶葡萄酒和1桶啤酒,6个桶的容量分别为30升.32升.36升.38升.40升和62升,并且只卖整桶酒,不零卖.第一位顾客买走了2整桶葡萄酒,第二位顾客买走的葡萄酒是第一位顾客的2倍.那么,本来有多少升啤酒呢?解析:由于该酒商只卖整桶酒,简单分析几个桶的容量可知,第二位顾客必须买走剩下的3桶葡萄酒才有可能是第一位顾客的2倍.假设第一位顾客买走的葡萄酒共L升,那么第二位顾客买走的是2L升.也就是说,葡萄酒的总数应该能被3整除.所以,解法就呼之欲出了. Python 解法1 1

使用python解线性矩阵方程

这学期有一门运筹学,讲的两大块儿:线性优化和非线性优化问题.在非线性优化问题这里涉及到拉格朗日乘子法,经常要算一些非常变态的线性方程,于是我就想用python求解线性方程.查阅资料的过程中找到了一个极其简单的解决方式,也学到了不少东西.先把代码给出. import numpy as np # A = np.mat('1 2 3;2 -1 1;3 0 -1') A = np.array([[1, 2, 3], [2, -1, 1], [3, 0, -1]]) b = np.array([9, 8,

快速傅里叶变换(FFT)算法【详解】

快速傅里叶变换(Fast Fourier Transform)是信号处理与数据分析领域里最重要的算法之一.我打开一本老旧的算法书,欣赏了JW Cooley 和 John Tukey 在1965年的文章中,以看似简单的计算技巧来讲解这个东西. 本文的目标是,深入Cooley-Tukey  FFT 算法,解释作为其根源的“对称性”,并以一些直观的python代码将其理论转变为实际.我希望这次研究能对这个算法的背景原理有更全面的认识. FFT(快速傅里叶变换)本身就是离散傅里叶变换(Discrete

快速傅里叶变换(FFT)

快速傅里叶变换(FFT)算法[详解] 快速傅里叶变换(Fast Fourier Transform)是信号处理与数据分析领域里最重要的算法之一.我打开一本老旧的算法书,欣赏了JW Cooley 和 John Tukey 在1965年的文章中,以看似简单的计算技巧来讲解这个东西. 本文的目标是,深入Cooley-Tukey  FFT 算法,解释作为其根源的"对称性",并以一些直观的python代码将其理论转变为实际.我希望这次研究能对这个算法的背景原理有更全面的认识. FFT(快速傅里叶

机器学习之最小二乘法

1.背景: 1801年,意大利天文学家朱赛普·皮亚齐发现了第一颗小行星谷神星.经过40天的跟踪观测后,由于谷神星运行至太阳背后,使得皮亚齐失去了谷神星的位置.随后全世界的科学家利用皮亚齐的观测数据开始寻找谷神星,但是根据大多数人计算的结果来寻找谷神星都没有结果.时年24岁的高斯也计算了谷神星的轨道.奥地利天文学家海因里希·奥伯斯根据高斯计算出来的轨道重新发现了谷神星. 高斯使用的最小二乘法的方法发表于1809年他的著作<天体运动论>中,而法国科学家勒让德于1806年独立发现“最小二乘法”,但因