CVXPY:约束导致问题不遵循DCP规则

时间:2019-11-20 11:30:38

标签: python optimization cvxpy

我正在尝试使用CVXPY和MIP使一组汽车的总价值最大化。 每辆车都有自己的价值(以及其他特征,例如颜色,版本等),并为用户提供了一些选择,我想为您推荐能使总价值最大化的最佳汽车。

汽车及其特性的示例:

  Model_Code Color   Version   Score
0         A   White    X       359.4879
1         B   Black    X       425.1045
2         E   Black    Y       742.0248
3         C   Yellow   Z       1353.8500
4         D   White    Y       807.1862

除了仅积极解决方案和总体车辆的典型限制外,这是我正在使用的代码:

scores = dataset['Score'].values.tolist()

selection = cp.Variable(dataset.shape[0], integer=True)

order_size_restriction = cp.sum(selection) <= sel_order_size
total_value = selection * scores

problem = cp.Problem(cp.Maximize(total_value), [selection >= 0, selection <= 100, order_size_restriction])

result = problem.solve(solver=cp.GLPK_MI, verbose=False)

这完美无瑕,但是,正如预期的那样,求解器仅建议一个模型(C,得分最高)。因此,我尝试在解决方案中实现一些可变性,例如,强制解决方案使用至少具有2种不同颜色的汽车。

这是我的问题开始的地方。 为了应用这种约束,我首先为每辆汽车的颜色创建了虚拟变量,如下所示:

ext_color_dummies = np.array(pd.get_dummies(dataset['Color']))

提供了以下内容:

   [1 0 0,  
    0 1 0,  
    0 1 0,  
    0 0 1,
    1 0 0]

现在,如果我将上述矩阵乘以解决方案,那么对于10辆汽车的订单来说,它将是:

[0 0 0 10 0]

结果将是:

[0 0 10]

告诉我,从三种可用的颜色(白色,黑色,黄色)中,我只选择一种(10辆黄色的车辆)。

现在,直奔主题,我将如何强制解决方案选择多种颜色? 这是我尝试过的:

ext_color_dummies = np.array(pd.get_dummies(dataset['Colour']))
ext_color_multiplication = selection * ext_color_dummies   
ext_color_restriction = cp.length(ext_color_multiplication)

然后将ext_color_restriction添加到上述问题变量中的约束中,如下所示:

problem = cp.Problem(cp.Maximize(total_value), 
                     [selection >= 0, 
                      selection <= 100, 
                      order_size_restriction, 
                      ext_color_restriction_2 >= sel_ext_color_count])

其中sel_ext_color_count是要包含在解决方案中的不同颜色的数量。 但是,正如标题所示,这是我开始遇到可怕的错误的时候:

  

DCPError:问题不遵循DCP规则。具体来说:   以下约束条件不是DCP:3.0 <= length(var337 * [[0. 0. 0。   1.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [1。 0. 0. 0.] [0。 0. 1. 0.]]),因为以下子表达式不是:|-length(var337 * [[0. 0. 0. 1.] [0. 0. 0. 1.] [0. 0。 1. 0.] [0. 1. 0。   0.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [1。 0. 0. 0.] [0。 0. 1. 0。]])

注意:错误是由于实际代码引起的,而不是此处提供的示例,因此,为什么虚拟变量矩阵的维数不同。

因此,我做了任何体面的程序员所做的事情,并且阅读了文档继续破解,并尝试了另一种方法,像这样更改了限制:

ext_color_restriction = cp.sum(ext_color_multiplication / ext_color_multiplication, axis=0, keepdims=True)

但是,问题不会消失:

  

DCPError:问题不遵循DCP规则。具体来说:   以下约束不是DCP:3.0 <= Sum(var383 * [[0. 0. 0. 1.]   [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 1. 0.]   [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.]   [0。 0. 1. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [1。 0. 0. 0.] [0。 0. 1. 0.]]   / var383 * [[0。 0. 0. 1.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.]   [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 1. 0. 0.]   [0。 0. 0. 1.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.]   [1。 0. 0. 0.] [0。 0. 1. 0.]],0,True),因为以下   子表达式不是:|-var383 * [[0。 0. 0. 1.] [0。 0. 0. 1.] [0。   0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [1。 0. 0. 0.] [0。 0. 1. 0.]]] / var383 * [[0。 0. 0. 1.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 1. 0. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [0。 0. 1. 0.] [0。 0. 0. 1.] [0。 0. 0. 1.] [1。 0. 0. 0.] [0。 0. 1. 0。]]

最后,我屈服了,浏览了few topics,最终找到了expression rules for CVX。 我不理解为什么第一种方法给出DCPError(我相信我理解第二种方法给出DCPError的原因),因此各自碰壁。

所以我做了所有程序员都会做的事情,然后转向了 Stackoverflow的圣杯。

因此,总而言之,我的两个问题是:

  • 如何确保解决方案的可变性?
  • 为什么我的第一种方法会引发DCPError并有办法 解决吗?

0 个答案:

没有答案