Проблемы синтаксического анализа IloBoolVarArray на Bool в CPLEX

У меня проблема IloBoolVarArray в MIP. Когда решатель закончил, я анализирую эти переменные до double, но иногда я получаю очень маленькие значения, такие как 1.3E-008 вместо 0. Мой вопрос: почему? Проблема только в разборе? Внутренне решатель использовал это значение, поэтому результат не заслуживает доверия?

Большое спасибо.


person jonango    schedule 09.03.2016    source источник
comment
Зачем вам нужно преобразовать логическое значение в двойное? Вы пытались сравнить логическое значение с IloTrue или IloFalse?   -  person vcp    schedule 10.03.2016
comment
Это эксперимент, потому что моя целевая функция умножает IloNumVarArray на IloBoolVarArray, и у меня возникают проблемы с точностью. Я хочу найти проблему   -  person jonango    schedule 10.03.2016


Ответы (1)


CPLEX внутренне работает с данными с плавающей запятой двойной точности. Он имеет параметр допуска EpInt. Если переменная x имеет значения

0 <= x <= EpInt, or
1-EpInt <= x <= 1

Затем CPLEX считает значение двоичным. Значение по умолчанию для EpInt равно 10^-6, поэтому ваши видимые значения решения 10^-8 согласуются с поведением CPLEX по умолчанию. Если вам действительно не нужны точные целочисленные значения, вам следует учитывать это при извлечении решений из CPLEX. Одна особенно плохая вещь, которую вы могли бы сделать в C++, это

IloBoolVar x(env);
// ...
cplex.solve();
int bad_value = cplex.getValue(x); // BAD
int ok_value = cplex.getValue(x) + 0.5; // OK

Здесь для bad_value может быть установлено значение 0, даже если эффективное значение решения CPLEX равно 1. Это связано с тем, что CPLEX может иметь значение 0,999999, которое будет усечено до 0. Второе назначение надежно сохранит решение.

В последней версии CPLEX вы можете установить для EpInt значение 0, что заставит CPLEX рассматривать только 0.0 и 1.0 как двоичные. Если вам действительно нужны точные значения 0 или 1, вам следует помнить о доменах, для которых предназначен CPLEX. Если вы пытаетесь использовать его для решения, например, проблем с криптологией, вы можете не получить хороших результатов даже с небольшими экземплярами.

person David Nehme    schedule 10.03.2016
comment
Итак, в некоторых случаях у меня будут операции как 236.212 * 10^-6? Я работаю со многими значениями (но это не большие данные), но когда я проверял решение, были ошибки точности около 1E-2, поэтому я предположил, что ошибка точности накапливалась во время операций. Большое спасибо. - person jonango; 10.03.2016