如何调试约束优化算法?

计算科学 优化 凸优化 约束优化
2021-12-09 20:48:37

我已经基于 Nesterov 教授的算法实现了一个鞍点优化问题,primal-dual[1]。不幸的是,它不起作用。似乎正在收敛。但不幸的是,不是我使用一些开箱即用的求解器获得的最佳解决方案。我相信开箱即用的求解器的结果是正确的。

我的问题是,根据论文的论点,算法必须正常工作。但是有些事情出错了。我想检查论文证明中的不等式和条件,但我不知道该怎么做?特别是因为许多不等式涉及未知的最优解(x)。有什么方法可以检查论文中的不等式,并了解导致我的实施不起作用的问题所在?

请注意,我使用相同的求解器解决了算法中的内部优化问题。

[1],Yurii Nesterov,凸问题的原始对偶次梯度方法,数学。程序。2009

3个回答

编写优化例程就像编写任何其他不太简单的程序一样,并且涉及大量调试。您在问题中提到的所有事情都是很好的检查(即注意理论上应该持有的所有事情确实在迭代期间保持)。

一些更一般的检查是:

  • 您确定解决方案是独一无二的吗?如果不是,两个求解器可能会返回不同的最优解。

  • 原始价值。看看原始目标值的值是否收敛。如果所有原始值都是有限的(即可行的),那么原始目标序列应该收敛到序列的最小值(不一定是单调的)。您还可以将算法结果的原始值与黑盒求解器的原始值进行比较。

  • 对偶值也是如此。

一些标准错误:

  • 步长错误。有时错误的步长仍然会导致收敛的方法,但实际上解决的是不同的问题。

  • 更新顺序错误。

  • 标志,尤其是在数据术语前面。

  • 各种错误,例如将迭代计数器的名称用于其他目的,意外覆盖某些东西......

除了@Dirk 已经说明的事情之外,在一个足够简单的问题上运行您的算法,您可以在一张纸上准确地完成算法的每一步。然后比较你的算法实际上做了什么。

例如,在您尝试最小化具有线性约束的低次多项式的问题上运行它。

您可以使用测试驱动开发(TDD),背后的想法是:

  • 在编写代码之前,您使用预期结果编写测试;
  • 每行代码(几乎所有行)都在测试中,因此当您修改一行时,您可以检查是否存在正确的行为或副作用。

使用这种方法,您可以找到并防止 Dirk 描述的一些错误。

要从数学角度编写有意义的测试,请遵循 Wolfgang Bangerth 的建议。您保留一个可以手动完成的简单案例,以及您现在的确切解决方案(在您的案例中为最佳解决方案)。通过这种方式,您可以测试论文中的不等式,并检查各个步骤。x

为了让您的生活更轻松,请尝试使用单元测试框架(许多语言都有它)。

使用 TDD 的优势在后续对初稿的修改中显现出来,您将在以后对代码的操作中节省时间。