使用scipy basinhopping时,如何不用全局变量实现回调展示优化进度?
替代全局变量的几种优雅实现方式
1. 使用类封装状态
通过类来封装当前最小值的状态,既避免了全局变量,又能清晰地管理跟踪逻辑,适合需要复用或扩展进度跟踪功能的场景:
class ProgressTracker: def __init__(self, initial_min): self.min_val = initial_min def callback(self, x, f, accept): if f < self.min_val: print([round(num, 2) for num in x], f) self.min_val = f # 使用方式 print("Optimizing using basinhopping") tracker = ProgressTracker(initial_min=10) res = basinhopping(distance, x0=points, niter=1000, minimizer_kwargs={"bounds": bounds, "constraints": cons, "method": "SLSQP"}, callback=tracker.callback)
2. 使用闭包(Closure)
利用闭包捕获外部作用域的变量,无需定义完整类,实现轻量级的状态跟踪:
def make_bh_callback(initial_min): min_val = initial_min def callback(x, f, accept): nonlocal min_val if f < min_val: print([round(num, 2) for num in x], f) min_val = f return callback # 使用方式 print("Optimizing using basinhopping") bh_callback = make_bh_callback(initial_min=10) res = basinhopping(distance, x0=points, niter=1000, minimizer_kwargs={"bounds": bounds, "constraints": cons, "method": "SLSQP"}, callback=bh_callback)
3. 使用可变对象存储状态
借助列表这类可变对象的特性,绕过全局变量直接修改状态值,适合快速实现的简单场景:
def show_bh(x, f, accept): if f < min_val[0]: print([round(num, 2) for num in x], f) min_val[0] = f # 使用方式 print("Optimizing using basinhopping") min_val = [10] # 用列表存储可变状态 res = basinhopping(distance, x0=points, niter=1000, minimizer_kwargs={"bounds": bounds, "constraints": cons, "method": "SLSQP"}, callback=show_bh)
内容的提问来源于stack exchange,提问作者Simd
相关产品推荐
相关产品推荐

