Интерфейс CPLEX C ++: Как получить индекс нарушенного ограничения?

Я пытаюсь решить целочисленную линейную программу (ILP) с помощью решателя IBM ILOG CPLEX на C ++. Решатель заявляет, что проблема невозможна, и указывает на индекс нарушенного ограничения. Мой вопрос касается идентификации и анализа этого ограничения в C ++.

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

Предпочтительно, я хотел бы получить индекс нарушенного ограничения в C ++ и получить как можно больше информации об этом конфликте.

В настоящее время я использую средство для уточнения конфликта, но не получаю никакой полезной информации. В частности, я держу IloRangeArray из всех ограничений, которые я когда-либо добавляю к модели, звоните refineConflict для этого массива, а затем использовать функцию getConflict запросить (возможно) нарушенные ограничения. В результате все ограничения, которые я когда-либо добавил, возможно, нарушены, и никакое ограничение не было доказано.

Как я могу получить доступ к индексу одного ограничения, указанного в сообщении об ошибке, в котором говорится, что проблема невозможна?

Кроме того, я неправильно использую средство уточнения конфликтов? Например. я делаю что-то не так, когда делаю копии ограничений, которые добавляю в модель в отдельном массиве? (Конструктор копирования и оператор присваивания некоторых классов в Cplex, кажется, имеют нестандартное поведение, которое я не понимаю.)

Любая помощь приветствуется.

2

Решение

Я не пытался использовать API для уточнения конфликтов. Наверное, стоит разобраться в этом … но я часто использую средство уточнения конфликтов в автономном интерактивном CPLEX. Мне не известно о каких-либо проблемах сохранения копий ограничений в вашем собственном коде — я делал это раньше в CPLEX & Концерт с C ++. Это может быть концептуальное недопонимание того, что делает переработчик конфликта …

Помните, что очень редко иметь одно идентифицируемое невыполнимое ограничение. Гораздо чаще встречается набор ограничений, которые не могут быть выполнены вместе, но если какое-либо из этого набора ограничений будет удалено, тогда остальные будут выполнимы. Это обычно называют «неприводимым неосуществимым множеством».

Подумайте, например, о трех ограничениях:

a >= b + 1
b >= c + 1
c >= a + 1

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

В любом случае попробуйте экспортировать модель в виде файла формата LP, MPS или SAV и прочитать его в автономном оптимизаторе CPLEX. Затем оптимизируйте его — он также должен потерпеть неудачу с заявленной невозможностью. Затем запустите средство уточнения конфликта и отобразите вычисленный (неприводимый) недопустимый набор:

read fred.lp
optimize
conflict
display conflict all

Я считаю, что MPS-файлы лучше сохраняют всю точность проблемы и, вероятно, более портативны, чтобы их можно было использовать с другими решателями, но LP-файлы гораздо более удобочитаемы для человека. Предполагается, что формат файла SAV является наиболее точной копией того, что CPLEX имеет в памяти, но он очень непрозрачен и, скорее, специфичен для CPLEX. Если ваша проблема явно недостижима, возможно, с форматом LP лучше работать, но если проблема является нерешаемой, вы можете получить другое поведение из файла LP. Вероятно, вам бы очень помогло, если бы вы назвали все свои переменные рекламными ограничениями. Может быть, просто сделать именование в отладочных сборках или добавить флаг, чтобы контролировать, нужно ли делать дополнительное именование.

1

Другие решения

Других решений пока нет …