比试错更有效地优化多个变量的算法

本文关键字:变量 算法 优化 有效地 | 更新日期: 2023-09-27 18:34:29

谷歌在这方面的结果似乎需要比我熟悉的更高级的数学(我可能并不比五年级学生聪明,但我不打算找出答案(。

我正在寻找一种解决多元优化问题的通用方法,最好是在 c# 中,而无需深入研究矩阵、特征向量和正态分布。

假设我有数值变量 xyzw,以及函数 f,使得 w = f(x, y, z) .我想最大化w,并且...

  • f未知
  • xy和/或z之间的相互依赖性(如果有的话(是未知
  • 在某些情况下,我只有事后数据集
  • 在其他情况下,我可以改变xyz,并按需重新采样w
  • 在先验情况下,理想算法以最少的xyz的试验排列来最大化w,并在每一轮抽样后为每个选择下一个值

我对自变量有粗略的最小和最大界限。我当然不想对不必要的排列空间进行采样。我希望该算法至少具有粗略的能力来检测最明显的相互依赖关系,例如,当x> 2y时收益递减,或者当x yz的总和超过某个上限时,w的实际恶化等。

看过的大多数数学库都假设我知道如何在Boigenfoodle Continuum上进行量子nergenflip投影,而我只是不在那里。非数学程序员将如何做到这一点?

比试错更有效地优化多个变量的算法

如果您不想卡在本地最小值中,可以尝试模拟退火。

基本上,从一些x,y,z开始,从零均值分布(正态分布或高斯分布(随机生成dx,dy和dz。如果 w(x+dx,y+dy,z+dz(> w(x,y,z(,则选择此新解决方案。否则选择它概率 w(x+dx,y+dy,z+dz(/w(x,y,z(。

蟒蛇代码

def simAnneal( w, seed_x, numSteps=100000, sigma=0.01 ):
    optimal_x = [i for i in seed_x]
    optimal_w = w(optimal_x)
    cur_w = w(seed_x)
    for i in range(numSteps):
        new_x = [i+random.gauss(0, sigma) for i in seed_x]
        new_w = w(new_x)
        if (new_w > cur_w) or (random.random() > new_w / cur_w) :
            cur_x = new_x
            cur_w = new_w
            if cur_w > optimal_w:
                optimal_w = cur_w
                optimal_x = cur_x
    return optimal_x

如果你能采样f,你可以做一些爬山。 从任意位置 (x,y,z( 开始。 样本 f 位于 (x,y,z( 和 (x+delta,y,z(。 如果后者更好,请搬到那里。 如果没有,请尝试一些较小的增量。 还可以尝试负增量和其他两个坐标上的增量。 当没有增量给你增加 f 时,你已经达到了最大值。

请注意,这只会为您提供局部最大值,不一定是全局最大值。 如果您的增量太小,它在数值上也非常不稳定。

如果你对f有所了解,你可以做得更好,比如它是x,y,z中的低次多项式。 然后,您可以对系数进行最小二乘拟合,然后通过将导数设置为零来最大化多项式。

看起来你可以从 http://www.dotnumerics.com/NumericalLibraries/Optimization/Default.aspx 获得 C# 的 Nelder-Mead 单纯形优化算法的实现。使用这种方法,您所要做的就是给它一些可以评估要在任意点优化的函数的东西。它不像需要导数的方法那样高效,事实上,它在数学上甚至不像 Torczon Simplex 变体那样受人尊敬 - 但人们确实使用它,我找不到免费的 C# Torczon Simplex 实现。