信赖域求解Rosenbrock函数(LM求解子问题)
来源:互联网 发布:openwrt 网络配置 编辑:程序博客网 时间:2024/06/06 02:31
二维求解
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3Dfrom pandas import DataFramedef draw(x1, x2): ''' 采用matplolib绘制曲面图 :param x: x轴坐标数组 :param y: y轴坐标数组 :param z: z轴坐标数组 :return: ''' X = x1 Y = x2 Z = (1 - x1) ** 2 + 100 * (x2 - x1 ** 2) ** 2 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_trisurf(X, Y, Z) plt.show()def draw2(x1,x2): x = x1 y = x2 #绘制Xk的离散点图形 plt.xlim(xmax = 1,xmin = 0) plt.ylim(ymax = 1,ymin = 0) plt.plot(x,y,'ro') plt.xlabel('x') plt.ylabel('y') plt.show()def cal_rosenbrock(x): # 计算rosenbrock函数的值 return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)def cal_rosenbrock_prax(x1, x2): """ 对x1求偏导 """ return -2 + 2 * x1 - 400 * (x2 - x1 ** 2) * x1def cal_rosenbrock_pray(x1, x2): """ 对x2求偏导 """ return 200 * (x2 - x1 ** 2)def rosen_hess(x): x = np.asarray(x) H = np.diag(-400*x[:-1],1) - np.diag(400*x[:-1],-1) diagonal = np.zeros_like(x) diagonal[0] = 1200*x[0]**2-400*x[1]+2 diagonal[-1] = 200 diagonal[1:-1] = 202 + 1200*x[1:-1]**2 - 400*x[2:] H = H + np.diag(diagonal) return Hdef check(T): c = 0 for i in T[0:]: if i <= 0: c = 1 break return cdef for_rosenbrock_func(max_iter_count=100000,step_size = 0.001): pre_x = np.zeros((2,), dtype=np.float32) X_all = np.zeros((2,), dtype=np.float32) loss = 10 cnt = 0 I = np.eye(2) miu = 1 loss_all = [] while loss > 0.001 and cnt < max_iter_count: der = np.zeros((2,), dtype=np.float32) der[0] = cal_rosenbrock_prax(pre_x[0], pre_x[1]) der[1] = cal_rosenbrock_pray(pre_x[0], pre_x[1]) Hess = np.zeros((2,), dtype=np.float32) G_k = rosen_hess(pre_x) + miu * I T_vector = np.linalg.eigvals(G_k) #计算特征值 # 如果不正定,阻尼系数扩大四倍 while check(T_vector) : miu = 4 * miu G_k = rosen_hess(pre_x) + miu * I T_vector = np.linalg.eigvals(G_k) S_k = np.linalg.solve(G_k,-1 * der) error1 = cal_rosenbrock(pre_x) - cal_rosenbrock(pre_x + S_k) error2 = -1.0 * np.dot(der,S_k.transpose()) + 0.5 * np.dot(np.dot(S_k.transpose(),rosen_hess(pre_x)),S_k) r = error1 / error2 #比较r值 #如果r大于0 if r > 0: pre_x = pre_x + S_k # 如果r值小于0.25,步子太大,缩小范围,令 μk+1=4μk if r < 0.25: miu = 4 * miu # 如果r大于0.75 ,到信赖域边缘,步子有点小,令 μk+1=μk/2 elif r > 0.75: miu = miu / 2.0 # 如果r大于等于0.25且小于等于0.75 ,介于信赖域与非信赖域之间,令 μk+1=μk elif r >= 0.25 and r <= 0.75: miu = miu # r小于0,即沿反方向上升,应停步,按照r小于0.25缩小范围 elif r <= 0: pre_x = pre_x miu = 4 * miu loss = cal_rosenbrock(pre_x) # 最小值为0 X_all = np.vstack((X_all,pre_x)) print("count: ", cnt, "the loss:", loss,"μ:",miu) loss_all.append(loss) cnt += 1 x = X_all[:,0] y = X_all[:,1] z = loss_all draw(x,y) draw2(x,y) return pre_xif __name__ == '__main__': w = for_rosenbrock_func() print(w)
11维函数求解
import numpy as np import matplotlib as plt def cal_rosenbrock(x): # 计算rosenbrock函数的值 return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)def rosen_der(x): xm = x[1:-1] xm_m1 = x[:-2] xm_p1 = x[2:] der = np.zeros_like(x) der[1:-1] = 200*(xm-xm_m1**2) - 400*(xm_p1 - xm**2)*xm - 2*(1-xm) der[0] = -400*x[0]*(x[1]-x[0]**2) - 2*(1-x[0]) der[-1] = 200*(x[-1]-x[-2]**2) return derdef rosen_hess(x): x = np.asarray(x) H = np.diag(-400*x[:-1],1) - np.diag(400*x[:-1],-1) diagonal = np.zeros_like(x) diagonal[0] = 1200*x[0]**2-400*x[1]+2 diagonal[-1] = 200 diagonal[1:-1] = 202 + 1200*x[1:-1]**2 - 400*x[2:] H = H + np.diag(diagonal) return Hdef check(T): c = 0 for i in T[0:]: if i <= 0: c = 1 break return cdef for_rosenbrock_func(max_iter_count = 1000): pre_x = np.zeros((11,),dtype=np.float32) loss = 10 cnt = 0 I = np.eye(11) miu = 1 while loss > 0.001 and cnt < max_iter_count: der = np.zeros((11,), dtype=np.float32) Hess = np.zeros((11,), dtype=np.float32) # 计算梯度,hessian矩阵 der = rosen_der(pre_x) G_k = rosen_hess(pre_x) + miu * I T_vector = np.linalg.eigvals(G_k) #计算特征值 # 如果不正定,阻尼系数扩大四倍 while check(T_vector) : miu = 4 * miu G_k = rosen_hess(pre_x) + miu * I T_vector = np.linalg.eigvals(G_k) S_k = np.linalg.solve(G_k,-1 * der) error1 = cal_rosenbrock(pre_x) - cal_rosenbrock(pre_x + S_k) error2 = -1.0 * np.dot(der,S_k.transpose()) + 0.5 * np.dot(np.dot(S_k.transpose(),rosen_hess(pre_x)),S_k) r = error1 / error2 #比较r值 #如果r大于0 if r > 0: pre_x = pre_x + S_k # 如果r值小于0.25,步子太大,缩小范围,令 μk+1=4μk if r < 0.25: miu = 6 * miu # 如果r大于0.75 ,到信赖域边缘,步子有点小,令 μk+1=μk/2 elif r > 0.75: miu = miu / 2.0 # 如果r大于等于0.25且小于等于0.75 ,介于信赖域与非信赖域之间,令 μk+1=μk elif r >= 0.25 and r <= 0.75: miu = miu # r小于0,即沿反方向上升,应停步,按照r小于0.25缩小范围 elif r <= 0: pre_x = pre_x miu = 6 * miu loss = cal_rosenbrock(pre_x) # 最小值为0 print("count: ", cnt, "the loss:", loss,"μ:",miu) cnt += 1 return pre_xif __name__ == '__main__': w = for_rosenbrock_func() print(w)
阅读全文
0 0
- 信赖域求解Rosenbrock函数(LM求解子问题)
- 利用信赖域算法求解无约束的非线性最小二乘问题~
- 迭代求解最优化问题——信赖域方法
- 递归函数求解问题
- 最长子段问题求解
- 求解最大子数组问题
- 求解最大子数组问题
- 最大子序列问题求解
- 最长递增子序列问题的求解(LIS)
- 关于最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 最长公共子序列问题(动态规划求解)
- 最大子数组求解问题(算法导论)
- Trust-Region with DogLeg method 信赖域和狗腿法的最优化求解
- 函数求解
- AI医疗--概念,应用场景及现状解析
- define与inline的区别
- hadoop 2.7.4伪分布式安装(参照官网单节点安装)
- Ubuntu下的内核编译
- 【USACO题库】3.1.6 Stamps邮票
- 信赖域求解Rosenbrock函数(LM求解子问题)
- owncloud的安装配置和使用
- C++小技巧之CONTAINING_RECORD
- [剑指offer]二维数组中的查找
- HTTP报文结构
- HTTPS
- ubuntu 16.04 LTS
- java 多线程
- 微信公众号 群发文本消息