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

Jupyter Notebook内核重启:NLopt优化Rosenbrock函数报错排查

问题排查与代码修复

你的代码存在多个明确错误,这些是导致Jupyter内核重启的核心原因,以下是具体问题和修复方案:

1. 未定义函数与无效赋值

  • myfunc1里的NULL是Python不存在的标识符,无梯度优化器需要在grad非空时填充合理值,应替换为np.zeros_like(grad)。
  • myfunc2调用了未定义的Rosen_grad函数,会直接抛出NameError导致崩溃,必须补充实现Rosenbrock函数的梯度计算逻辑。

2. 错误的条件判断逻辑

循环中的i是数组索引(整数类型),你用它和字符串"LD_MMA"/"LD_LBFGS"做比较,这个判断永远不成立,所有优化器都会错误使用myfunc1,梯度型优化器无法获取所需梯度,引发逻辑异常。应改为用names[i]判断优化器类型。

3. 文件操作错误

  • 'results' + i中i是整数,无法直接与字符串拼接,会抛出TypeError,需转为字符串,比如用f'results_{names[i]}.txt'命名文件。
  • f.write([...])试图直接写入列表,文件对象仅接受字符串/字节类型,需要将结果格式化为字符串后再写入。

4. 资源耗尽的循环设计

while time.time()-ini < 180循环会在3分钟内不断增大j的值(变量维度持续升高),高维优化问题会快速消耗内存和CPU,最终导致Jupyter内核因资源耗尽重启。如果需要测试不同维度,应限制j的最大值,或改为固定维度测试。

5. 无效的优化器参数

opt.set_xtol_rel(0)是无效设置,nlopt要求相对容差必须大于0,建议改为1e-8。


修复后的代码示例

import nlopt
import numpy as np
import time

def Rosenbrock(x):
    N = len(x)
    x1 = x[:-1]
    x2 = x[1:]
    return np.sum(100 * np.square(x2 - np.square(x1)) + np.square(np.ones(N-1) - x1))

def Rosen_grad(x):
    # 实现Rosenbrock函数的梯度计算
    N = len(x)
    grad = np.zeros(N)
    grad[:-1] += -400 * x[:-1] * (x[1:] - x[:-1]**2) - 2 * (1 - x[:-1])
    grad[1:] += 200 * (x[1:] - x[:-1]**2)
    return grad

def myfunc1(x, grad):
    if grad.size > 0:
        grad[:] = np.zeros_like(grad)
    return Rosenbrock(x)

def myfunc2(x, grad):
    if grad.size > 0:
        grad[:] = Rosen_grad(x)
    return Rosenbrock(x)

names = ["LN_SBPLX", "LN_NELDERMEAD", "LN_PRAXIS", "LN_NEWUOA", "LN_BOBYQA", "LN_COBYLA", "LD_MMA", "LD_LBFGS"]
max_dim = 10  # 限制最大测试维度,避免资源耗尽
j = 2

for idx, opt_name in enumerate(names):
    ini = time.time()
    # 限制维度增长,避免无限循环消耗资源
    while time.time() - ini < 180 and j <= max_dim:
        x0 = np.repeat(0, j)
        print(f"Testing optimizer: {opt_name}, dimension: {j}")
        # 直接调用优化器枚举值,避免字符串拼接
        opt_type = getattr(nlopt, opt_name)
        opt = nlopt.opt(opt_type, len(x0))
        
        # 正确判断优化器类型
        if opt_name in ["LD_MMA", "LD_LBFGS"]:
            opt.set_min_objective(myfunc2)
        else:
            opt.set_min_objective(myfunc1)
        
        opt.set_lower_bounds(np.repeat(-10, len(x0)))
        opt.set_upper_bounds(np.repeat(10, len(x0)))
        opt.set_xtol_rel(1e-8)
        opt.set_stopval(1e-8)
        
        start = time.time()
        try:
            x = opt.optimize(x0)
            end = time.time()
            result = opt.last_optimize_result()
            # 格式化结果为字符串写入文件
            with open(f'results_{opt_name}_dim{j}.txt', 'w') as f:
                f.write(f"Optimizer: {opt_name}\n")
                f.write(f"Dimension: {j}\n")
                f.write(f"Time elapsed: {end - start:.4f}s\n")
                f.write(f"Optimization result code: {result}\n")
                f.write(f"Optimal x: {x}\n")
                f.write(f"Optimal value: {Rosenbrock(x):.6f}\n")
        except Exception as e:
            print(f"Error with {opt_name} (dim {j}): {str(e)}")
            continue
        j += 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:50:34