赞
踩
文章摘要:线性规划的Python实现。
参考书籍:数学建模算法与应用(第3版)司守奎 孙玺菁。
PS:只涉及了具体实现并不涉及底层理论。学习底层理论以及底层理论实现:可以参考1.最优化模型与算法——基于Python实现 渐令 粱锡军2.算法导论(原书第3版)Thomas H.Cormen Charles E.Leiserson、Ronald L.Rivest Clifford Stein
文章声明:如有发现错误,还望批评指正。
目标函数:
max
o
r
min
y
=
∑
i
=
1
n
a
i
x
i
\max\;or\;\min\; y=\sum\limits_{i=1}^{n}a_ix_i
maxorminy=i=1∑naixi
约束条件:
∑
j
=
1
n
a
i
j
x
j
≤
o
r
=
o
r
≥
b
i
,
i
=
1
,
2
,
…
,
m
\sum\limits_{j=1}^{n}a_{ij}x_{j}\leq or = or \geq b_i,i=1,2,\dots,m
j=1∑naijxj≤or=or≥bi,i=1,2,…,m
x
j
≥
0
,
j
=
1
,
2
,
…
,
n
x_j\geq0,j=1,2,\dots,n
xj≥0,j=1,2,…,n
一些名词: 可行解,可行域与最优解。
PS:至于如何找到最优解的还请参考最前面的PS,没有兴趣可以不用进行研究。希望以后上了最优化的课程或者有时间了能够手搓。感觉工程量有点大,哈哈也许没有必要。所以博主没有学习过最优化相关理论,对于求解器的方法同样也不知道。但是从工程的角度,我们可以不用知道,那是理论学家需要去做的事。看需要,看兴趣。
参考书籍例1.9
目标函数:
max
∑
i
=
0
n
(
r
i
−
p
i
)
x
i
\max\sum\limits_{i=0}^n(r_i-p_i)x_i
maxi=0∑n(ri−pi)xi
min
{
max
1
≤
i
≤
n
{
q
i
x
i
}
}
\min\{\max\limits_{1\leq i\leq n}\{ q_ix_i\} \}
min{1≤i≤nmax{qixi}}
约束条件:
∑
i
=
0
n
(
1
+
p
i
)
x
i
=
M
\sum\limits_{i=0}^{n}(1+p_i)x_i=M
i=0∑n(1+pi)xi=M
x
i
≥
0
,
i
=
0
,
1
,
2
,
…
,
n
x_i\geq0,i=0,1,2,\dots,n
xi≥0,i=0,1,2,…,n
目标函数:
max
∑
i
=
0
n
(
r
i
−
p
i
)
x
i
\max\sum\limits_{i=0}^n(r_i-p_i)x_i
maxi=0∑n(ri−pi)xi
约束条件:
q
i
x
i
M
≤
a
,
i
=
0
,
1
,
2
,
…
,
n
\frac{q_ix_i}{M}\leq a,i=0,1,2,\dots,n
Mqixi≤a,i=0,1,2,…,n
∑
i
=
0
n
(
1
+
p
i
)
x
i
=
M
\sum\limits_{i=0}^{n}(1+p_i)x_i=M
i=0∑n(1+pi)xi=M
x
i
≥
0
,
i
=
0
,
1
,
2
,
…
,
n
x_i\geq0,i=0,1,2,\dots,n
xi≥0,i=0,1,2,…,n
from scipy.optimize import linprog import numpy as np M=10000 lt1=np.array([0.05,0.28,0.21,0.23,0.25]) lt2=np.array([0,0.01,0.02,0.045,0.065]) c=lt1-lt2;c=-c A_ub1=np.diag([0,0.025,0.015,0.055,0.026]);A_ub2=np.diag([-1,-1,-1,-1,-1]);A_ub=np.vstack((A_ub1,A_ub2)) A_eq=1+lt2;A_eq=A_eq.reshape(1,-1) b_eq=np.array([M]) lt=[] for i in range(0,50): b_ub=np.array([i/1000*M for _ in range(5)]+[0 for _ in range(5)]) result=linprog(c,A_ub,b_ub,A_eq,b_eq) lt.append(-result.fun) import matplotlib.pyplot as plt import seaborn as sns plt.figure(figsize=(16,9));sns.set_style("darkgrid");plt.rcParams['font.sans-serif']=['SimHei'] plt.plot([i for i in range(len(lt))],lt,ms=10,marker="o",linestyle="--",linewidth=5,color="green") plt.xlabel("a");plt.ylabel("收益");plt.show()
以下两个模型需要目标函数进行线性转换。但是这样会造成不等式约束右侧包含变量,scipy库无法解决所以使用cvxpy库(至少我没找到功能函数)。
目标函数:
min
{
max
1
≤
i
≤
n
{
q
i
x
i
}
}
\min\{\max\limits_{1\leq i\leq n}\{ q_ix_i\} \}
min{1≤i≤nmax{qixi}}
约束条件:
∑
i
=
0
n
(
r
i
−
p
i
)
x
i
≥
k
M
\sum\limits_{i=0}^n(r_i-p_i)x_i\geq kM
i=0∑n(ri−pi)xi≥kM
∑
i
=
0
n
(
1
+
p
i
)
x
i
=
M
\sum\limits_{i=0}^{n}(1+p_i)x_i=M
i=0∑n(1+pi)xi=M
x
i
≥
0
,
i
=
0
,
1
,
2
…
,
n
x_i\geq0,i=0,1,2\dots,n
xi≥0,i=0,1,2…,n
import numpy as np import cvxpy as cp M=10000 x=cp.Variable(6,pos=True) obj=cp.Minimize(x[5]) p=np.array([0,0.01,0.02,0.045,0.065]) con1=(1+p)@x[:-1]==M q=np.array([0,0.025,0.015,0.055,0.026]) con2=cp.multiply(q,x[:5])<=x[5] r=np.array([0.05,0.28,0.21,0.23,0.25]) lt=[] for i in range(100): con3=(r-p)@x[:-1]>=i/100*M con=[con1,con2,con3] pro=cp.Problem(obj,con) pro.solve(solver='ECOS') lt.append(x.value[5]) import matplotlib.pyplot as plt import seaborn as sns plt.figure(figsize=(16,9));sns.set_style("darkgrid");plt.rcParams['font.sans-serif']=['SimHei'] plt.plot([i for i in range(len(lt))],lt,ms=10,marker="o",linewidth=5,color="green") plt.xlabel("k");plt.ylabel("风险");plt.savefig("figure")
分析:收益到0.26之后便就没有解了。
注释:(默认问题为凸问题,具体是不是我证明不了)ECOS是一个求解凸优化的方法(具体理论我不知道),具有数值稳定,求解效率等等优点,
目标函数:
min
{
ω
{
max
1
≤
i
≤
n
{
q
i
x
i
}
}
−
(
1
−
ω
)
∑
i
=
0
n
(
r
i
−
p
i
)
x
i
\min \{\omega\{\max\limits_{1\leq i\leq n}\{ q_ix_i\} \}-(1-\omega) \sum\limits_{i=0}^n(r_i-p_i)x_i
min{ω{1≤i≤nmax{qixi}}−(1−ω)i=0∑n(ri−pi)xi}
约束条件:
∑
i
=
0
n
(
1
+
p
i
)
x
i
=
M
\sum\limits_{i=0}^{n}(1+p_i)x_i=M
i=0∑n(1+pi)xi=M
x
i
≥
0
,
i
=
0
,
1
,
2
,
…
,
n
x_i\geq0,i=0,1,2,\dots,n
xi≥0,i=0,1,2,…,n
import numpy as np import cvxpy as cp M=10000 x=cp.Variable(6,pos=True) p=np.array([0,0.01,0.02,0.045,0.065]) con1=(1+p)@x[:-1]==M q=np.array([0,0.025,0.015,0.055,0.026]) con2=cp.multiply(q,x[:5])<=x[5] con=[con1,con2] r=np.array([0.05,0.28,0.21,0.23,0.25]) lt1=[];lt2=[] for i in range(100): obj=cp.Minimize(i*x[5]-(1-i/100)*((r-p)@x[:-1])) pro=cp.Problem(obj,con);pro.solve(solver='ECOS') lt1.append((r-p)@x.value[:-1]);lt2.append(x[5].value) import matplotlib.pyplot as plt import seaborn as sns plt.figure(figsize=(16,9));sns.set_style("darkgrid");plt.rcParams['font.sans-serif']=['SimHei'] plt.plot([i for i in range(len(lt1))],lt1,ms=10,marker="o",linewidth=5,color="green") plt.xlabel("w");plt.ylabel("收益");plt.savefig("figure1") plt.figure(figsize=(16,9));sns.set_style("darkgrid");plt.rcParams['font.sans-serif']=['SimHei'] plt.plot([i for i in range(len(lt2))],lt2,ms=10,marker="o",linewidth=5,color="green") plt.xlabel("w");plt.ylabel("风险");plt.savefig("figure2")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。