You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效获取含两个局部极小值函数的全局最小值?

单变量双局部极小值函数的全局优化解决方案

问题背景

需要最小化一个已知存在两个局部极小值的函数,但使用scipy.optimize.minimize_scalar只能找到局部最优解。由于需要执行数千次该计算,要求解决方案高效、耗时低。

函数定义

用于计算目标结果的函数如下:

import numpy as np

def get_v_theta(v, theta):
    vx = v[0]
    vy = v[1]
    vz = v[2]
    v_theta = (vx + vy)/2 + (vx - vy)/2*np.cos(2*theta) + vz*np.sin(2*theta)
    return v_theta

def get_result(v1_theta, v2_theta):
    v_max = max(v1_theta, v2_theta)
    v_min = min(v1_theta, v2_theta)
    v_med = (v_max + v_min)/2
    v_alt = (v_max - v_min)/2
    if v_med > 0:
        result = (v_alt/100 + v_med/400)**(-1)
    else:
        result = 100/v_alt
    return result

def get_result_theta(theta, v1, v2):
    v1_theta = get_v_theta(v1, theta)
    v2_theta = get_v_theta(v2, theta)
    return get_result(v1_theta, v2_theta)

复现问题

给定示例向量:

v1 = np.array([2.91931, 0.758059, 0.10201])
v2 = np.array([-1.29405, 7.76101, -1.75803])

通过绘图可观察到全局极小值约在θ ≈ -1.4处:

import matplotlib.pyplot as plt

thetas = np.arange(-np.pi/2, np.pi/2, np.pi/100)
results = [get_result_theta(t, v1, v2) for t in thetas]
plt.plot(thetas, results)
plt.show()

但直接使用minimize_scalar仅能得到局部极小值θ ≈ 0.147:

from scipy import optimize

res = optimize.minimize_scalar(get_result_theta, args=(v1, v2), method='bounded', bounds=(-np.pi/2, np.pi/2))
print(res.x)  # 输出约0.147

快速全局优化方案

由于已知函数仅有两个局部极小值,可通过多初始点局部优化的方式快速找到全局最优,该方法耗时远低于全局优化算法(如差分进化),适合大规模计算。

实现思路

在目标区间内选取多个覆盖不同区域的初始点,分别执行局部优化,最终保留结果最小的那个解。因为函数只有两个局部极小值,只需选取2-5个初始点即可覆盖所有可能的极小值区域。

代码实现

def find_global_min(v1, v2):
    # 选取覆盖区间的初始点,确保涵盖两个极小值区域
    init_points = [-np.pi/2, -np.pi/4, 0, np.pi/4, np.pi/2]
    best_fun = float('inf')
    best_theta = None
    
    for init in init_points:
        # 执行局部有界优化
        res = optimize.minimize_scalar(
            get_result_theta,
            args=(v1, v2),
            method='bounded',
            bounds=(-np.pi/2, np.pi/2),
            x0=init
        )
        # 更新最优结果
        if res.fun < best_fun:
            best_fun = res.fun
            best_theta = res.x
    return best_theta, best_fun

# 测试示例
best_theta, best_fun = find_global_min(v1, v2)
print(f"全局最优θ: {best_theta:.3f}, 最小结果: {best_fun:.3f}")
# 输出应为θ≈-1.4,对应最小结果

额外优化:提升函数计算速度

由于需要执行数千次计算,可简化目标函数的计算逻辑,减少重复运算:

def get_v_theta(v, theta):
    cos2t = np.cos(2 * theta)
    sin2t = np.sin(2 * theta)
    return (v[0] + v[1])/2 + (v[0] - v[1])/2 * cos2t + v[2] * sin2t

def get_result(v1_theta, v2_theta):
    v_max = max(v1_theta, v2_theta)
    v_min = min(v1_theta, v2_theta)
    v_med = (v_max + v_min) / 2
    v_alt = (v_max - v_min) / 2
    return (v_alt/100 + v_med/400)**(-1) if v_med > 0 else 100/v_alt

替代方案:粗扫描+局部优化

如果不确定初始点的选择,可先对区间进行粗扫描,找到结果较小的几个候选点,再对这些点做局部优化:

def find_global_min_scan(v1, v2):
    # 粗扫描区间
    scan_thetas = np.linspace(-np.pi/2, np.pi/2, 20)
    scan_results = [get_result_theta(t, v1, v2) for t in scan_thetas]
    # 取结果最小的前2个点作为初始点
    top2_indices = np.argsort(scan_results)[:2]
    init_points = scan_thetas[top2_indices]
    
    best_fun = float('inf')
    best_theta = None
    for init in init_points:
        res = optimize.minimize_scalar(get_result_theta, args=(v1, v2), method='bounded', bounds=(-np.pi/2, np.pi/2), x0=init)
        if res.fun < best_fun:
            best_fun = res.fun
            best_theta = res.x
    return best_theta, best_fun

内容的提问来源于stack exchange,提问作者Juan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:32:30