【问题标题】:Docplex adding constraint is too slowDocplex 添加约束太慢
【发布时间】:2023-04-05 23:50:01
【问题描述】:

这是一个相同的问题,但不同的是我使用的是 docplex。

cplex.linear_constraints.add too slow for large models

如何使用带有 docplex 的索引添加约束?

我的代码如下所示。

x = lm.binary_var_dict(range(n),name="x");
xv = [ax for i,ax in x.items()];

for i in range(l):
  Bx = {xv[j]:B[i,j] for j in range(n)};
  Bx = lm.linear_expr(Bx);
  lm.add_constraint(Bx == 1);

【问题讨论】:

  • 请显示您用于 docplex 的代码,否则很难说出如何改进它。您是逐个添加约束还是批量添加约束?您确定添加约束时会浪费时间,还是可能是创建约束时出现问题?
  • 很抱歉。请找到上面的代码。

标签: python cplex docplex


【解决方案1】:

可以尝试批量添加约束吗?

使用 Model.add_constraints() 为模型批量添加约束通常更有效。尝试在列表或理解中对约束进行分组(两者都有效)。

例子:

m.add_constraints((m.dotf(ys, lambda j_: i + (i+j_) % 3) >= i for i in rsize),
         ("ct_%d" % i for i in rsize))

来自Writing efficient DOcplex code

【讨论】:

    【解决方案2】:

    您可以通过多种替代方法来创建约束。例如,您可以使用函数sumscal_prod。您可以批量创建或不批量创建。 这是一个说明不同变体的小测试代码:

    from docplex.mp.model import Model
    import time
    
    n = 1000
    l = n
    B = { (i, j) : i * n + j for i in range(l) for j in range(n) }
    with Model() as m:
        x = m.binary_var_dict(range(n),name="x");
        xv = [ax for i,ax in x.items()];
    
        start = time.time()
        for i in range(l):
            Bx = {xv[j]:B[i,j] for j in range(n)};
            Bx = m.linear_expr(Bx);
            m.add_constraint(Bx == 1);
        elapsed1 = time.time() - start
    print('Original: %.2f' % elapsed1)
    
    with Model() as m:
        x = m.binary_var_dict(range(n),name="x");
        xv = [ax for i,ax in x.items()];
    
        start = time.time()
        m.add_constraints(m.linear_expr({xv[j]:B[i,j] for j in range(n)}) == 1 for i in range(l))
        elapsed2 = time.time() - start
    print('Original batched: %.2f' % elapsed2)
    
    with Model() as m:
        x = m.binary_var_dict(range(n),name="x");
        xv = [ax for i,ax in x.items()];
    
        start = time.time()
        for i in range(l):
            m.add_constraint(m.sum(B[i,j] * xv[j] for j in range(n)) == 1)
        elapsed3 = time.time() - start
    print('Sum: %.2f' % elapsed3)
    
    with Model() as m:
        x = m.binary_var_dict(range(n),name="x");
        xv = [ax for i,ax in x.items()];
    
        start = time.time()
        Bx = m.linear_expr(Bx);
        m.add_constraints(m.sum(B[i,j] * xv[j] for j in range(n)) == 1 for i in range(l))
        elapsed4 = time.time() - start
    print('Sum batched: %.2f' % elapsed4)
    
    with Model() as m:
        x = m.binary_var_dict(range(n),name="x");
        xv = [ax for i,ax in x.items()];
    
        start = time.time()
        for i in range(l):
            m.add_constraint(m.scal_prod([xv[j] for j in range(n)],
                                         [B[i,j] for j in range(n)]) == 1)
        elapsed5 = time.time() - start
    print('scal_prod: %.2f' % elapsed5)
    
    with Model() as m:
        x = m.binary_var_dict(range(n),name="x");
        xv = [ax for i,ax in x.items()];
    
        start = time.time()
        Bx = m.linear_expr(Bx);
        m.add_constraints(m.scal_prod([xv[j] for j in range(n)],
                                      [B[i,j]for j in range(n)]) == 1 for i in range(l))
        elapsed6 = time.time() - start
    print('scal_prod batched: %.2f' % elapsed6)
    

    在我的盒子上,这给了

    Original: 1.86
    Original batched: 1.82
    Sum: 2.84
    Sum batched: 2.81
    scal_prod: 1.55
    scal_prod batched: 1.50
    

    所以批处理不会买太多但是scal_prodlinear_expr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 2011-04-21
      相关资源
      最近更新 更多