Раскраска графа с установленными ограничениями CVXPY - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь закодировать ограничения для задачи раскраски графа с помощью CVXPY.Я довольно новичок в смешанно-целочисленном программировании (MIP), и у меня возникли некоторые трудности при определении ограничений.У меня есть входные данные, такие как список «ребер» ниже.Где каждый кортеж в списке - это ребро, которое начинается на одном узле и заканчивается на другом.Например, первое ребро начинается в узле «0» и заканчивается в узле «1».

Я хотел бы указать следующие ограничения:

  • каждый узел может иметьтолько один цвет.

  • вершины, имеющие одно ребро, должны иметь разные цвета.

  • каждый узел должен иметь хотя бы один цвет.

Целевой функцией будет количество используемых цветов.

Для переменной выбора я хочу указать цвет, который принимает каждый узел.

Я используюcolors массив для умножения на переменную выбора и затем суммирования для каждого узла, чтобы выбрать цвет для узла и указать, что каждый узел может иметь только один цвет.

Я получаю ошибку ниже.Правильно ли я строю переменную выбора?

Кроме того, это похоже на большую работу, кто-нибудь видит более простой способ сделать это?Или кто-нибудь знает пример решения проблемы раскраски графа с помощью CVXPY?

Еще одна вещь, если я перенесу массив цветов, ошибка исчезнет.

Входные данные:

ребра

[(0, 1), (1, 2), (1, 3)]

код:

# selection variable
# 4 is the number of nodes
selection = cvxpy.Variable(4, boolean=True)

# array for colors
colors = np.array([[1,0,0,0],
                        [0,1,0,0],
                        [0,0,1,0],
                        [0,0,0,1],
                        [1,1,0,0],
                        [1,1,1,0],
                        [1,1,1,1],
                        [0,1,1,1],
                        [0,0,1,1],
                        [1,0,1,0],
                        [0,1,0,1],
                        [0,1,1,0],
                        [1,1,0,0],
                        [0,0,0,0]])


# each node can only have one color constraint

one_color = cvxpy.sum(selection * colors, axis=0) == 1

ошибка:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-18-b22226c89a2f> in <module>()
      1 # each node can only have one color constraint
      2 
----> 3 one_color = cvxpy.sum(selection * colors, axis=0) == 1

~/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, 4) (14, 4)
...