使用scipy.minimize求解极小化问题时如何保存更优的中间结果
实现方案
你只需要在原有回调函数基础上新增全局变量记录历史最优目标值,每次迭代判断当前结果是否更优,符合条件就追加写入txt文件即可,具体修改如下:
完整修改后代码
import numpy as np from scipy.optimize import minimize import os # 用于判断日志文件是否存在,方便生成表头 Nfeval = 1 best_obj = np.inf # 极小化问题初始最优值设为无穷大 log_file = "optimize_best_log.txt" # 保存最优结果的文件路径 def objective_fnc(x): .... return y def callbackF(x): global Nfeval, best_obj, log_file current_obj = objective_fnc(x) # 保留原有的迭代信息打印逻辑 print('{0:4d} {1: 3.6f} {2: 3.6f} {3: 3.6f} {4: 3.6f} {5: 3.6f}'.format(Nfeval, x[0], x[1], x[2], x[3], current_obj)) Nfeval += 1 # 判断当前结果是否优于历史最优 if current_obj < best_obj: best_obj = current_obj # 判断是否需要写入表头(文件不存在/文件为空时写表头) write_header = not os.path.exists(log_file) or os.path.getsize(log_file) == 0 # 追加模式写入文件,不会覆盖历史记录 with open(log_file, 'a+', encoding='utf-8') as f: if write_header: f.write("迭代次数,x1,x2,x3,x4,目标函数值\n") f.write(f"{Nfeval-1},{x[0]:.6f},{x[1]:.6f},{x[2]:.6f},{x[3]:.6f},{current_obj:.6f}\n") res=minimize(objective_fnc, x0, method='Nelder-Mead', bounds=bnds, callback=callbackF, options={'disp': True})
注意事项
- 如果是极大化优化,将判断条件
current_obj < best_obj改为current_obj > best_obj,同时将best_obj初始值设为-np.inf即可 - 写入使用追加模式
a+,即使程序意外中断,所有历史最优记录都会完整保存在txt中 - 如果不需要csv格式,可将写入内容中的逗号替换为空格、制表符等其他分隔符
- 若要降低重复计算目标函数的开销,可修改目标函数将最新计算值存在全局变量中,回调函数直接读取即可,无需重复调用
objective_fnc
内容的提问来源于stack exchange,提问作者nekovolta
相关产品推荐
相关产品推荐

