我有一个我需要最小化的功能,
其中x1,y1,x2,y2,v2,v1给我。我必须为任何x找到此函数的全局最小值。
我发现函数的全局最小值将是min(x1,x2)和max(x1,x2)之间的x,并且范围之间的函数应该是U形曲线。所以,取low = min(x1,x2)和high = max(x1,x2),我做了一个二元搜索,在那里我得了一个效率参数e = 0.000001,并在二元搜索中给出了以下条件
if(f(mid + e)< f(mid)) 高=中间-E; 其他 低=中间+ E;
但是,我没有得到正确的结果。我正在寻找6-7位小数的准确度。任何形式的代码/伪代码的帮助将不胜感激。
答案 0 :(得分:0)
问题看起来是非凸的,这通常是一个问题,因为非凸优化非常困难。特别是与高精度解决方案的需求相结合。一般来说,它是不可行的(找到任何全局最小值),但有这样一个小问题有可能(但准确性可能仍然是一个问题)。
以下代码(python + scipy + pyomo + couenne)只是一些可能方法的一些演示。当然,最好的方法是使用函数的一些特性。
一般的想法是:
golden
和bounded
; brentq
使用一些重要的技巧来加速收敛)用couenne'作为界限的全局最小值(并通过一些小的常数eps加宽)from __future__ import division
from scipy.optimize import minimize_scalar, brute
import math
""" Constants """
x1 =3
x2 = 1
y1 = 0.5
y2 = 3
v1 = 2
v2 = 2
""" Scipy-based 1d-minimization using brentq (local-optimal) """
def f(x):
return math.sqrt(x**2 - 2*x1*x + x1**2 + y1**2) / v1 + \
math.sqrt(x**2 - 2*x2*x + x2**2 + y2**2) / v2
res = minimize_scalar(f)
print('Brentq: ', res.x)
""" Pyomo + Couenne based minimization (global-optimal) """
from pyomo.environ import *
from pyomo.opt import SolverFactory
model = ConcreteModel()
model.x = Var()
model.obj = Objective(expr=sqrt(model.x**2 - 2*x1*model.x + x1**2 + y1**2) / v1 + \
sqrt(model.x**2 - 2*x2*model.x + x2**2 + y2**2) / v2, sense=minimize)
opt = SolverFactory('couenne')
results = opt.solve(model)
print('Couenne: ', model.x.value)
""" Reopt 1d-minimization ("golden" + "bounded") with obtained bounds by couenne """
eps = 0.001
res = minimize_scalar(f, method='bounded', bounds=(model.x.value - eps, model.x.value + eps),
options={'xatol': 1e-9, 'maxiter': 1000})
print('Couenne reopt (bounded): ', res.x)
res = minimize_scalar(f, method='golden', bounds=(model.x.value - eps, model.x.value + eps),
options={'xtol': 1e-9})
print('Couenne reopt (golden): ', res.x)
Brentq:
2.71428567406
f(x)
2.01556443707
Couenne:
2.71428571429
f(x)
2.01556443707
Couenne reopt (bounded):
2.71428573487
f(x)
2.01556443707
Couenne reopt (golden):
2.71428570645
f(x)
2.01556443707
这些优化器的性能可能在很大程度上取决于所选问题的常量。你必须决定走哪条路线。我不知道您使用的语言和可用的库。