电气博文传送门
学好电气全靠它,个人电气博文目录(持续更新中…) 题:
例题:
python代码求解 :
思路上面就有,照着敲吧。
主要是为了学习下python 求解优化问题和学习下电网调度。在这之前很少涉足这来。
工具包介绍
非线性规划(scipy.optimize.minimize)
一.背景:
现在项目上有一个用python 实现非线性规划的需求。非线性规划可以简单分两种,目标函数为凸函数 or 非凸函数。
凸函数的 非线性规划,比如fun=x2+y2+x*y,有很多常用的python库来完成,网上也有很多资料,比如CVXPY
非凸函数的 非线性规划(求极值),从处理方法来说,可以尝试以下几种:
1.纯数学方法,求导求极值;
2.使用神经网络,深度学习来处理,可参考反向传播算法中链式求导的过程;
3.寻找一些python库来做,本文介绍scipy.optimize.minimize的使用方法
二.库方法介绍
官方文档:https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html
来看下改方法的入参
scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)
解释:
fun: 求最小值的目标函数
x0:变量的初始猜测值,如果有多个变量,需要给每个变量一个初始猜测值。minimize是局部最优的解法,所以
args:常数值,后面demo会讲解,fun中没有数字,都以变量的形式表示,对于常数项,需要在这里给值
method:求极值的方法,官方文档给了很多种。一般使用默认。每种方法我理解是计算误差,反向传播的方式不同而已,这块有很大理论研究空间
constraints:约束条件,针对fun中为参数的部分进行约束限制
代码:
# coding=utf-8
from scipy.optimize import minimize
import numpy as np
#目标函数
def fun(args):
a1,a2,a3,b1,b2,b3,c1,c2,c3=args
v=lambda x: (a1+a2*x[0]+a3*x[0]*x[0]+b1+b2*x[1]+b3*x[1]*x[1]+c1+c2*x[2]+c3*x[2]*x[2])
return v
def con(args):
# 约束条件 分为eq 和ineq
#eq表示 函数结果等于0 ; ineq 表示 表达式大于等于0
d1, d2, d3, d4, d5, d6 ,d7= args1
cons = ({'type': 'eq', 'fun': lambda x: d1+d2*x[0]-d3-d4*x[1]},\
{'type': 'eq', 'fun': lambda x: d1+d2*x[0]-d5-d6*x[2]},\
{'type': 'eq', 'fun': lambda x: x[0]+x[1]+x[2]-d7})
return cons
if __name__ == "__main__":
# 定义常量值
args = (300,10,0.15,200,20,0.2,100,10,0.3) # a1,a2,a3,b1,b2,b3,c1,c2,c3
# 设置参数范围/约束条件
args1 = (10, 0.3, 20, 0.4, 10, 0.6,320) # d1, d2, d3, d4, d5, d6,d7
cons = con(args1)
# 设置x初始猜测值
x0 = np.array((100, 50, 100))
res = minimize(fun(args), x0, method='SLSQP', constraints=cons)
print(res.fun)
print(res.success)
print(res.x)
结果:
和给出的答案一样的。
解释说明:
目标函数:使三台机组的成本曲线和最小。
args 对应原始成本曲线中的数:(300,10,0.15,200,20,0.2,100,10,0.3)
后面会传进来
def fun(args):
a1,a2,a3,b1,b2,b3,c1,c2,c3=args
v=lambda x: (a1+a2*x[0]+a3*x[0]*x[0]+b1+b2*x[1]+b3*x[1]*x[1]+c1+c2*x[2]+c3*x[2]*x[2])
return v
约束条件
最优情况: 发电机组1成本曲线对功率求导 =发电机组2成本曲线对功率求导=发电机组3成本曲线对功率求导
为什么是求导 相等 。这个电分里教的有,最基本的,不想解释。
发电机组1功率+发电机组2功率+发电机组3功率=负荷功率
本文约束条件可以表达为:
1.发电机组1成本曲线对功率求导 =发电机组2成本曲线对功率求导
2.发电机组1成本曲线对功率求导 =发电机组3成本曲线对功率求导
3.发电机组1功率+发电机组2功率+发电机组3功率=负荷功率
参数:
d1, d2, d3, d4, d5, d6 表示各发电机组成本曲线求导后的系数。
d7 为负荷功率
def con(args):
# 约束条件 分为eq 和ineq
#eq表示 函数结果等于0 ; ineq 表示 表达式大于等于0
d1, d2, d3, d4, d5, d6 ,d7= args1
cons = ({'type': 'eq', 'fun': lambda x: d1+d2*x[0]-d3-d4*x[1]},\
{'type': 'eq', 'fun': lambda x: d1+d2*x[0]-d5-d6*x[2]},\
{'type': 'eq', 'fun': lambda x: x[0]+x[1]+x[2]-d7})
return cons
主函数:
要定义一些数值=
等于说 前面在定义目标函数和约束时全用字母代替,不能出现具体数
。具体数在后面传入。
x0 = np.array((100, 50, 100)) 定义x初始解
res.fun 目标函数值
res.success 是否求得值
res.x 未知数的值
if __name__ == "__main__":
# 定义常量值
args = (300,10,0.15,200,20,0.2,100,10,0.3) # a1,a2,a3,b1,b2,b3,c1,c2,c3
# 设置参数范围/约束条件
args1 = (10, 0.3, 20, 0.4, 10, 0.6,320) # d1, d2, d3, d4, d5, d6,d7
cons = con(args1)
# 设置x初始猜测值
x0 = np.array((100, 50, 100))
res = minimize(fun(args), x0, method='SLSQP', constraints=cons)
print(res.fun)
print(res.success)
print(res.x)