Пакет cvxpy новые синтаксические ошибки суммирования записей - PullRequest
0 голосов
/ 17 сентября 2018

Я новичок в пакете cvxpy.Я пытаюсь использовать его для работы с примером из следующего блога:

https://towardsdatascience.com/integer-programming-in-python-1cbdfa240df2

Где мы пытаемся оптимизировать комбинацию маркетинговых каналов, отправляемых клиенту.

В пакете cvxpy произошли некоторые последние изменения, и я получаю сообщение об ошибке ниже, когда пытаюсь запустить шаг sum_entries (который в последней версии был изменен на cvxpy.sum)

Я думаю, что проблема связана с несовместимостью параметров selection и TRANSFORMER, но я не достаточно знаком с пакетом cvxpy, чтобы знать.Любые советы приветствуются.

Code:

test_probs.shape

(200, 8)



Code:

# selection = cvxpy.Bool(*test_probs.shape) # syntax changed in latest version

selection = cvxpy.Variable(*test_probs.shape, boolean=True)



# constraints

# Constant matrix that counts how many of each 
# material we sent to each customer

TRANSFORMER = np.array([[1,0,0],
                        [0,1,0],
                        [0,0,1],
                        [1,1,0],
                        [1,0,1],
                        [0,1,1],
                        [1,1,1],
                        [0,0,0]])


# can't send customer more promotion than there is supply

# note: sum_entries changed to sum in latest cvxpy version

supply_constraint = cvxpy.sum(selection * TRANSFORMER, axis=0) <= supply


Error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-47-f2ebf41a00af> in <module>()
     18 # note: sum_entries changed to sum in latest cvxpy version
     19 
---> 20 supply_constraint = cvxpy.sum(selection * TRANSFORMER, axis=0) <= supply
     21 
     22 

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/expressions/expression.py in cast_op(self, other)
     47         """
     48         other = self.cast_to_const(other)
---> 49         return binary_op(self, other)
     50     return cast_op
     51 

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/expressions/expression.py in __mul__(self, other)
    385             return cvxtypes.multiply_expr()(self, other)
    386         elif self.is_constant() or other.is_constant():
--> 387             return cvxtypes.mul_expr()(self, other)
    388         else:
    389             warnings.warn("Forming a nonconvex expression.")

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/atoms/affine/binary_operators.py in __init__(self, lh_exp, rh_exp)
     41 
     42     def __init__(self, lh_exp, rh_exp):
---> 43         super(BinaryOperator, self).__init__(lh_exp, rh_exp)
     44 
     45     def name(self):

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/atoms/atom.py in __init__(self, *args)
     42         self.args = [Atom.cast_to_const(arg) for arg in args]
     43         self.validate_arguments()
---> 44         self._shape = self.shape_from_args()
     45         if len(self._shape) > 2:
     46             raise ValueError("Atoms must be at most 2D.")

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/atoms/affine/binary_operators.py in shape_from_args(self)
    107         """Returns the (row, col) shape of the expression.
    108         """
--> 109         return u.shape.mul_shapes(self.args[0].shape, self.args[1].shape)
    110 
    111     def is_atom_convex(self):

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/utilities/shape.py in mul_shapes(lh_shape, rh_shape)
    140     lh_old = lh_shape
    141     rh_old = rh_shape
--> 142     lh_shape, rh_shape, shape = mul_shapes_promote(lh_shape, rh_shape)
    143     if lh_shape != lh_old:
    144         shape = shape[1:]

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/utilities/shape.py in mul_shapes_promote(lh_shape, rh_shape)
    107     if lh_mat_shape[1] != rh_mat_shape[0]:
    108         raise ValueError("Incompatible dimensions %s %s" % (
--> 109             lh_shape, rh_shape))
    110     if lh_shape[:-2] != rh_shape[:-2]:
    111         raise ValueError("Incompatible dimensions %s %s" % (

ValueError: Incompatible dimensions (1, 200) (8, 3)

Обновление:

Я попытался изменить форму выделения, как это предлагается в комментарии ниже.

код:

selection = cvxpy.Variable(test_probs.shape, boolean=True)

и теперь я получаю новую ошибку при выполнении части кода supply_constraint, представленной ниже.

код:

# constraints

# Constant matrix that counts how many of each 
# material we sent to each customer

TRANSFORMER = np.array([[1,0,0],
                        [0,1,0],
                        [0,0,1],
                        [1,1,0],
                        [1,0,1],
                        [0,1,1],
                        [1,1,1],
                        [0,0,0]])


# can't send customer more promotion than there is supply

# note: sum_entries changed to sum in latest cvxpy version

supply_constraint = cvxpy.sum(selection * TRANSFORMER, axis=0) <= supply

Ошибка:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-10-6eb7a55ea896> in <module>()
     18 # note: sum_entries changed to sum in latest cvxpy version
     19 
---> 20 supply_constraint = cvxpy.sum(selection * TRANSFORMER, axis=0) <= supply
     21 
     22 

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/expressions/expression.py in cast_op(self, other)
     47         """
     48         other = self.cast_to_const(other)
