Как увеличить количество решений Cplex?

У меня есть эта cplex-модель с 1 переменной binay (x_i). Теперь у меня есть 2 вопроса по его комплексным решениям (я поместил их в один пост, потому что они связаны).

Первое. Для моей модели я получил 26 решений, но я знаю, что на самом деле решений гораздо больше. Как решения генерируются в cplex? Есть ли способ увеличить количество раствора?

Во-вторых: я хочу получить доступ ко всем решениям с помощью пула решений, но когда я пытаюсь распечатать все решения, он распечатывает все существующие переменные (очевидно, мне просто нужны переменные, которые равны 1 ) с их значением.

Это мой код для пула решений:

def generate_soln_pool(mdl):      
    cpx = mdl.get_cplex()
    cpx.solnpoolintensity=4
    cpx.solnpoolagap=0
    cpx.populatelim=100000
    try:
        cpx.populate_solution_pool()
    except CplexSolverError:
        print("Exception raised during populate")
        return []
    numsol = cpx.solution.pool.get_num()
    print(numsol)
    nb_vars = mdl.number_of_variables
    sol_pool = []
    for i in range(numsol):

        x_i = cpx.solution.pool.get_values(i)
        assert len(x_i) == nb_vars
        sol = mdl.new_solution()
        for k in range(nb_vars):
            vk = mdl.get_var_by_index(k)
            sol.add_var_value(vk, x_i[k])
        sol_pool.append(sol)
    return sol_pool

bm=CModel()
pool = generate_soln_pool(bm)
for s, sol in enumerate(pool,start=1):
        print(" this is solution #{0} of the pool".format(s))
        sol.display()

Это часть моего вывода:

x_0 = 0
x_1 = 0
x_2 = 0
x_3 = 0
x_4 = 0
x_5 = 0
x_6 = 0
x_7 = 0
x_8 = 0
x_9 = 0
x_10= 0
x_11 = 1
x_12 = 0
x_13 = 0
.
.
.


person Sana.Nz    schedule 19.03.2020    source источник


Ответы (1)


Думаю, вы взяли настройки параметров из пример в документации? Эти параметры заставят CPLEX перечислить все оптимальные решения. Если вам нужны все решения, вы должны установить очень большое значение разрыва пула решений.

В CPLEX есть много способов генерировать решения, но примерно он следует стандартной схеме ветвей и границ, дополненной эвристикой.

Конечно, у решения есть значение для каждой переменной. Если вам нужны только определенные переменные, вы можете использовать различные типы фильтрации и понимания, которые предоставляет Python. Например, чтобы получить индексы двоичных переменных, которые в решении равны 1, вы можете сделать что-то вроде этого:

indices = [j for j, a in enumerate(cpx.solution.pool.get_values(i)) if a > 0.5]

РЕДАКТИРОВАТЬ: Посмотрев и запустив код, мы выяснили, в чем проблема:

  1. Код устанавливает только параметр абсолютного зазора, он также должен устанавливать параметр относительного зазора.

  2. Код устанавливает такие параметры, как cpx.solnpoolintensity = 4. Это неправильный способ установки параметров. Оператор просто создаст новое свойство в объекте, которое игнорируется остальной частью кода.

Правильный способ настройки параметров для перечисления (до) 4000 решений:

cpx.parameters.mip.pool.intensity.set(4)
cpx.parameters.mip.pool.absgap.set(1e75)
cpx.parameters.mip.pool.relgap.set(1e75)
cpx.parameters.mip.limits.populate.set(4000)
person Daniel Junglas    schedule 19.03.2020
comment
Да, я использую это. Насколько большим должен быть разрыв? Я кладу 9000000000000000000000000000000000000000000000000, но получаю тот же результат. - person Sana.Nz; 20.03.2020
comment
Обычно подходит значение по умолчанию 1e75. Может решений больше нет? Если вы обновите свой вопрос либо своей полной моделью (например, экспортированной в LP или SAV), либо своим полным кодом и данными, мы сможем проверить, есть ли другие решения или что не так с вашим кодом. - person Daniel Junglas; 20.03.2020
comment
Ну, у меня около 400 штук. Когда я запускаю, программа находит 26 решений для всех. Но когда я запускаю программу для 50 из этих элементов, она показывает 40 решений! - person Sana.Nz; 23.03.2020
comment
Я не понимаю, почему большее количество элементов дает больше решений в целом. Опять же, если вы хотите, чтобы мы рассмотрели это глубже / глубже, вам нужно будет предоставить минимальный рабочий пример кода, который иллюстрирует проблему. Также было бы хорошо, если бы вы могли указать возможное решение, которое CPLEX не может найти. Другими словами, докажите, что CPLEX не прав. - person Daniel Junglas; 23.03.2020
comment
Есть ли частный способ поделиться с вами своим кодом? - person Sana.Nz; 23.03.2020
comment
Кроме того, это одно из возможных решений, которое Cplex не генерирует: [181,240,167, 254,4, 417,83, 338] - person Sana.Nz; 23.03.2020
comment
Вы можете отправить электронное письмо на адрес daniel (dot) junglas (at) de (dot) ibm (dot) com, чтобы поделиться своей моделью / кодом. - person Daniel Junglas; 24.03.2020