数学建模笔记—— 线性规划
线性规划
在人们的生产实践中,经常会遇到如何利用现有资源来安排生产,以取得最大经济效益的问题。此类问题构成了运筹学的一个重要分支—数学规划,而线性规划(Linear Programming 简记 LP)则是数学规划的一个重要分支。自从 1947 年 G. B. Dantzig 提出求解线性规划的单纯形方法以来,线性规划在理论上趋向成熟,在实用中日益广泛与深入。特别是在计算机能处理成千上万个约束条件和决策变量的线性规划问题之后,线性规划的适用领域更为广泛了,已成为现代管理中经常采用的基本方法之一。
常见的运筹优化问题:
- 若要生产两种机床,利润分别为XXX,机器有不同的损耗费用,不同的工作时间,怎么安排生产能够让总利润最大呢?
- 若总资产是A,有n种资序可以进行配置,每种资产配置平均收益率XXX,风险损失率XXX,手续费XXX,怎么组合投资使得收益最大,风险最小
- 若商品有n个产地和p个销售地,需要从产地运输到销售地,各产地的产量是XXX,各销售地的需求量是XXX,不同产地运输到不同销售地的运价是XXX,怎么调运才能使总运费最省?
- 不同类型的车辆承载量不同,工地各点之间需安排车辆运输,工地里有多条线路。满足用工需求的情况下,怎么安排车辆能使车次安排最合理?
线性规划(Linear programming,简称LP),是运筹学中研究较早、发展较快、应用广泛、方法较成熟的一个重要分支,是辅助人们进行科学管理的一种数学方法,是研究线性约来条件下线性目标函数的极值问题的数学理论和方法。
1. 模型引出
1.1 线性规划模型的三要素
- 决策变量:问题中要确定的未知量,用于表明规划问题中的用数量表示的方案、措施等,可由决策者决定和控制;
- 目标函数:决策变量的函数,优化目标通常是求该函数的最大值或最小值;
- 约束条件:决策变量的取值所受到的约束和限制条件,通常用含有决策变量的等式或不等式表示。
1.2 线性规划模型建立步骤
从实际问题中建立数学模型一般有以下三个步骤:
- 根据影响所要达到目的的因素找到决策变量
- 由决策变量和所在达到目的之间的函数关系确定目标函数
- 由决策变量所受的限制条件确定决策变量所要满足的约束条件
示例:
KK明星特别喜欢玩一款游戏,想找到一种最快的方式升到满级
- 这个游戏每天有100点体力,我们可以通过反复通关A、B、C三张地图来获取经验升级
- 通关A图可以获得20点经验,通关B图可以获得30点经验,通关C图可以获得45点经验
- 通关地图会消耗体力,通关A图消耗4点体力,通关B图消耗8点体力,通关C图消耗15点体力
- 同时A、B、C三图每天加在一起最多通关20次
KK应该怎么组合通过ABC三个地图的次数,来使今天获得的经验最大?
分析该题目,可得:
- 决策变量:三个地图通关次数。设A、B、C三个地图通关的次数分别为 x 1 , x 2 , x 3 x_1,x_2,x_3 x1,x2,x3
- 目标函数:获得的经验最高。设经验为 y , m a x y = 20 x 1 + 30 x 2 + 45 x 3 y,\quad max\ y=20x_1+30x_2+45x_3 y,max y=20x1+30x2+45x3
- 约束条件:消耗体力不能超过100。 4 x 1 + 8 x 2 + 15 x 3 ≤ 100 4x_1+8x_2+15x_3\leq100 4x1+8x2+15x3≤100
三个地图最多通关20次。 x 1 + x 2 + x 3 ≤ 20 x_1+x_2+x_3\leq20 x1+x2+x3≤20
隐藏约束条件, x 1 , x 2 , x 3 ≥ 0 x_1,x_2,x_3\geq0 x1,x2,x3≥0
1.3 线性规划的表现形式
- 一般形式/代数形式
m a x ( 或 m i n ) z = c 1 x 1 + c 2 x 2 + ⋯ + c n x n , s.t. { a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n ≤ ( 或=, ≥ ) b 1 , a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n ≤ ( 或=, ≥ ) b 2 , ⋮ a m 1 x 1 + a m 2 x 2 + ⋯ + a m n x n ≤ ( 或=, ≥ ) b m , x 1 , x 2 , ⋯ , x n ≥ 0. \begin{aligned}&max(\text{或}min) z=c_{1}x_{1}+c_{2}x_{2}+\cdots+c_{n}x_{n},\\&\text{s.t.}\begin{cases}a_{11}x_1+a_{12}x_2+\cdots+a_{1n}x_n\leq(\text{或=,}\geq)b_1,\\a_{21}x_1+a_{22}x_2+\cdots+a_{2n}x_n\leq(\text{或=,}\geq)b_2,\\\vdots\\a_{m1}x_1+a_{m2}x_2+\cdots+a_{mn}x_n\leq(\text{或=,}\geq)b_m,\\x_1,x_2,\cdots,x_n\geq0.\end{cases}\end{aligned} max(或min)z=c1x1+c2x2+⋯+cnxn,s.t.⎩ ⎨ ⎧a11x1+a12x2+⋯+a1nxn≤(或=,≥)b1,a21x1+a22x2+⋯+a2nxn≤(或=,≥)b2,⋮am1x1+am2x2+⋯+amnxn≤(或=,≥)bm,x1,x2,⋯,xn≥0.
在上述示例中,线性规划可写成:
m a x y = 20 x 1 + 30 x 2 + 45 x 3 , s . t . { 4 x 1 + 8 x 2 + 15 x 3 ≤ 100 , x 1 + x 2 + x 3 ≤ 20 , x 1 , x 2 , x 3 ≥ 0. \begin{aligned}&max\quad\mathrm{y}=20x_{1}+30x_{2}+45x_{3},\\&\mathrm{s.t.}\begin{cases}4x_1+8x_2+15x_3\leq100,\\x_1+x_2+x_3\leq20,\\x_1,x_2,x_3\geq0.\end{cases}\end{aligned} maxy=20x1+30x2+45x3,s.t.⎩ ⎨ ⎧4x1+8x2+15x3≤100,x1+x2+x3≤20,x1,x2,x3≥0.
-
简写形式
max ( 或 m i n ) z = ∑ j = 1 n c j x j , s . t . { ∑ j = 1 n a i j x j ≤ ( 或=, ≥ ) b i , i = 1 , 2 , ⋯ , m , x j ≥ 0 , j = 1 , 2 , ⋯ , n . \begin{aligned} &\max(\text{或}min) z=\sum_{j=1}^{n}c_{j}x_{j}, \\ &\mathrm{s.t.}\begin{cases}\sum_{j=1}^{n}a_{ij}x_{j}\leq(\text{或=,}\geq)b_{i}, i=1,2,\cdots,m,\\\\x_{j}\geq0, j=1,2,\cdots,n.\end{cases} \end{aligned} max(或min)z=j=1∑ncjxj,s.t.⎩ ⎨ ⎧∑j=1naijxj≤(或=,≥)bi,i=1,2,⋯,m,xj≥0,j=1,2,⋯,n. -
矩阵表现形式
m a x ( 或 m i n ) z = c T x , s . t . { A x ≤ ( 或 = , ≥ ) b , x ≥ 0. max(\text{或}min) z=c^Tx,\\s.t.\begin{cases}Ax\leq(\text{或}=, \geq)b,\\x\geq0.\end{cases} max(或min)z=cTx,s.t.{Ax≤(或=,≥)b,x≥0.c = [ c 1 , c 2 , … , c n ] T 一一目标函数的系数向量,即价值向量; x = [ x 1 , x 2 , … , x n ] T 一一决策向量; A = ( a i j ) m × n 一一约束方程组的系数矩阵; b = [ b 1 , b 2 , . . . , b m ] T 一一约束方程组的常数向量。 \begin{aligned}&c=[c_1,c_2,\ldots,c_n]^T\text{一一目标函数的系数向量,即价值向量;}\\&x=[x_1,x_2,\ldots,x_n]^T\text{一一决策向量;}\\&A=\left(a_{ij}\right)_{m\times n}\text{一一约束方程组的系数矩阵;}\\&b=[b_1,b_2,...,b_m]^T\text{一一约束方程组的常数向量。}\end{aligned} c=[c1,c2,…,cn]T一一目标函数的系数向量,即价值向量;x=[x1,x2,…,xn]T一一决策向量;A=(aij)m×n一一约束方程组的系数矩阵;b=[b1,b2,...,bm]T一一约束方程组的常数向量。
在上述示例中,线性规划可写成:
m a x y = c T x , s . t . { A x ≤ b , x ≥ 0. c = [ 20 , 30 , 45 ] T x = [ x 1 , x 2 , x 3 ] T A = [ 4 8 15 1 1 1 ] b = [ 100 , 20 ] T \begin{aligned} &max\: y=c^{T}x, \\ &s.t.\begin{cases}Ax\leq b,\\x\geq0.\end{cases} \\ &c=[20,30,45]^T \\ &x=[x_1,x_2,x_3]^T \\ &A=\begin{bmatrix}4&8&15\\1&1&1\end{bmatrix} \\ &b=[100,20]^T \end{aligned} maxy=cTx,s.t.{Ax≤b,x≥0.c=[20,30,45]Tx=[x1,x2,x3]TA=[4181151]b=[100,20]T
1.4 线性规划的模型特点
- 要解决的问题是优化类的(即在限的资源条件下,获取最大的收益)
- 目标函数和约束条件都是决策变量的线性函数,即不存在 x 2 , e x , 1 x , s i n x , l o g 2 x x^2,e^x,\frac{1}{x},sinx,log_2x x2,ex,x1,sinx,log2x等
- 线性规划模型:在一组线性约束条件下,求线性目标函数的最大值或最小值
2.典型例题
(1998年国赛A题)市场上有 n n n种资产(如股票、债券、…) s i ( i = 1 , 2 , ⋅ ⋅ ⋅ , n ) s_i\left(i=1,2,\cdotp\cdotp\cdotp,n\right) si(i=1,2,⋅⋅⋅,n)供投资者选择,某公司有数额为 M M M的一笔相当大的资金可用作一个时期的投资。公司财务分析人员对这 n n n种资产进行了评估,估算出在这一时期内购买资产 s i s_i si的平均收益率为 r i r_i ri, 并预测出购买 s i s_i si的风险损失率为 q i q_i qi。考虑到投资越分散, 总的风险越小,公司确定,当用这笔资金购买若干种资产时,总体风险可用所投资的 s i s_i si中最大的一个风险来度量。
购买 s i s_i si要付交易费,费率为 p i p_i pi,并且当购买额不超过给定值 u i u_i ui时,交易费按购买 u i u_i ui计算(不买当然无须付费)。另外,假定同期银行存款利率是 r 0 ( r 0 = 5 % ) r_0(r_0=5\%) r0(r0=5%),且既无交易费又无风险。
已知 n = 4 n=4 n=4时的相关数据如表所示。
S i S_i Si r i ( % ) r_i(\%) ri(%) q i ( % ) q_i(\%) qi(%) p i ( % ) p_i(\%) pi(%) u i u_i ui(元) S 1 S_1 S1 28 2.5 1 103 S 2 S_2 S2 21 1.5 2 198 S 3 S_3 S3 23 5.5 4.5 52 S 4 S_4 S4 25 2.6 6.5 40
投资收益问题:给上述公司设计投资组合方案,用给定资金 M M M,有选择地购买若干种资产或存银行生息,使净收益尽可能大,总体风险尽可能小。
问题分析:
- 决策变量:投资不同项目 s i s_i si的为 x i ( i = 1 , 2 , ⋯ , n ) x_i(i=1,2,\cdots,n) xi(i=1,2,⋯,n)
- 目标函数:净收益 Q Q Q尽可能大、总风险尽可能小
- 约束条件:总资金 M M M有限,每一笔投资都是非负数
- 且已知,目标函数和约束条件都是决策变量的线性函数
因此可以构建线性规划模型
模型假设:
- 可供投资的贸金数额 M M M相当大
- 投资越分散,总的风险越小,总体风险可用所投资的 s i s_{i} si中最大的一个风险来度量
- 可供选择的 n + 1 n+1 n+1种资产(含银行存款)之间是相互独立的
- 每种资产可购买的数量为任意值
- 在当前投资周期内, r i , q i , p i , u i ( i = 0 , 1 , ⋅ ⋅ ⋅ , n r_i,q_i,p_i,u_i(i=0,1,\cdotp\cdotp\cdotp,n ri,qi,pi,ui(i=0,1,⋅⋅⋅,n)固定不变
- 不考虑在资产交易过程中产生的其他费用,如股票交易印花税等
- 由于投资数额 M M M相当大,而题目设定的定额 u i u_i ui相对 M M M很小, p i u i p_iu_i piui更小,因此假设每一笔交易 x i x_i xi都大于对应定额 u i u_i ui
模型建立:
-
总体风险用所投资的 s i s_i si中最大的一个风险来衡量,即 m a x { q i x i ∣ i = 1 , 2 , ⋯ , n } . max\{q_ix_i| i=1,2,\cdots,n\}. max{qixi∣i=1,2,⋯,n}.
-
购买 s i ( i = 1 , 2 , ⋅ ⋅ ⋅ , n s_i(i=1,2,\cdotp\cdotp\cdotp,n si(i=1,2,⋅⋅⋅,n)所付交易费本来是一个分段函数,但假设中已经假设每一笔交易 x i x_i xi都大于对应定额 u i u_i ui,所以交易费 = p i x i =p_ix_i =pixi, 这样购买 s i s_i si的净收益可以简化为 ( r i − p i ) x i (r_i-p_i)x_i (ri−pi)xi。
-
目标函数为:
{ m a x ∑ i = 0 n ( r i − p i ) x i , m i n { m a x 1 ≤ i ≤ n { q i x i } } \begin{cases}max\sum_{i=0}^n(r_i-p_i)x_i ,\\min\{max_{1\leq i\leq n}\{q_ix_i\}\}\end{cases} {max∑i=0n(ri−pi)xi,min{max1≤i≤n{qixi}} -
约束条件为:
{ ∑ i = 0 n ( 1 + p i ) x i = M , x i ≥ 0 , i = 0 , 1 , ⋯ , n . \begin{cases}&\sum_{i=0}^{n}(1+p_{i})x_{i}=M,\\&x_{i}\geq0,\quad i=0,1,\cdots,n.\end{cases} {∑i=0n(1+pi)xi=M,xi≥0,i=0,1,⋯,n.
可见这是一个多目标规划模型
模型的简化:
-
在实际投资中,投资者承受风险的程度不一样,若给定风险一个界限 a a a,使最大的一个风险 q i x i M ≤ a \frac{q_ix_i}M\leq a Mqixi≤a ,可找到相应的投资方案。这样把多目标规划变成一个目标的线性规划。
-
这里将目标函数 m i n { m a x 1 ≤ i ≤ n { q i x i } } min\{max_{1\leq i\leq n}\left\{q_ix_i\right\}\} min{max1≤i≤n{qixi}}转化为了约束条件: q i x i M ≤ a \frac{q_ix_i}M\leq a Mqixi≤a(总体风险小于某个常数 )
得到单目标规划模型如下:
m a x ∑ i = 0 n ( r i − p i ) x i s . t . { q i x i M ≤ a , i = 1 , 2 , ⋯ , n , ∑ i = 0 n ( 1 + p i ) x i = M , x i ≥ 0 , i = 0 , 1 , ⋯ , n . max\sum_{i=0}^n(r_i-p_i)x_i\quad\mathrm{s.t.}\begin{cases}\frac{q_ix_i}{M}\leq a,i=1,2,\cdots,n,\\\sum_{i=0}^n(1+p_i)x_i=M,\\x_i\geq0,\quad i=0,1,\cdots,n.\end{cases} maxi=0∑n(ri−pi)xis.t.⎩ ⎨ ⎧Mqixi≤a,i=1,2,⋯,n,∑i=0n(1+pi)xi=M,xi≥0,i=0,1,⋯,n.
此时的约束条件:- 风险不超过某定值
- 投资所有项目的总金额加起来等于总资产
- 投资的金额都是非负数
3. python代码求解
python linprog 函数
r
e
s
u
l
t
=
l
i
n
p
r
o
g
(
c
,
A
_
u
b
,
b
_
u
b
,
A
_
e
q
,
b
_
e
q
,
b
o
u
n
d
s
,
m
e
t
h
o
d
)
m
i
n
c
x
,
s
.
t
.
{
A
_
u
b
⋅
x
≤
b
_
u
b
,
A
_
e
q
⋅
x
=
b
_
e
q
,
x
∈
b
o
u
n
d
s
.
result=linprog(c,A\_ub,b\_ub,A\_eq,b\_eq,bounds,method) min\:cx\:,\\s.t.\begin{cases}A\_ub\cdot x\leq b\_ub,\\A\_eq\cdot x=b\_eq,\\x\in bounds.\end{cases}
result=linprog(c,A_ub,b_ub,A_eq,b_eq,bounds,method)mincx,s.t.⎩
⎨
⎧A_ub⋅x≤b_ub,A_eq⋅x=b_eq,x∈bounds.
- c c c——目标函数的决策变量对应的系数向量(行列向量都可以,下同)
- A _ u b , b _ u b A\_ub,b\_ub A_ub,b_ub——不等式约束条件的变量系数矩阵和常数项矩阵(必须是 ≤ \leq ≤形式)
- A _ e q , b _ e q A\_eq,b\_eq A_eq,b_eq——等式约束条件的系数矩阵和常数项矩阵
- b o u n d s bounds bounds——表示决策变量定义域的 n × 2 n\times2 n×2矩阵,None表示无穷
- m e t h o d method method一一调用的求解方法,默认为 highs
- r e s u l t result result有多个参数,常用 x x x为最优解, f u n fun fun为函数最小值, n i t nit nit迭代次数等,调用时用 r e s u l t . x result.x result.x
注意:要调用 l i n p r o g linprog linprog函数,变量必须是标准形式,即目标函数是求最小值,约束条件都是小于等于号或等号,如果不满足标准形式,我们可以同乘“ — ”变号来继续求解。
3.1 求解KK升级的问题
由上述分析得知该问题的线性规划可表示为:
m
a
x
y
=
20
x
1
+
30
x
2
+
45
x
3
,
s
.
t
.
{
4
x
1
+
8
x
2
+
15
x
3
≤
100
,
x
1
+
x
2
+
x
3
≤
20
,
x
1
,
x
2
,
x
3
≥
0.
\begin{aligned}&max\quad\mathrm{y}=20x_{1}+30x_{2}+45x_{3},\\&\mathrm{s.t.}\begin{cases}4x_1+8x_2+15x_3\leq100,\\x_1+x_2+x_3\leq20,\\x_1,x_2,x_3\geq0.\end{cases}\end{aligned}
maxy=20x1+30x2+45x3,s.t.⎩
⎨
⎧4x1+8x2+15x3≤100,x1+x2+x3≤20,x1,x2,x3≥0.
化为标准形式:
m
i
n
−
y
=
−
20
x
1
−
30
x
2
−
45
x
3
,
s
.
t
.
{
4
x
1
+
8
x
2
+
15
x
3
≤
100
,
x
1
+
x
2
+
x
3
≤
20
,
x
1
,
x
2
,
x
3
≥
0.
\begin{aligned}&min\quad\mathrm{-y}=-20x_{1}-30x_{2}-45x_{3},\\&\mathrm{s.t.}\begin{cases}4x_1+8x_2+15x_3\leq100,\\x_1+x_2+x_3\leq20,\\x_1,x_2,x_3\geq0.\end{cases}\end{aligned}
min−y=−20x1−30x2−45x3,s.t.⎩
⎨
⎧4x1+8x2+15x3≤100,x1+x2+x3≤20,x1,x2,x3≥0.
套用
l
i
n
p
r
o
g
linprog
linprog函数:
r
e
s
u
l
t
=
l
i
n
p
r
o
g
(
c
,
A
_
u
b
,
b
_
u
b
,
A
_
e
q
,
b
_
e
q
,
b
o
u
n
d
s
,
m
e
t
h
o
d
)
m
i
n
c
x
,
s
.
t
.
{
A
_
u
b
⋅
x
≤
b
_
u
b
,
A
_
e
q
⋅
x
=
b
_
e
q
,
x
∈
b
o
u
n
d
s
.
result=linprog(c,A\_ub,b\_ub,A\_eq,b\_eq,bounds,method) min\:cx\:,\\s.t.\begin{cases}A\_ub\cdot x\leq b\_ub,\\A\_eq\cdot x=b\_eq,\\x\in bounds.\end{cases}
result=linprog(c,A_ub,b_ub,A_eq,b_eq,bounds,method)mincx,s.t.⎩
⎨
⎧A_ub⋅x≤b_ub,A_eq⋅x=b_eq,x∈bounds.
得:
{
c
=
[
−
20
,
−
30
,
−
45
]
A
−
ub
=
[
4
8
15
1
1
1
]
b
−
ub
=
[
100
,
20
]
b
o
u
n
d
s
=
[
[
0
,
N
o
n
e
]
,
[
0
,
N
o
n
e
]
,
[
0
,
N
o
n
e
]
]
\begin{cases}c=\begin{bmatrix}-20&,-30&,-45\end{bmatrix}\\A_-\text{ub}=\begin{bmatrix}4&8&15\\1&1&1\end{bmatrix}\\b_-\text{ub}=\begin{bmatrix}100&,20\end{bmatrix}\\bounds=[[0,None],[0,None],[0,None]]\end{cases}
⎩
⎨
⎧c=[−20,−30,−45]A−ub=[4181151]b−ub=[100,20]bounds=[[0,None],[0,None],[0,None]]
源码:
from scipy.optimize import linprog
# 目标函数系数,这里取复制是因为linprog默认进行最小值优化
c = [-20, -30, -45]
# 不等式约束矩阵
A_ub = [
[4, 8, 15],
[1, 1, 1]
]
# 不等式约束右侧值向量
b_ub = [100, 20]
# 定义域
bounds = [(0, None), (0, None), (0, None)]
# 求解线性规划问题
# 注意:由于linprog默认进行最小值优化,所以目标函数系数取负值来求解最大值
result = linprog(c, A_ub, b_ub, bounds=bounds)
print(result)
# 输出结果
print("A、B、C的通过次数分别为:", result.x)
# 目标函数的最大值是最小化问题的相反数
y = -result.fun
print("最终获得的经验为:", y)
输出:
message: Optimization terminated successfully. (HiGHS Status 7: Optimal)
success: True
status: 0
fun: -450.0
x: [ 1.500e+01 5.000e+00 0.000e+00]
nit: 2
lower: residual: [ 1.500e+01 5.000e+00 0.000e+00]
marginals: [ 0.000e+00 0.000e+00 2.500e+00]
upper: residual: [ inf inf inf]
marginals: [ 0.000e+00 0.000e+00 0.000e+00]
eqlin: residual: []
marginals: []
ineqlin: residual: [ 0.000e+00 0.000e+00]
marginals: [-2.500e+00 -1.000e+01]
mip_node_count: 0
mip_dual_bound: 0.0
mip_gap: 0.0
A、B、C的通过次数分别为: [15. 5. 0.]
最终获得的经验为: 450.0
注意:实际上该题目属于整数规划,求出整数解是巧合。
3.2 求解投资收益问题
由上述分析得知该问题的线性规划可表示为:
m
a
x
∑
i
=
0
n
(
r
i
−
p
i
)
x
i
s
.
t
.
{
q
i
x
i
M
≤
a
,
i
=
1
,
2
,
⋯
,
n
,
∑
i
=
0
n
(
1
+
p
i
)
x
i
=
M
,
x
i
≥
0
,
i
=
0
,
1
,
⋯
,
n
.
max\sum_{i=0}^n(r_i-p_i)x_i\\\mathrm{s.t.}\begin{cases}\frac{q_ix_i}{M}\leq a,i=1,2,\cdots,n,\\\sum_{i=0}^n(1+p_i)x_i=M,\\x_i\geq0,\quad i=0,1,\cdots,n.\end{cases}
maxi=0∑n(ri−pi)xis.t.⎩
⎨
⎧Mqixi≤a,i=1,2,⋯,n,∑i=0n(1+pi)xi=M,xi≥0,i=0,1,⋯,n.
化为标准形式:
m
i
n
∑
i
=
0
n
(
p
i
−
r
i
)
x
i
s
.
t
.
{
q
i
x
i
M
≤
a
,
i
=
1
,
2
,
⋯
,
n
,
∑
i
=
0
n
(
1
+
p
i
)
x
i
=
M
,
x
i
≥
0
,
i
=
0
,
1
,
⋯
,
n
.
min\sum_{i=0}^n(p_i-r_i)x_i\\ \mathrm{s.t.}\begin{cases}\frac{q_ix_i}{M}\leq a,i=1,2,\cdots,n,\\\sum_{i=0}^n(1+p_i)x_i=M,\\x_i\geq0,\quad i=0,1,\cdots,n.\end{cases}
mini=0∑n(pi−ri)xis.t.⎩
⎨
⎧Mqixi≤a,i=1,2,⋯,n,∑i=0n(1+pi)xi=M,xi≥0,i=0,1,⋯,n.
根据表格数据,得:
m
i
n
f
=
[
0.05
,
0.27
,
0.19
,
0.185
,
0.185
]
⋅
[
x
0
,
x
1
,
x
2
,
x
3
,
x
4
]
T
s.t.
{
x
0
+
1.01
x
1
+
1.02
x
2
+
1.045
x
3
+
1.065
x
4
=
M
,
0.025
x
1
≤
a
M
,
0.015
x
2
≤
a
M
,
0.055
x
3
≤
a
M
,
0.026
x
4
≤
a
M
,
x
i
≥
0
(
i
=
0
,
1
,
⋯
,
4
)
.
\begin{aligned}&min\:f=[0.05, 0.27, 0.19, 0.185, 0.185]\cdot[x_{0},x_{1},x_{2},x_{3},x_{4}]^{T}\\&\text{s.t.}\begin{cases}x_0+1.01x_1+1.02x_2+1.045x_3+1.065x_4=M,\\0.025x_1\leq aM,\\0.015x_2\leq aM,\\0.055x_3\leq aM,\\0.026x_4\leq aM,\\x_i\geq0 (i=0,1,\cdots,4).\end{cases}\end{aligned}
minf=[0.05,0.27,0.19,0.185,0.185]⋅[x0,x1,x2,x3,x4]Ts.t.⎩
⎨
⎧x0+1.01x1+1.02x2+1.045x3+1.065x4=M,0.025x1≤aM,0.015x2≤aM,0.055x3≤aM,0.026x4≤aM,xi≥0(i=0,1,⋯,4).
这里我们不妨取
M
=
1
M=1
M=1万元;由于a是任意给定的风险度,到底怎样没有一个准则,不同的投资者有不同的风险度。我们从a=0开始,以步长
Δ
\Delta
Δa=0.001进行循环搜索,搜索至a=5%(低风险者能接受的风险)
源码如下:
import matplotlib.pyplot as plt # 用于绘图
from numpy import ones, diag, c_, zeros # 用于创建数组
from scipy.optimize import linprog # 用于执行线性规划
# 设置matplotlib的参数使其支持Latex文本和字体大小
plt.rc('text', usetex=True)
plt.rc('font', size=16)
# 线性规划问题的目标函数系数
c = [-0.05, -0.27, -0.19, -0.185, -0.185]
# 线性不等式的约束矩阵
# 使用c_来合并数组,zeros创建全零数组作为第一列,diag创建一个对角矩阵
A = c_[zeros(4), diag([0.025, 0.015, 0.055, 0.026])]
# 线性等式约束的系数矩阵和右侧的值
Aeq = [[1, 1.01, 1.02, 1.045, 1.065]]
beq = [1]
# 初始化参数a,以及两个用于存储结构的空列表
a = 0
aa = []
ss = []
# 循环,a的值从0开始,步长为0.001,直到a的值为0.05
while a <= 0.05:
# 创建线性不等式约束的右侧值b
b = ones(4)*a
# 执行线性规划,得到最优解
res = linprog(c, A_ub=A, b_ub=b, A_eq=Aeq, b_eq=beq, bounds=[(0, None)]*5)
# 提取线性规划的解向量x和最优值Q
x = res.x
Q = -res.fun
# 将a和Q分别添加到aa和ss列表中
aa.append(a)
ss.append(Q)
a += 0.001
# 绘制结果,a作为横坐标,Q作为纵坐标
plt.plot(aa, ss, 'r*')
# 添加标签
plt.xlabel(r'$a$')
plt.ylabel(r'$Q$', rotation=90)
plt.show()
输出:
![img](https://img-blog.csdnimg.cn/img_convert/48770e22bba0e94ef66358e6e95c5532.png)
结果分析:
风险 a a a与收益 Q Q Q之间的关系见图。从图中可以看出:
- 风险不超过 2.5 2.5% 2.5时,风险大,收益也大
-
a
=
0.006
a=0.006
a=0.006附近有一个转折点,在这一点左边,风险增加很少时,利润增长很快。在这一点右边,风险增加很大时,利润增长很缓慢,所以对于风险和收益没有特殊偏好的投资者来说,应该选择曲线的转折点作为最优投资组合,大约是
a
=
0.6
%
,
Q
=
2000
a=0.6\%,Q=2000
a=0.6%,Q=2000,所对应投资方案为:
风险度 a = 0.006 a=0.006 a=0.006,收益$Q= 2019 元; 2019元; 2019元;x_0=0 元 元 元,x_1=$ 2400 元, x 2 = 4000 元, x 3 = 1091 元, x 4 = 2212 元 2400元,x_{2}=4000元,x_{3}=1091元,x_{4}=2212元 2400元,x2=4000元,x3=1091元,x4=2212元