Разделить и разрезать - Branch and cut

Разделить и разрезать[1] это метод комбинаторная оптимизация для решения целочисленные линейные программы (ILP), то есть линейное программирование (LP) задачи, в которых некоторые или все неизвестные ограничены целое число значения.[2] Разделение и сокращение включает в себя выполнение ветвь и переплет алгоритм и использование рубки ужесточить релаксации линейного программирования. Обратите внимание, что если сокращения используются только для ужесточения начальной релаксации LP, алгоритм называется разрезать и ветвить.

Алгоритм

Это описание предполагает, что ILP является максимизация проблема.

Метод решает линейная программа без целочисленного ограничения используя обычный симплексный алгоритм. Когда оптимальное решение получено, и это решение имеет нецелое значение для переменной, которая должна быть целой, a алгоритм плоскости отсечения может быть использован для поиска дополнительных линейных ограничений, которым удовлетворяют все достижимый целые точки, но нарушены текущим дробным решением. Эти неравенства могут быть добавлены к линейной программе, так что ее разрешение приведет к другому решению, которое, будем надеяться, будет «менее дробным».

На данный момент ветвь и переплет часть алгоритма запущена. Проблема разбита на несколько (обычно две) версии. Затем новые линейные программы решаются симплексным методом, и процесс повторяется. В процессе ветвей и границ нецелые решения LP-релаксации служат верхними границами, а интегральные решения - нижними. Узел может быть обрезанный если верхняя граница ниже существующей нижней границы. Кроме того, при решении релаксации LP могут быть созданы дополнительные плоскости сечения, которые могут быть либо глобальные сокращения, т.е. справедливо для всех возможных целочисленных решений, или местные сокращения, что означает, что им удовлетворяют все решения, удовлетворяющие боковым ограничениям из текущего рассматриваемого ветвления и привязанного поддерева.

Алгоритм кратко изложен ниже.

  1. Добавьте начальную ILP к , список активных проблем
  2. Набор и
  3. пока не пусто
    1. Выбрать и удалить (удалить из очереди) проблему из
    2. Решите ЛП релаксацией проблемы.
    3. Если решение неосуществимо, вернитесь к 3 (пока). В противном случае обозначим решение через с объективной ценностью .
    4. Если , вернитесь к 3.
    5. Если целое число, установить и вернитесь к 3.
    6. При желании ищите плоскости сечения, которые нарушаются . Если таковые обнаружены, добавьте их к релаксации LP и вернитесь к 3.2.
    7. Разделение для разделения проблемы на новые задачи с ограниченными возможными регионами. Добавьте эту проблему в и вернуться к 3
  4. возвращаться

Псевдокод

