Python CPLEX API: условная итерация для двоичных переменных - PullRequest
0 голосов
/ 22 апреля 2020

Я работаю над теоретико-графической задачей. Предположим, мы хотим найти граф G = (V, E), такой, что существует разбиение X из V, содержащее не более k классов эквивалентности. Переменная p_S принимает значение 1 точно, когда S является членом раздела X, и ноль в противном случае. Таким образом, у нас есть ограничение на то, что сумма по всем переменным p_S не больше k для всех подмножеств S из V.

Итак, я хочу перебрать все p_S, имеющие значение 1, и определить больше ограничений основанный на элементах, которые я извлекаю из S. Эти ограничения сохранят то, что члены класса эквивалентности имеют некоторые общие свойства.

Можно ли получить доступ к переменным p_S таким образом и как я могу это сделать?

В качестве альтернативы я знаю, что могу обойтись без итераций по моим двоичным переменным, если мне разрешено использовать двоичные переменные в качестве коэффициентов в моих ограничениях. Это возможно?

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

CPLEX Python API основано на индексе. Чтобы перебрать все двоичные переменные со значением решения, равным 1, нам нужно запросить типы переменных и значения решения и отфильтровать их соответствующим образом. Вот простой пример:

import sys
import cplex


def main(modelfile):
    # Read in a model file.
    c = cplex.Cplex()
    c.read(modelfile)

    # Solve the model and print the solution and status.
    c.solve()
    print("Solution value:", c.solution.get_objective_value())
    print("Solution status: {0} ({1})".format(
        c.solution.get_status_string(),
        c.solution.get_status()))

    # Display all binary variables that have a solution value of 1.
    types = c.variables.get_types()
    nvars = c.variables.get_num()
    binvars = [idx for idx, typ
               in zip(range(nvars), c.variables.get_types())
               if typ == c.variables.type.binary]
    inttol = c.parameters.mip.tolerances.integrality.get()
    binvars_at_one = [idx for idx, val
                      in zip(binvars, c.solution.get_values(binvars))
                      if abs(val - 1.0) <= inttol]
    print("Binary variables with a solution value equal to one:")
    for varname in c.variables.get_names(binvars_at_one):
        print("  ", varname)


if __name__ == "__main__":
    if len(sys.argv) != 2:
        raise ValueError("usage: {0} <model>".format(sys.argv[0]))
    main(sys.argv[1])

Для получения дополнительной информации см. Документацию для Cplex.variables и Cplex.solution .

0 голосов
/ 22 апреля 2020

Пример линеаризации:

from docplex.mp.model import Model

mdl = Model(name='binaryproduct')

x = mdl.binary_var(name='x')
y = mdl.binary_var(name='y')

z = mdl.binary_var(name='z')
# z==x*y
mdl.add_constraint(x+y<=1+z, 'ct1')
mdl.add_constraint(z<=x, 'ct2')
mdl.add_constraint(z<=y, 'ct3')
#end of z==x*y

mdl.solve()



for v in mdl.iter_binary_vars():
    print(v," = ",v.solution_value)
...