我正在尝试使用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的圣杯。
因此,总而言之,我的两个问题是: