最小化f(x,y),其中x和y是整数

时间:2009-07-24 14:36:48

标签: c# algorithm numerical-analysis minimization

我想知道是否有人有任何关于最小化函数的建议,f(x,y),其中x和y是整数。我已经研究了很多最小化和优化技术,比如BFGS和GSL中的其他技术,以及Numerical Recipes的内容。到目前为止,我已尝试实现几种不同的方案。第一种方法是选择最大下降方向f(x + 1,y),f(x-1,y),f(x,y + 1),f(x,y-1),并按照该方向线最小化。我也尝试过使用下坡单纯(Nelder-Mead)方法。两种方法都远离最低限度。它们似乎都在更简单的函数上工作,比如找到抛物面的最小值,但我认为两者,尤其是前者,都是针对x和y是实值(双精度)的函数而设计的。还有一个问题是我需要尽可能少地调用f(x,y)。它与外部硬件通信,每次呼叫需要几秒钟。任何想法都将非常感激。

以下是错误功能的示例。对不起,我之前没有发帖。此功能需要几秒钟的时间来评估。此外,我们从设备查询的信息如果低于我们想要的值,则不会添加到错误中,只有当它高于

double Error(x,y)
{
  SetDeviceParams(x,y);
  double a = QueryParamA();
  double b = QueryParamB();
  double c = QueryParamC();
  double _fReturnable = 0;
  if(a>=A_desired)
  {
    _fReturnable+=(A_desired-a)*(A_desired-a);
  }
  if(b>=B_desired)
  {
    _fReturnable+=(B_desired-b)*(B_desired-b);
  }
  if(c>=C_desired)
  {
    _fReturnable+=(C_desired-c)*(C_desired-c);
  }
  return Math.sqrt(_fReturnable)
}

8 个答案:

答案 0 :(得分:4)

这里有很多很多解决方案。事实上,基于这一主题有完整的书籍和学科。我现在正在阅读一篇优秀的文章:How to Solve It: Modern Heuristics

没有一种解决方案是正确的 - 根据您对功能的具体了解,不同的解决方案具有不同的优势。甚至已经证明,没有一种启发式方法能够在所有优化任务中发挥最佳性能。

如果您知道您的函数是二次函数,则可以使用Newton-Gauss一步找到最小值。遗传算法可以是一个很好的通用工具,或者你可以尝试模拟退火,这不太复杂。

答案 1 :(得分:3)

你看过遗传算法了吗?他们非常非常善于发现最小值和最大值,同时避免局部最小值/最大值。

答案 2 :(得分:2)

如果它是一个任意函数,那就没有巧妙的方法了。

假设我们有一个定义为:

的函数
f(x, y) = 0 for x==100, y==100
          100 otherwise

任何算法如何真实地找到(100,100)作为最小值?它可以是任何可能的价值组合。

你知道关于你正在测试的功能吗?

答案 3 :(得分:2)

你如何定义f(x,y)?最小化是一个难题,取决于函数的复杂性。

遗传算法可能是一个很好的候选者。

资源:

Genetic Algorithms in Search, Optimization, and Machine Learning

Implementing a Genetic Algorithms in C#

Simple C# GA

答案 4 :(得分:1)

您通常要寻找的是数学中的optimisation technique。一般来说,它们适用于实值函数,但许多函数可以适用于整数值函数。

特别是,我建议您查看non-linear programminggradient descent。两者似乎都非常适合您的应用。

如果您可以提供更多详细信息,我可能会建议一些更具体的信息。

答案 5 :(得分:1)

Jon Skeet的回答是正确的。你确实需要关于f及其衍生物的信息,即使f在任何地方都是连续的。

理解你所要求的困难的最简单方法(仅在整数值处最小化f)只是考虑一个变量的f:R-> R(f是实数的实值函数)这使得各个整数之间出现大的偏差。您可以轻松地构造这样的函数,使得实线上的局部最小值与整数的最小值之间没有相关性,并且与一阶导数没有关系。

对于任意函数,除了蛮力之外我都没办法。

答案 6 :(得分:1)

让我们看看你在数学方面的问题。这一切都假设我理解 你的问题完全。如果我弄错了,请随时纠正我。

我们希望尽量减少以下内容:

\ sqrt((a-a_desired)^ 2 +(b-b_desired)^ 2 +(c-c_desired)^ 2)

或其他表示法 || Pos(x - x_desired)|| _2

其中x =(a,b,c)和Pos(y)= max(y,0)意味着我们想要“正面部分”(这个帐户) 为你的if语句)。最后,我们希望限制自己 解决方案,其中x是整数值。

与上述海报不同,我认为遗传算法根本不是你想要的 事实上,我认为解决方案要容易得多(假设我理解你的问题)。

1)在上面的函数中运行任何优化例程。这会给你 解x ^ * =(a ^ *,b ^ *,c ^ *)。随着这个功能的不断增加 对于变量,您可以期待的最佳整数解决方案是 (小区(一个^ *),小区(B ^ *),小区(C ^ *))。

现在你说你的功能很难评估。有工具 对于这不是基于启发式的。以Derivative-Free为名称 优化。人们使用这些工具来优化基于模拟的目标(我有 甚至听说过一个目标函数基于作物收获率的情况!)

这些方法中的每一种都具有不同的属性,但通常它们会尝试 不仅要最小化目标,还要减少目标函数评估的数量。

答案 7 :(得分:0)

抱歉格式化以前太糟糕了。这是错误函数的一个例子

double Error(x,y)
{
SetDeviceParams(x,y);
double a = QueryParamA();
double b = QueryParamB();
double c = QueryParamC();
double _fReturnable = 0;
if(a>=A_desired)
{
  _fReturnable+=(A_desired-a)*(A_desired-a);
}
if(b>=B_desired)
{
 _fReturnable+=(B_desired-b)*(B_desired-b);
}
if(c>=C_desired)
{
  _fReturnable+=(C_desired-c)*(C_desired-c);
}
return Math.sqrt(_fReturnable)
}