Я работаю над некоторыми расширенными эвристиками ветвления для смешанного целочисленного программирования, используя CPLEX (12.9) с помощью API Python (3.6). Часть решений о ветвлении должна основываться на оценке сильных ветвлений (SB) переменных. Хотя я могу запросить оценку псевдостоимости переменных напрямую через API [1], кажется, нет простого способа получить рассчитанные оценки SB. Поэтому я хочу реализовать расчет самостоятельно. Я нашел старое сообщение на форуме, описывающее, как максимально эффективно реализовать сильные вычисления ветвления [2] с помощью C-API. К сожалению, описанный метод использует библиотечные вызовы (например, CPXgetcallbacknodelp()), для которых я не могу найти соответствующие методы Python.
Это оставляет меня с тремя вопросами:
Мой вопрос касается эффективного расчета/получения баллов SB. Я знаю, как реализовать обратные вызовы в целом.






Невозможно получить доступ непосредственный к nodelp через CPLEX Python API. Если вы используете один из обратных вызовов, унаследованных от HSCallback, вы можете вызвать для него solve() и т. д.
Что вы можете сделать (хотя это может быть неэффективно), так это клонировать исходную проблему, передавать ее обратному вызову при ее создании, а затем на каждом узле вызывать Cplex.advanced.strong_branching().
Спасибо за ваш полезный ответ. Чтобы использовать advanced.strong_branching на каждом узле, клон моей проблемы должен знать, какие переменные уже использовались для ветвления над текущим узлом (не так ли?).
Я думаю, вам не нужно знать, какие переменные были разветвлены сами по себе. С другой стороны, вам нужно знать, какие из них зафиксированы в текущем узле, что вы можете получить, посмотрев границы. Это будет включать в себя переменные, которые были разветвлены, а также те, которые были выведены с помощью других средств.
Хорошая точка зрения. Таким образом, в основном я мог бы сделать следующее (сокращение и предварительное решение отключены на данный момент): - Сохраняйте копию проблемы в отдельной переменной. - В каждом узле запрашивайте текущие границы переменных и добавляйте их в копию. - Используйте strong_branching при копировании и сборе результатов. Кажется разумным. Я проведу некоторое исследование того, как можно использовать теплый старт для ускорения процесса.
Я также придумал другую стратегию, которая может быть быстрее. Используйте nodecallback и branchcallback. В обратном вызове ветвей добавьте ветки для каждой переменной, для которой я хочу рассчитать оценку SB (sb-узлы), и одну псевдоветвь, которая состоит из той же проблемы, что и текущий узел (псевдоузел). В обратном вызове node всегда сначала выбирайте sb-узлы и решайте их, устанавливая ограничение симплексной итерации на некоторое значение. Соберите информацию, сгенерированную sb-узлами, и передайте ее псевдоузлу, чтобы принять реальное решение о ветвлении.
На форуме IBM Developer Answers здесь есть связанный вопрос.