函数最小化时如何限制theta角的取值范围在0到π之间?
给theta角添加0到π范围限制的实现方案
给theta加0到π的限制,不需要修改目标函数的核心计算逻辑,更稳妥的方式是用支持边界约束的优化器,比在目标函数里加惩罚项靠谱得多,下面是具体实现:
方法一:使用带边界约束的优化器(推荐)
你原来用的optimize.fmin是无约束优化函数,换成scipy.optimize.fmin_l_bfgs_b即可直接设置变量的上下界,它专门处理带边界约束的优化问题。
修改后的完整代码
import math import numpy as np from scipy import optimize # 假设X、Y、Z、R0及SIMPLEX相关常量已提前定义 fi = [] theta = [] for i in range(1, 36): fi.append(10*i*math.pi/180) for j in range(1, 36): theta.append(10*j*math.pi/180) def f(params): phi, teta = params count = 0. for u in range(len(X)): count += ((R0[u] - X[u]*math.sin(teta)*math.cos(phi) - Y[u]*math.sin(teta)*math.sin(phi) - Z[u]*math.cos(teta))/(len(X) + 2))**2 return count # 定义边界:phi无范围限制,theta强制约束在0到π之间 bounds = [(-np.inf, np.inf), (0, np.pi)] for q in range(len(fi)): for w in range(len(theta)): initial_p = [fi[q], theta[w]] # 调用带边界约束的优化器 result = optimize.fmin_l_bfgs_b( f, initial_p, bounds=bounds, maxiter=SIMPLEX_CALCU_LIMIT, factr=1e7, # 对应原fmin的ftol参数,1e7等价于ftol=1e-7,可根据需求调整 disp=False ) # 优化结果解析:result[0]是最优参数,result[1]是目标函数值,按需处理 optimized_phi, optimized_theta = result[0]
说明
bounds参数是一个二元组列表,每个元素对应一个变量的(下界, 上界),这里给theta明确设置了0到π的范围,phi保持无约束。factr参数用来控制收敛精度,和原代码中ftol的作用一致,可根据SIMPLEX_SIZE_LIMIT调整数值。
方法二:在目标函数中添加惩罚项(不推荐)
如果非要继续使用optimize.fmin,可以在目标函数里加惩罚逻辑:当theta超出0~π范围时,返回一个极大值,让优化器自动避开这类参数。但这种方法稳定性差,不推荐使用。
修改后的目标函数示例
def f(params): phi, teta = params # 超出范围时返回极大值,强制优化器避开 if not (0 <= teta <= math.pi): return 1e10 # 设一个足够大的惩罚值 count = 0. for u in range(len(X)): count += ((R0[u] - X[u]*math.sin(teta)*math.cos(phi) - Y[u]*math.sin(teta)*math.sin(phi) - Z[u]*math.cos(teta))/(len(X) + 2))**2 return count
缺点
惩罚值设置过小可能约束不住theta,设置过大又可能导致优化器收敛异常,不如专门的约束优化器可控。
内容的提问来源于stack exchange,提问作者Fridrieh
相关产品推荐
相关产品推荐

