Как увеличить количество решений Cplex? - PullRequest
0 голосов
/ 19 марта 2020

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

Первый: Для моей модели я получил 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
.
.
.

1 Ответ

1 голос
/ 19 марта 2020

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

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

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

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

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

  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)
...