Scipy的direct优化器在简易测试优化问题中过早终止,求可行解决方法
看起来你遇到的问题是Scipy的direct优化器因为默认的终止阈值设置得过于严格,导致它还没探索到真正的最优区域就早早停下了。咱们来一步步解决这个问题:
1. 调整vol_tol参数(最关键的一步)
direct优化器的终止条件之一是:当包含当前最优解的超矩形体积低于vol_tol时,就会认定“已经找到足够好的解”。默认的vol_tol=1e-16对于20维的问题来说,超矩形的体积会下降得极快——毕竟20维下,哪怕每个维度只分割几次,体积都会变成极小的数值,很容易触发终止。
你可以把这个值调大一些,让优化器继续分割搜索区域,探索更多可能的解。比如改成vol_tol=1e-6或者更大:
result = direct(score, locally_biased=False, bounds=bounds, maxiter=10000, maxfun=10000, vol_tol=1e-6)
2. 调整epsilon参数
epsilon是控制优化器判断“两个点是否足够接近”的阈值,调大这个值可以让优化器更关注大范围的搜索区域,而不是过早聚焦在某个局部区域。比如加上epsilon=1e-2:
result = direct(score, locally_biased=False, bounds=bounds, maxiter=10000, maxfun=10000, vol_tol=1e-6, epsilon=1e-2)
3. 尝试启用locally_biased模式
虽然你现在设置了locally_biased=False,但这个模式默认是开启的——它会让优化器在找到一个较好的解后,优先在这个解的周围进行更细致的搜索。你的最优解是一个大范围的平坦区域(所有变量等于非4-6区间的数),启用这个模式说不定能帮助优化器更快地锁定这个区域,你可以试试去掉locally_biased=False,用默认的True来测试。
为什么会出现这个问题?
你的目标函数里,当所有变量都等于5时,main_score(变量差分的绝对值最大值)是0,但parity_in_range是20%3=2,总得分2。direct一开始可能在5附近的区域找到了这个得分较低的点,然后因为超矩形体积很快降到了默认的1e-16以下,就直接终止了,完全没来得及探索0-4或者6-10这些能得到0分的区域。
通过调整上面的参数,让优化器有更多的空间和次数去探索整个搜索范围,应该就能找到真正的最优解了。
备注:内容来源于stack exchange,提问作者Simd

