无约束最优化问题之Rosenbrock法

无约束最优化问题之Rosenbrock方法

算法目的

  求解无约束优化问题的极小值(最小值)。

算法特点

  算法步骤中不需要计算目标函数的导数。

算法步骤

在这里插入图片描述

例题1

  用Rosenbrock方法解
min ⁡ f ( x ) : = ( x 1 − 3 ) 2 + 2 ( x 2 + 2 ) 2 . \min f(x):=(x_1-3)^2+2(x_2+2)^2. minf(x):=(x13)2+2(x2+2)2.

解:设置初始基点坐标 x ( 0 ) = ( 0 , 0 ) T x^{(0)}=(0,0)^T x(0)=(0,0)T,初始搜索方向集 d = { ( 1 , 0 ) T ,   ( 0 , 1 ) T } d=\{(1,0)^T,\ (0,1)^T \} d={ (1,0)T, (0,1)T},初始步长集 δ = { 1 ,   1 } \delta =\{1,\ 1\} δ={ 1, 1},加速因子 α = 3 \alpha = 3 α=3,衰减因子 β = − 0.5 \beta=-0.5 β=0.5,允许误差 ϵ = 0.01 \epsilon=0.01 ϵ=0.01

import numpy as np
import sys


# 定义目标函数
def function(x):
    return (x[0] - 3.) ** 2 + 2 * (x[1] + 2) ** 2


# 输入算法参数: 初始点坐标xk, 初始搜索方向sd, 初始步长delta, 加速因子alpha, 衰减因子beta, 允许误差epsilon
xk = np.array([0., 0])
sd = np.array([[1., 0], [0, 1]])
delta_0 = np.array([1., 1])
alpha = 3.
beta = -0.5
epsilon = 0.01

# 初始化大探测阶段数, 计算变量维数, 初始化第1大阶第1轮探测出发点和生成迭代用步长
k1, k2 = 1, 1
dim = len(xk)
y1 = xk.copy()
delta = delta_0.copy()

while 1:

    # 进入一个新的大探测阶段
    print('\n进入第', k1, '个大探测阶段')
    print('基点为:', xk, '函数值:', function(xk))
    print('各搜索方向:\n', sd)

    # 初始化用于构造新正交方向列的Lambda列
    Lambda = np.zeros([dim, 1])

    while 1:
        # 进入每一轮小探测
        print('\n  进入第', k2, '轮小探测')
        print('  探测出发点为:', y1)
        print('  各搜索步长:\n', delta)
        yk = y1.copy()
        for i in range(dim):
            t1, t2 = function(yk + delta[i] * sd[i]), function(yk)
            if t1 < t2:
                Lambda[i, 0] += delta[i]
                yk += delta[i] * sd[i]
                delta[i] *= alpha
            else:
                delta[i] *= beta
            print('  第', i + 1, '次探测得到的点;', yk, '函数值', function(yk))
        k2 += 1
        if function(yk) < function(y1):
            y1 = yk
        else:
            if function(yk) < function(xk):
                break
            elif False not in (np.abs(delta) <= epsilon):
                print('\n满足delta<=epsilon, 停止迭代, 最优解的估计:', xk, '函数值', function(xk))
                sys.exit()
            else:
                y1 = yk

    # 进入一个新的方向构造阶段
    if np.linalg.norm(yk - xk, ord=2) <= epsilon:
        print('\n满足||x(k+1)-x(k)|| <= epsilon, 停止迭代, 最优解的估计', yk, '函数值', function(yk))
        sys.exit()
    else:
        xk = yk
        y1 = yk

        # 新定义一组方向{p(n)}
        for i in range(dim):
            if Lambda[i] != 0:
                sd[i, :] = np.sum(Lambda[i:, 0] * sd[i:, :], axis=0)

        # 使用Gram-Schmidt正交化方法把{p(n)}正交化
        for i in range(1, dim):
            t = 0
            for j in range(i):
                t += (np.dot(sd[j, :], sd[i, :].T) / np.dot(sd[j, :], sd[j, :].T)) * sd[j, :]
            sd[i, :] -= t

        # 再单位化向量
        for i in range(dim):
            sd[i, :] /= np.linalg.norm(sd[i, :], ord=2)

        # 初始化步长
        delta = delta_0.copy()
    k1 += 1
    k2 = 1

  结果:

进入第 1 个大探测阶段
基点为: [0. 0.] 函数值: 17.0
各搜索方向:
 [[1. 0.]
 [0. 1.]]
 
  进入第 1 轮小探测
  探测出发点为: [0. 0.]
  各搜索步长:
 [1. 1.]1 次探测得到的点; [1. 0.] 函数值 12.02 次探测得到的点; [1. 0.] 函数值 12.0
  
  进入第 2 轮小探测
  探测出发点为: [1. 0.]
  各搜索步长:
 [ 3
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

此账号已停更

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值