Python cvxpy - повторное использование некоторых ограничений

В настоящее время я использую cvxpy для оптимизации действительно большой проблемы, но теперь столкнулся с текущей проблемой. Я запускаю несколько итераций решателя (каждая итерация снижает гибкость некоторых переменных). В каждом прогоне всего 50 ограничений, из которых только 2 различаются в каждом прогоне. Остальные 48 ограничений идентичны. На каждой итерации я перестраиваю с нуля эти 2 ограничения, проблему и функцию obj. Если я не перестрою оставшиеся (те же) 48 ограничений, окончательное решение не будет иметь смысла.

Я прочитал этот пост CVXPY: как эффективно решить серию аналогичных проблем, но здесь, в моем случае, мне не нужно менять параметры и повторно оптимизировать.

Мне только что удалось подготовить пример, показывающий эту проблему:

    x = cvx.Variable(3)
    y = cvx.Variable(3)

    tc = np.array([1.0, 1.0,1.0])
    constraints2 = [x >= 2]
    constraints3 = [x <= 4]
    constraints4 = [y >= 0]
    
    for i in range(2):
        if i == 0:
            constraints1 = [x - y >= 0]
            
        else:
            x = cvx.Variable(3)
            y = cvx.Variable(3)
            constraints1 = [x + y == 1,
                           x - y >= 1,
                           x - y >= 0,
                           x >= 0]
    
        
        
        constraints = constraints1 + constraints2 + constraints3 + constraints4
        # Form objective.
        obj = cvx.Minimize( (tc.T @ x ) - (tc.T @ y ) )
        
        # Form and solve problem.
        prob = cvx.Problem(obj, constraints)
        prob.solve()
        

        solution_value = prob.value
        solution = str(prob.status).lower() 
        print("\n\n** SOLUTION:  {}     Value: {} ".format(solution, solution_value))
        print("* optimal (x + y == 1) dual variable", constraints[0].dual_value)
        print("optimal (x - y >= 1) dual variable", constraints[1].dual_value)
        print("x - y value:", (x - y).value)
        print("x = {}".format(x.value))
        print("y = {}".format(y.value))

Как видите, constraints2 требует, чтобы все значения в векторе x были больше 2. constraints2 добавляется в обеих итерациях к ограничениям, используемым в решателе. Второе решение должно дать вам значения вектора x меньше 2. Почему? Как избежать этой проблемы? Спасибо


person Angelo    schedule 22.10.2020    source источник
comment
Почему вы переопределяете x и y в цикле for? Кроме того, не могли бы вы уточнить и помочь мне понять, что иллюстрирует этот фрагмент кода?   -  person steven    schedule 22.10.2020


Ответы (1)


Вам необходимо использовать параметры, как описано в связанном сообщении < / а>. Предположим, у вас есть ограничение rhs >= lhs, которое иногда используется, а иногда нет, где rhs и lhs имеют размеры m x n. Напишите следующий код:

param = cp.Parameter((m, n))
slack = cp.Variable((m, n))
param_constraint = [rhs >= lhs + cp.multiply(param, slack)]

Теперь, чтобы отключить ограничение, установите param.values = np.ones((m, n)). Чтобы включить ограничение, установите param.values = np.zeros((m, n)). Вы можете включить / выключить некоторые записи ограничения, установив для некоторых записей param значение 1, а для других - 0.

person steven    schedule 22.10.2020
comment
Спасибо, Стивен, меня немного беспокоит, что то, что вы имеете в виду, относится к значениям, которые меняются на каждой итерации. В моем случае выше вы можете видеть, что constraint2 всегда один и тот же, на самом деле ничего не меняется. Так что у меня нет никаких параметров, которые можно было бы повторить. Могли бы вы поделиться рабочей версией моего кода выше в качестве обучающего примера? Спасибо - person Angelo; 22.10.2020
comment
Основная проблема с фрагментом кода заключается в том, что вы переопределяете x и y, что нарушает код. - person steven; 22.10.2020
comment
В этом и заключалась проблема, отличный улов! Я потратил на это 3 дня, и это сработало. Спасибо, Стивен! - person Angelo; 23.10.2020