from sympy import * import math # a,b,c代表三个未知数,l代表步长 a,b,c,l = symbols("a b c l") #函数表达式 f = 4*a**2 + 2*b**2 + 2*c**2 def deriv(f, x): f_x = diff(f, x, 1) return f_x def f_count(a, b, c): f_result = 2*a**2 + 2*b**2 + 2*c**2 return f_result def f_search(p,grads): l = symbols("l") t = f.subs({a: p[0] + l * grads[0], b: p[1] + l * grads[1], c: p[2] + l * grads[2]}) print("搜索函数为:", t) return t # 2-范数(模) def norm(x,y,z): return math.sqrt(x**2 + y**2 + z**2) def count_l(t): # 令 t函数的导数为零,求解步长l l = symbols("l") t_deriv = deriv(t, l) l = solve(Eq(t_deriv), l) l = float(l[0]) print("步长l为:",l) return l def next_point(): pass if __name__ == "__main__": p = [] variable = ["x", "y", "z"] for i in variable: p.append(int(input("请输入初始点%c坐标---->" % i))) e = float(input("请输入收敛精度---->")) print("初始点坐标为:", p) # 分别对a,b,c求偏导 f_a = deriv(f, a) f_b = deriv(f, b) f_c = deriv(f, c) # print(f_a, f_b, f_a) grads = [0,0,0] # 初始化列表 grads[0] = -(f_a.subs(a, p[0])) grads[1] = -(f_b.subs(b, p[1])) grads[2] = -(f_c.subs(c, p[2])) while norm(grads[0], grads[1], grads[2]) > e : # 求在P点的负梯度 grads = [0,0,0] # 初始化列表 grads[0] = -(f_a.subs(a, p[0])) grads[1] = -(f_b.subs(b, p[1])) grads[2] = -(f_c.subs(c, p[2])) print("在",p,"点负梯度为:",grads) # 沿负梯度方向做一维搜索 # t = f.subs({a: p[0] + l * grads[0], b: p[1] + l * grads[1], c: p[2] + l * grads[2]}) # print("搜索函数为:", t) t = f_search(p, grads) # # 令 t函数的导数为零,求解步长l # t_deriv = deriv(t, l) # print(t_deriv) # l = solve(Eq(t_deriv), l) # l = float(l[0]) # print(l) l = count_l(t) # 下一迭代点 for i in range(3): p[i] = p[i] + l * grads[i] print(p) else: print("循环结束")
梯度法
最新推荐文章于 2022-06-28 22:03:37 发布