我有一个非常复杂的模型,需要解决许多参数。尽管模型复杂,但每一步的函数形式都不是不规则的。
我看到一些带有起始值的奇怪行为。如果我从标准的随机值(全为 0)开始,求解器会在 673 秒内收敛于“找到局部最优解”,0 次 CG 迭代。
如果我从我知道接近解的值开始,求解器会收敛于“原始可行解估计无法改进。”,493 次 CG 迭代,1718 秒。
请注意,在这两种情况下,最终值相同(或非常相似)。
2个问题:
从您的第一个问题中,我们了解到您正在使用“智能”求解器,即动态调整算法以实现最佳收敛。共轭梯度法是“长距离”寻找最优值的好方法,但在接近浅层最优值时收敛速度很慢。
与所有“智能”代码一样,也有启发式失败的情况,而您也遇到过这种情况。我假设你的最优解相当浅,所以如果你的参数稍微改变,目标函数(即你试图优化的实际标准)变化很小。现在求解器无法知道参数已经非常接近最优值。据它所知,在目标函数非常平坦的区域中,它可能离解很远。经过一些初始测试,因此默认使用共轭梯度法,这是一种接近最佳值的缓慢但安全的方法。但是,由于经过大量搜索后,它实际上并没有走得很远,它告诉您,如果幸运,您开始接近最佳状态,但如果您不走运,您的解决方案就很远,
如果您知道您的初始猜测会很好,那么您可能需要检查您的求解器是否允许指定应该/不应该使用哪些算法。
共轭梯度是一种梯度类型的优化算法(也称为“最速下降”),在某些情况下容易收敛缓慢。即使你接近最佳状态。
在WikiPedia 上,您可以找到说明这种行为的数字,我在这里修改了其中一个:
您看到的是等高线图上的 iso-cost(或 iso-objective)线。假设我们从第 1 点开始,这是一个很好的起始值。红线显示了达到最佳状态所采取的路径。我们看到它向最优方向曲折前进,这需要大量的函数评估,因此需要时间。
如果我们将其与选择 A 点作为起始值时的性能进行比较,我们会获得更快的收敛(或者至少,这是我在这种情况下所期望的)。让我们假设在这种情况下只需要一次迭代。
现在看看第 5 点,它显然接近最优值,但需要大量迭代才能达到最优值。当您接近一个狭窄的山谷时,算法会从一侧跳到另一侧,在途中只朝着最佳方向前进。当您从山谷较宽的一侧接近时,您会看到梯度更趋向于最佳状态,这会导致更快的收敛。
在您的情况下,可能是您的初始值有点像上面的第 5 点,而通用起始值与 A 点相当。这是假设您的起始值收敛到真实值,这可能不是案件。如果您的起始值接近但它与全局最优值之间存在一个峰值,那么您将不会收敛到正确的值,如下图所示。
当 knitro 更改为 CG 或他们的其他算法之一时,应该在文档中提及或只有 knitro 的开发人员知道。