---> 49         return binary_op(self, other)
     50     return cast_op
     51 

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/expressions/expression.py in __le__(self, other)
    482         """NonPos : Creates an inequality constraint.
    483         """
--> 484         return NonPos(self - other)
    485 
    486     def __lt__(self, other):

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/expressions/expression.py in cast_op(self, other)
     47         """
     48         other = self.cast_to_const(other)
---> 49         return binary_op(self, other)
     50     return cast_op
     51 

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/expressions/expression.py in __sub__(self, other)
    370         """Expression : The difference of two expressions.
    371         """
--> 372         return self + -other
    373 
    374     @_cast_other

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/expressions/expression.py in cast_op(self, other)
     47         """
     48         other = self.cast_to_const(other)
---> 49         return binary_op(self, other)
     50     return cast_op
     51 

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/expressions/expression.py in __add__(self, other)
    358         """Expression : Sum two expressions.
    359         """
--> 360         return cvxtypes.add_expr()([self, other])
    361 
    362     @_cast_other

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/atoms/affine/add_expr.py in __init__(self, arg_groups)
     34         # For efficiency group args as sums.
     35         self._arg_groups = arg_groups
---> 36         super(AddExpression, self).__init__(*arg_groups)
     37         self.args = []
     38         for group in arg_groups:

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/atoms/atom.py in __init__(self, *args)
     42         self.args = [Atom.cast_to_const(arg) for arg in args]
     43         self.validate_arguments()
---> 44         self._shape = self.shape_from_args()
     45         if len(self._shape) > 2:
     46             raise ValueError("Atoms must be at most 2D.")

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/atoms/affine/add_expr.py in shape_from_args(self)
     42         """Returns the (row, col) shape of the expression.
     43         """
---> 44         return u.shape.sum_shapes([arg.shape for arg in self.args])
     45 
     46     def expand_args(self, expr):

~/anaconda2/envs/py36/lib/python3.6/site-packages/cvxpy/utilities/shape.py in sum_shapes(shapes)
     50             raise ValueError(
     51                 "Cannot broadcast dimensions " +
---> 52                 len(shapes)*" %s" % tuple(shapes))
     53 
     54         longer = shape if len(shape) >= len(t) else t

ValueError: Cannot broadcast dimensions  (3,) (1, 3)

1 Ответ

0 голосов
/ 18 сентября 2018

Ваша проблема возникает при создании переменной selection. Вы распаковываете кортеж формы в несколько аргументов. Первый аргумент Variable должен быть формой. Итак, правильная конструкция:

selection = cvxpy.Variable(test_probs.shape, boolean=True)

Вы можете убедиться, что это правильно, проверив атрибут формы:

selection.shape

Что теперь должно дать:

(200, 8)
...