【问题标题】:Minimize function of x最小化 x 的函数
【发布时间】:2017-01-27 11:43:04
【问题描述】:

我有一个函数需要最小化,

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 并在二分查找中给出了以下条件

如果(f(中+e)

但是,我没有得到正确的结果。我正在寻找小数点后 6-7 位的精度。任何代码/伪代码形式的帮助将不胜感激。

【问题讨论】:

  • 格式化你的问题(不好读)。展示你的代码并多解释一下你在做什么和你在观察什么。 But, I am not getting correct results for this 是什么意思?你需要什么样的精度?哪种编程语言?
  • 我做了一些更改。我希望现在很清楚。
  • 你仍然没有解释你的结果出了什么问题,你也没有显示任何代码或告诉我们编程语言。通常人们会使用在某个库中实现的经典优化算法。因此,在 python/scipy 中向您展示一些代码可能对您没有帮助。
  • 我没有得到我需要的准确度(小数点后 6-7 位)。任何语言都可以。即使是伪代码也可以。
  • 局部最优还是全局最优解?它似乎是非凸的,这是关于全局解决方案的问题。

标签: mathematical-optimization binary-search


【解决方案1】:

这个问题看起来是非凸的,这通常是一个问题,因为非凸优化非常困难。特别是结合对高精度解决方案的需求。一般来说,这是不可行的(找到任何全局最小值),但是对于这么小的问题有机会(但准确性可能仍然是一个问题)。

以下代码(python + scipy + pyomo + couenne)只是一些可能的方法的一些演示。最好的方法当然是利用函数的一些特性。

  • scipy:开源通用科学函数库
  • pyomo:开源线性/非线性数学规划库
  • couenne:开源全局 MINLP 求解器

大体思路是:

  • 使用经过充分测试的标量最小化算法,如brent's algorithm 来解决您的问题
    • 这对您来说可能已经足够了(但不能保证全局解决方案)
    • 应该支持大多数语言
  • 与使用求解器 couenne 的非凸/非线性 MINLP 方法进行比较
    • 查看 couenne 的文档以了解发生了什么
  • 只是为了好玩:使用couenne的解决方案并尝试对其进行抛光
    • 使用上述标量最小化方法(这次:更保守/安全的方法goldenboundedbrentq 使用了一些重要的技巧来加速收敛)以 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

这些优化器的性能可能在很大程度上取决于您选择的问题常量。你必须决定走哪条路。我不知道您使用的是哪种语言以及可用的库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    相关资源
    最近更新 更多