采用坐标轮换法求解最优化问题,示例基于书籍范例编写,并不适合所有情况,可以按需求进行修改补充。
代码注解已在程序注释标出,新手编写的程序较为简单,欢迎大佬批评指导
# 开发人员:盛夏的原谅色
# 开发时间:2023/10/26 13:02
# 本文件仅适用于学习分享,不可用作商业用途侵权必究
# 坐标轮换法python实现
# 导入第三方库
from sympy import symbols,diff,solve
a_values=[]
# 设定对应函数
def equation(x1,x2):
# 现代设计方法 张大可 第四章4.1函数
fx=2*x1**2+3*x2**2-8*x1+10
# 现代设计方法 张大可 第四章例4-1函数
# fx=x1**2+x2**2-x1*x2-10*x1-4*x2+60
return fx
# 计算最佳步长与迭代点
def step(x1,x2,i):
a = symbols('a')
# 通过条件判断实现,第一次向x方向搜索,步长为a
if i%2!=0:
x10 = x1 + a
x20 = x2 + 0
else:
x10 = x1 + 0
x20 = x2 + a
# 将含未知量a的点位带入函数,并对a求导
derivative = diff(equation(x10, x20), a)
# 打印输出
print(derivative)
# 一元函数取极值,必要条件一阶导为0,令导数方程=0可得a的值a_value
a_value = solve(derivative, a)[0]
# 保留三位小数
s=round(a_value,3)
# 将最优步长带入得到迭代点
if i%2!=0:
x_1 = x1 + s
x_2 = x2 + 0
else:
x_1 = x1 + 0
x_2 = x2 + s
# 保留3位小数
m=round(x_1,3)
n=round(x_2,3)
# 打印输出
print(m,n)
return m,n
# 主函数
def main():
# 输入初始点位
x_1 = round(float(input('请输入初始点x1:')),3)
x_2 = round(float(input('请输入初始点x2:')),3)
# i为循环判断变量
i=1
# i<20避免陷入死循环
while i<20:
# 保存初始点和迭代后初始点
if i%2!=0:
x10=x_1
x20=x_2
# 调用step函数计算最佳步长和迭代点,返回一个元组
c=step(x_1,x_2,i)
# 从元组中取出迭代点
x_1=c[0]
x_2=c[1]
# 完成一次迭代,i+1
i += 1
# 保证精度计算是迭代点(经历一轮x,y方向迭代的点)和迭代后初始点(做此轮初始点的上一轮迭代点)之间的计算
if i%2!=0:
# 精度计算
acc=((x_1-x10)**2+(x_2-x20)**2)**0.5
# 精度判断符合则完成计算,输出结果
if acc<=0.3:
fx=equation(x_1,x_2)
print('最优解为:',x_1,x_2,'此时精度为:',acc)
print('近似最优解为:',fx)
break
# 精度不符合,继续计算
else:
print('迭代点为:',x_1,x_2)
print('精度为:',acc,'不符合精度要求继续')
continue
# 当运行本程序时调用主函数
if __name__ == "__main__":
main()