如何指定Scipy Nelder-Mead最小化器的初始变量处理顺序?
Nelder-Mead方法下优先处理指定变量的解决方案
首先明确:Scipy的Nelder-Mead是基于单纯形的优化方法,它没有内置参数可以直接指定变量的处理顺序——因为它的迭代是针对整个参数向量的单纯形变形,而非逐个变量依次优化。但可以通过以下两种间接方式实现你“优先处理初始猜测中最大值变量”的需求:
1. 重新排序变量,将高优先级变量放在数组前列
把初始猜测中值更大(对应代价函数权重更高)的变量放到数组前面,同时调整代价函数的变量顺序以匹配对应权重。这种方式下,由于高优先级变量对代价函数的影响更显著,Nelder-Mead在迭代过程中会更积极地调整这些变量的取值。
修改后的代码示例
import numpy as np from scipy.optimize import minimize # 调整变量顺序:按初始值从大到小排列,对应权重从10到1 def CostFunction(x, OtherArguments): # x[0]对应原变量j(初始1000,权重10),x[9]对应原变量a(初始100,权重1) return x[0]*10 + x[1]*9 + x[2]*8 + x[3]*7 + x[4]*6 + x[5]*5 + x[6]*4 + x[7]*3 + x[8]*2 + x[9]*1 # 初始猜测按原数值从大到小排序 InitialGuessArray = np.array([1000, 900, 800, 700, 600, 500, 400, 300, 200, 100]) # 执行最小化 CostFunctionMinimized = minimize( CostFunction, InitialGuessArray, args=OtherArguments, method="Nelder-Mead", options={"disp": True, "maxiter": MinimizeMaxiter}, tol=MinimizeTol, bounds=None ) # 若需要还原回原变量顺序,反转结果数组即可 original_order_result = CostFunctionMinimized.x[::-1]
2. 自定义初始单纯形,提升高优先级变量的步长敏感度
Nelder-Mead的初始单纯形默认步长是固定比例(变量值的5%或0.05),你可以手动构造初始单纯形,给初始值更大的变量设置更大的步长。这样迭代时,这些变量的调整幅度会更显著,相当于被“优先处理”。
修改后的代码示例
import numpy as np from scipy.optimize import minimize # 修正原代价函数的语法错误 def CostFunction(x, OtherArguments): a, b, c, d, e, f, g, h, i, j = x return a*1 + b*2 + c*3 + d*4 + e*5 + f*6 + g*7 + h*8 + i*9 + j*10 InitialGuessArray = np.array([100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]) # 给每个变量设置与初始值成正比的步长(比如10%) step_sizes = InitialGuessArray * 0.1 # 构造初始单纯形:初始猜测为第一个顶点,其余顶点依次对单个变量增加对应步长 initial_simplex = np.array([ InitialGuessArray ] + [ InitialGuessArray + step_sizes * np.eye(len(InitialGuessArray))[k] for k in range(len(InitialGuessArray)) ]) # 执行最小化,传入自定义初始单纯形 CostFunctionMinimized = minimize( CostFunction, InitialGuessArray, args=OtherArguments, method="Nelder-Mead", options={"disp": True, "maxiter": MinimizeMaxiter, "initial_simplex": initial_simplex}, tol=MinimizeTol, bounds=None )
额外说明
原代码中的代价函数定义存在语法错误,正确的写法应该是将参数声明为x,再从x中解包变量,如上述示例所示。
内容的提问来源于stack exchange,提问作者Amir Ghorbani
相关产品推荐
相关产品推荐

