【问题标题】:Problem solving a minimization problem in cvxpy解决 cvxpy 中的最小化问题的问题
【发布时间】:2026-02-09 13:35:01
【问题描述】:

我有一个线性优化问题,可以用这样的成本函数代码表示:

value_to_minimize = 0.0;
for i in range(0, len(v_1)):
    value_to_minimize += np.abs(v_1[i] - (v_2[i] * c1 + v_3[i] * c2 + v_4[i] * c3));

求解器的任务应该是找到变量c1c2c3 的值,使值最小化。作为边界条件,c1c2c3 一起应该导致 1.0 而不是负数。 v_1v_2v_3v_4 是具有 10000 个浮点值的向量。

这里是在cvxpy中解决这个最小化问题的大纲,但是在cp.Minimize(...)中没有传递参数:

V1 = np.array(v_1).reshape(10000, 1)
V2 = np.array(v_2 + v_3 + v_4).reshape(10000, 3)
c = cp.Variable((3,1),nonneg=True)

prob = cp.Problem(cp.Minimize(..., # ???
                [sum(c) == 1])) 
prob.solve(verbose=True)

在这种情况下,cvxpy 的最小化函数看起来如何?

【问题讨论】:

  • (1) 哪些值是错误的,以什么方式出错? (2) 确保事物可以被复制。
  • @ErwinKalvelagen 感谢您的回复。 c 变量中的三个值不包含最佳值,因为我可以通过反复试验找到更好的值。在这种情况下,重现性并不是那么容易实现的,估计cp.pnorm(u - cp.sum(V@c), 1)) 是否真的做了我想要的对我有帮助。
  • 如果没有一小段代码可以重现问题 (*.com/help/minimal-reproducible-example),我不知道该如何提供帮助。
  • @ErwinKalvelagen 非常感谢。我现在已经编辑了问题,使其更加开放。
  • 顺便说一句。为什么要使用这个特定的库?这似乎是一个相对简单的线性优化问题。

标签: python solver cvxpy


【解决方案1】:

如果您不介意使用其他库,我会推荐 scipy 使用这个库:

from scipy.optimize import minimize
import numpy as np

def OF(x0, v_1, v_2, v_3, v_4):
  value_to_minimize = 0.0
  for i in range(0, len(v_1)):
    value_to_minimize += np.abs(v_1[i] - (v_2[i] * x0[0] + v_3[i] * x0[1] + v_4[i] * x0[2]))
  return value_to_minimize


if __name__ == '__main__':

  x0 = np.array([0, 0, 0])
  v_1 = np.random.randint(10, size = 10000)
  v_2 = np.random.randint(10, size = 10000)
  v_3 = np.random.randint(10, size = 10000)
  v_4 = np.random.randint(10, size = 10000)


  minx0 = np.repeat(0, [len(x0)] , axis = 0)
  maxx0 = np.repeat(np.inf, [len(x0)] , axis = 0)
  bounds = tuple(zip(minx0, maxx0))

  cons = {'type':'eq', 
  'fun':lambda x0: 1 - sum(x0)}
  res_cons = minimize(OF, x0, (v_1, v_2, v_3, v_4), bounds = bounds, constraints=cons, method='SLSQP')



  print(res_cons)
  print('Current value of objective function: ' + str(res_cons['fun']))
  print('Current value of controls:')
  print(res_cons['x'])

输出是:

     fun: 27919.666908810435
     jac: array([5092.        , 5672.        , 5108.39868164])
 message: 'Optimization terminated successfully.'
    nfev: 126
     nit: 21
    njev: 21
  status: 0
 success: True
       x: array([0.33333287, 0.33333368, 0.33333345])
Current value of objective function: 27919.666908810435
Current value of controls:
[0.33333287 0.33333368 0.33333345]

但显然这里的实际值意义不大,因为我只是对v_ 值使用了随机整数...只是一个演示,该模型将满足您对c 值加1 和非边界的约束小于零(负)。

编辑更新: 没有仔细研究 OF/约束以意识到这是一个线性问题...应该使用线性求解器算法(不过,您可以使用非线性,它是不过过分了)。

scipy 的线性求解器不适用于像这样的复杂优化问题,回到cvxpy

import numpy as np
import cvxpy as cp

# Create two scalar optimization variables.
x = cp.Variable()
y = cp.Variable()
z = cp.Variable()

v_1 = np.random.randint(10, size = 10000)
v_2 = np.random.randint(10, size = 10000)
v_3 = np.random.randint(10, size = 10000)
v_4 = np.random.randint(10, size = 10000)

constraints = [x + y + z == 1, x >= 0, y >= 0, z >= 0]

objective = cp.Minimize(cp.sum(cp.abs(v_1 - (v_2 * x + v_3 * y + v_4 * z))))

prob = cp.Problem(objective, constraints)
print("Value of OF:", prob.solve())
print('Current value of controls:')
print(x.value, y.value, z.value)

输出:

Value of OF: 27621.999978414093
Current value of controls:
0.3333333333016109 0.33333333406414983 0.3333333326298208

【讨论】:

  • 非常感谢您提供的解决方案,它运行良好。但是,我已经看到 SLSQP 是一个非线性求解器,而我的问题具有线性状态空间。我会因此在科学论文中受到批评吗?
  • @MerklT 啊我没有读过你的函数,是的,你应该使用线性求解器来解决线性问题。你不会因为 SLSQP 受到批评。但你可能会得到一些外观,因为它有点矫枉过正。我发布了更新!
【解决方案2】:

我强烈建议删除其中一个参数和一个约束。如果您知道c1 + c2 + c3 = 1.,请使用c3 = 1. - c1 - c2!这使得最小化器的任务变得更加容易。此外,如果v_1 等是 numpy 数组,则将它们用作数组,例如,

c3 = 1. - c1 - c2
value_to_minimize = np.sum(np.abs(v_1 - (v_2 * c1 + v_3 * c2 + v_4 * c3)))

【讨论】:

  • c3 的简化似乎合乎逻辑,谢谢。你将如何解决最小化问题?与另一个图书馆?