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
相关产品推荐
相关产品推荐

