如何评估信任构造拉格朗日?
我正在使用 scipy.optimize.minimize 中的 trust-constr 算法和间隔约束(下界 < g(x) < 上界)。 我想在找到的解决方案周围的区域中绘制拉格朗日函数,以分析收敛行为。
据我所知,拉格朗日定义为:
与:
在返回的 OptimizeResult
对象中,我可以找到屏障参数,但缺少松弛变量。存在拉格朗日乘子,但每个区间约束只有一个,而我期望有两个,因为每个区间约束都转换为两个规范不等式约束:
显然,我错过了一些东西,所以任何帮助将不胜感激。
最小可重现示例:
import scipy.optimize as so
import numpy as np
# Problem definition:
# Five 2D points are given, with equally spaced x coordinates.
# The y coordinate of the first point is zero, while the last point has value 10.
# The goal is to find the smallest y coordinate of the other points, given the
# difference between the y coordinates of two consecutive points has to lie within the
# interval [-3, 3].
xs = np.linspace(0, 4, 5)
y0s = np.zeros(xs.shape)
y0s[-1] = 10
objective_fun = lambda y: np.mean(y**2)
def constraint_fun(ys):
'''
Calculates the signed squared consecutive differences of the input vector, augmented
with the first and last element of y0s.
'''
full_ys = y0s.copy()
full_ys[1:-1] = ys
consecutive_differences = full_ys[1:] - full_ys[:-1]
return np.sign(consecutive_differences) * consecutive_differences**2
constraint = so.NonlinearConstraint(fun=constraint_fun, lb=-3**2, ub=3**2)
result = so.minimize(method='trust-constr', fun=objective_fun, constraints=[constraint], x0=y0s[1:-1])
# The number of interval constraints is equal to the size of the output vector of the constraint function.
print(f'Nr. of interval constraints: {len(constraint_fun(y0s[1:-1]))}')
# Expected nr of Lagrange multipliers: 2x number of interval constraints.
print(f'Nr. of Lagrange multipliers: {len(result.v[0])}')
输出:
Nr. of interval constraints: 4
Nr. of Lagrange multipliers: 4
预期输出:
Nr. of interval constraints: 4
Nr. of Lagrange multipliers: 8
I'm using the trust-constr
algorithm from scipy.optimize.minimize
with an interval constraint (lowerbound < g(x) < upperbound).
I would like to plot the Lagrangian in a region around the found solution to analyze the convergence behavior.
According to my knowledge, the Lagrangian is defined as:
with:
In the returned OptimizeResult
object, I can find the barrier parameter, but the slack variables are missing. The Lagrange multipliers are present, but there is only one per interval constraint, while I would expect two since each interval constraint is converted to two canonical inequality constraints:
Clearly, I'm missing something, so any help would be appreciated.
Minimal reproducible example:
import scipy.optimize as so
import numpy as np
# Problem definition:
# Five 2D points are given, with equally spaced x coordinates.
# The y coordinate of the first point is zero, while the last point has value 10.
# The goal is to find the smallest y coordinate of the other points, given the
# difference between the y coordinates of two consecutive points has to lie within the
# interval [-3, 3].
xs = np.linspace(0, 4, 5)
y0s = np.zeros(xs.shape)
y0s[-1] = 10
objective_fun = lambda y: np.mean(y**2)
def constraint_fun(ys):
'''
Calculates the signed squared consecutive differences of the input vector, augmented
with the first and last element of y0s.
'''
full_ys = y0s.copy()
full_ys[1:-1] = ys
consecutive_differences = full_ys[1:] - full_ys[:-1]
return np.sign(consecutive_differences) * consecutive_differences**2
constraint = so.NonlinearConstraint(fun=constraint_fun, lb=-3**2, ub=3**2)
result = so.minimize(method='trust-constr', fun=objective_fun, constraints=[constraint], x0=y0s[1:-1])
# The number of interval constraints is equal to the size of the output vector of the constraint function.
print(f'Nr. of interval constraints: {len(constraint_fun(y0s[1:-1]))}')
# Expected nr of Lagrange multipliers: 2x number of interval constraints.
print(f'Nr. of Lagrange multipliers: {len(result.v[0])}')
Output:
Nr. of interval constraints: 4
Nr. of Lagrange multipliers: 4
Expected output:
Nr. of interval constraints: 4
Nr. of Lagrange multipliers: 8
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你是对的,确实应该有 8 个拉格朗日乘数。作为解决方法,您可以使用旧的字典约束而不是
NonlinearConstraint
对象。这里,“fun”预计是一个满足 fun(x) >= 0 的函数。这给了我 8 个预期的拉格朗日乘数。尽管如此,它也应该与 NonlinearConstraint 一起使用,因此可能值得在 Github 上的 scipy 存储库中提出一个问题。
关于你的第二个问题:
res.constr
包含解决方案中的约束值列表,即g(x) - lb
和ub - g的值(x)
。由于我们有g(x) - lb - s = 0
和ub-g(x)-s=0
,因此立即得出res.constr
code> 只是您正在寻找的松弛变量的值(当我们使用字典约束时)。You're right, there should indeed be 8 lagrangian multipliers. As a workaround, you can use the old dictionary constraints instead of the
NonlinearConstraint
objects.Here, 'fun' is expected to be a function such that fun(x) >= 0. This gives me 8 lagrangian multipliers as expected. Nonetheless, it should also work with
NonlinearConstraint
s, so it might be worth opening an issue at the scipy repo on Github.Regarding your second question:
res.constr
contains a list of the constraint values at the solution, i.e. the values ofg(x) - lb
andub - g(x)
. Since we haveg(x) - lb - s = 0
andub-g(x)-s=0
it follows immediately thatres.constr
are just the values of the slack variables you are looking for (when we use dictionary constraints).