В C ++ -подобно псевдокод, это можно было бы написать:

 1 // Псевдокод решения ветвления и отсечения ILP, предполагая, что цель должна быть максимизирована 2 ILP_solution branch_and_cut_ILP(IntegerLinearProgram начальная_проблема) { 3     очередь active_list; // L, выше 4     active_list.ставить в очередь(начальная_проблема); // шаг 1 5     // шаг 2 6     ILP_solution Оптимальное решение; // это будет содержать x * выше 7     двойной best_objective = -стандартное::numeric_limits<двойной>::бесконечность; // будет содержать v * выше 8     пока (!active_list.пустой()) { // шаг 3 выше 9         LinearProgram& curr_prob = active_list.исключать из очереди(); // шаг 3.110         делать { // шаги 3.2-3.711             RelaxedLinearProgram& Relaxed_prob = LP_relax(curr_prob); // шаг 3.212             LP_solution curr_relaxed_soln = LP_solve(Relaxed_prob); // это x выше13             bool cut_planes_found = ложный;14             если (!curr_relaxed_soln.is_feasible()) { // шаг 3.315                 Продолжить; // пробуем другое решение; продолжается на шаге 316             }17             двойной current_objective_value = curr_relaxed_soln.ценить(); // v выше18             если (current_objective_value <= best_objective) { // шаг 3.419                 Продолжить; // пробуем другое решение; продолжается на шаге 320             }21             если (curr_relaxed_soln.is_integer()) { // шаг 3.522                 best_objective = current_objective_value;23                 Оптимальное решение = cast_as_ILP_solution(curr_relaxed_soln);24                 Продолжить; // продолжаем с шага 325             }26             // текущее смягченное решение не является интегральным27             если (unting_for_cutting_planes) { // шаг 3.628                 violated_cutting_planes = search_for_violated_cutting_planes(curr_relaxed_soln);29                 если (!violated_cutting_planes.пустой()) { // шаг 3.630                     cut_planes_found = истинный; // продолжаем с шага 3.231                     за (авто&& Cut_plane : violated_cutting_planes) {32                         active_list.ставить в очередь(LP_relax(curr_prob, Cut_plane));33                     }34                     Продолжить; // продолжаем с шага 3.235                 }36             }37             // шаг 3.7: либо нарушенные режущие плоскости не найдены, либо мы их не искали38             авто&& разветвленные_проблемы = branch_partition(curr_prob);39             за (авто&& ответвляться : разветвленные_проблемы) {40                 active_list.ставить в очередь(ответвляться);41             }42             Продолжить; // продолжаем с шага 343         } пока (unting_for_cutting_planes / * параметр алгоритма; см. 3.6 * /44                && cut_planes_found);45         // завершаем шаг 3.2 цикл do-while46     } // завершаем шаг 3 пока цикл47     возвращаться Оптимальное решение; // шаг 448 }

В приведенном выше псевдокоде функции LP_relax, LP_solve и branch_partition вызываемые как подпрограммы должны быть предоставлены в зависимости от проблемы. Например, LP_solve мог бы назвать симплексный алгоритм. Стратегии ветвления для branch_partition обсуждаются ниже.

Стратегии ветвления

Важным шагом в алгоритме ветвления и отсечения является шаг ветвления. На этом этапе можно использовать различные эвристики ветвления. Все описанные ниже стратегии ветвления включают то, что называется ветвление по переменной.[3] Ветвление по переменной включает выбор переменной, , с дробным значением, , в оптимальном решении текущей релаксации ЛП с последующим добавлением ограничений и

Наиболее недопустимое ветвление
Эта стратегия ветвления выбирает переменную, дробная часть которой ближе всего к 0,5.
Ветвление псевдозатрат
Основная идея этой стратегии - отслеживать каждую переменную. изменение целевой функции, когда эта переменная была ранее выбрана в качестве переменной для перехода. Затем стратегия выбирает переменную, для которой прогнозируется наибольшее изменение целевой функции на основе прошлых изменений, когда она была выбрана в качестве переменной ветвления. Обратите внимание, что ветвление псевдозатрат изначально неинформативно при поиске, так как несколько переменных были разветвлены.
Сильное ветвление
Сильное ветвление включает в себя проверку того, какая из переменных-кандидатов дает лучшее улучшение целевой функции, прежде чем фактически выполнять ветвление по ним. Полное сильное ветвление проверяет все возможные переменные и может потребовать больших вычислительных ресурсов. Вычислительные затраты могут быть уменьшены, если рассматривать только подмножество переменных-кандидатов и не решать каждую из соответствующих релаксаций LP до завершения.

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

Рекомендации

  1. ^ Падберг, Манфред; Ринальди, Джованни (1991). "Алгоритм ветвей и разрезов для решения крупномасштабных симметричных задач коммивояжера". SIAM Обзор. 33 (1): 60–100. Дои:10.1137/1033004. ISSN  0036-1445.
  2. ^ Джон Э., Митчелл (2002). "Разветвленные алгоритмы для задач комбинаторной оптимизации" (PDF). Справочник по прикладной оптимизации: 65–77.
  3. ^ Ахтерберг, Тобиас; Кох, Торстен; Мартин, Александр (2005). «Пересмотр правил ветвления». Письма об исследованиях операций. 33 (1): 42–54. Дои:10.1016 / j.orl.2004.04.002.

внешняя ссылка