Python cvxpy - 重用一些约束
Python cvxpy - reuse some constraints
我目前正在使用 cvxpy 优化一个非常大的问题,但现在面临当前问题。
我 运行 求解器的多次迭代(每次迭代都会降低某些变量的灵活性)。
每个 运行 总共有 50 个约束,其中只有 2 个在每个 运行 上不同。其余 48 个约束是相同的。
在每次迭代中,我都从头开始重建这 2 个约束、问题和 obj 函数。
如果我不重建剩余的(相同的)48 个约束,最终的解决方案就没有意义。
我读过这个 post 但在我这里,我不需要更改参数和重新优化。
我刚刚设法准备了一个示例来说明这个问题:
x = cvx.Variable(3)
y = cvx.Variable(3)
tc = np.array([1.0, 1.0,1.0])
constraints2 = [x >= 2]
constraints3 = [x <= 4]
constraints4 = [y >= 0]
for i in range(2):
if i == 0:
constraints1 = [x - y >= 0]
else:
x = cvx.Variable(3)
y = cvx.Variable(3)
constraints1 = [x + y == 1,
x - y >= 1,
x - y >= 0,
x >= 0]
constraints = constraints1 + constraints2 + constraints3 + constraints4
# Form objective.
obj = cvx.Minimize( (tc.T @ x ) - (tc.T @ y ) )
# Form and solve problem.
prob = cvx.Problem(obj, constraints)
prob.solve()
solution_value = prob.value
solution = str(prob.status).lower()
print("\n\n** SOLUTION: {} Value: {} ".format(solution, solution_value))
print("* optimal (x + y == 1) dual variable", constraints[0].dual_value)
print("optimal (x - y >= 1) dual variable", constraints[1].dual_value)
print("x - y value:", (x - y).value)
print("x = {}".format(x.value))
print("y = {}".format(y.value))
如您所见,constraints2 要求 x 向量中的所有值都大于 2。constraints2 在两次迭代中都添加到求解器中使用的“约束”。
第二种解决方案应该为您提供小于 2 的向量 x 的值。
为什么?如何避免这个问题?
谢谢
您需要使用中描述的参数。假设您有约束 rhs >= lhs
,有时使用,有时不使用,其中 rhs
和 lhs
的维度为 m x n
。编写以下代码:
param = cp.Parameter((m, n))
slack = cp.Variable((m, n))
param_constraint = [rhs >= lhs + cp.multiply(param, slack)]
现在要关闭约束,设置 param.values = np.ones((m, n))
。要打开约束,请设置 param.values = np.zeros((m, n))
。您可以通过将 param
的某些条目设置为 1 并将其他条目设置为 0 来改变约束 off/on 的某些条目。
我目前正在使用 cvxpy 优化一个非常大的问题,但现在面临当前问题。 我 运行 求解器的多次迭代(每次迭代都会降低某些变量的灵活性)。 每个 运行 总共有 50 个约束,其中只有 2 个在每个 运行 上不同。其余 48 个约束是相同的。 在每次迭代中,我都从头开始重建这 2 个约束、问题和 obj 函数。 如果我不重建剩余的(相同的)48 个约束,最终的解决方案就没有意义。
我读过这个 post
我刚刚设法准备了一个示例来说明这个问题:
x = cvx.Variable(3)
y = cvx.Variable(3)
tc = np.array([1.0, 1.0,1.0])
constraints2 = [x >= 2]
constraints3 = [x <= 4]
constraints4 = [y >= 0]
for i in range(2):
if i == 0:
constraints1 = [x - y >= 0]
else:
x = cvx.Variable(3)
y = cvx.Variable(3)
constraints1 = [x + y == 1,
x - y >= 1,
x - y >= 0,
x >= 0]
constraints = constraints1 + constraints2 + constraints3 + constraints4
# Form objective.
obj = cvx.Minimize( (tc.T @ x ) - (tc.T @ y ) )
# Form and solve problem.
prob = cvx.Problem(obj, constraints)
prob.solve()
solution_value = prob.value
solution = str(prob.status).lower()
print("\n\n** SOLUTION: {} Value: {} ".format(solution, solution_value))
print("* optimal (x + y == 1) dual variable", constraints[0].dual_value)
print("optimal (x - y >= 1) dual variable", constraints[1].dual_value)
print("x - y value:", (x - y).value)
print("x = {}".format(x.value))
print("y = {}".format(y.value))
如您所见,constraints2 要求 x 向量中的所有值都大于 2。constraints2 在两次迭代中都添加到求解器中使用的“约束”。 第二种解决方案应该为您提供小于 2 的向量 x 的值。 为什么?如何避免这个问题? 谢谢
您需要使用rhs >= lhs
,有时使用,有时不使用,其中 rhs
和 lhs
的维度为 m x n
。编写以下代码:
param = cp.Parameter((m, n))
slack = cp.Variable((m, n))
param_constraint = [rhs >= lhs + cp.multiply(param, slack)]
现在要关闭约束,设置 param.values = np.ones((m, n))
。要打开约束,请设置 param.values = np.zeros((m, n))
。您可以通过将 param
的某些条目设置为 1 并将其他条目设置为 0 来改变约束 off/on 的某些条目。