比试错更有效地优化多个变量的算法
本文关键字:变量 算法 优化 有效地 | 更新日期: 2023-09-27 18:34:29
谷歌在这方面的结果似乎需要比我熟悉的更高级的数学(我可能并不比五年级学生聪明,但我不打算找出答案(。
我正在寻找一种解决多元优化问题的通用方法,最好是在 c# 中,而无需深入研究矩阵、特征向量和正态分布。
假设我有数值变量 x、y、z 和 w,以及函数 f,使得 w = f(x, y, z)
.我想最大化w,并且...
-
f
未知 -
x
、y
和/或z
之间的相互依赖性(如果有的话(是未知
的 - 在某些情况下,我只有事后数据集
- 在其他情况下,我可以改变
x
、y
和z
,并按需重新采样w
- 在先验情况下,理想算法以最少的
x
、y
和z
的试验排列来最大化w
,并在每一轮抽样后为每个选择下一个值
我对自变量有粗略的最小和最大界限。我当然不想对不必要的排列空间进行采样。我希望该算法至少具有粗略的能力来检测最明显的相互依赖关系,例如,当x
> 2y
时收益递减,或者当x
、 y
和z
的总和超过某个上限时,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 实现。