Каноническая система пример в линейном программировании. Каноническая форма задач линейного программирования. Симплексный метод решения злп
ВЕНГЕРСКИЙ МЕТОД
Венгерский метод является одним из интереснейших и наиболее распространенных методов решения транспортных задач.
Рассмотрим сначала основные идеи венгерского метода на примере решения задачи выбора (задачи о назначениях), которая является частным случаем Т-задачи, а затем обобщим этот метод для произвольной Т-задачи.
Венгерский метод для задачи о назначениях
Постановка задачи. Предположим, что имеется различных работ и механизмов , каждый из которых может выполнять любую работу, но с неодинаковой эффективностью. Производительность механизма при выполнении работы обозначим , и = 1,...,n; j = 1,...,n . Требуется так распределить механизмы по работам, чтобы суммарный эффект от их использования был максимален. Такая задача называется задачей выбора или задачей о назначениях.
Формально она записывается так. Необходимо выбрать такую последовательность элементов из матрицы
чтобы сумма была максимальна и при этом из каждой строки и столбца С был выбран только один элемент.
Введем следующие понятия.
Нулевые элементы матрицы С называются независимыми нулями, если для любого строка и столбец, на пересечении которых расположен элемент , не содержат другие такие элементы .
Две прямоугольные матрицы С и D называются эквивалентными (C ~ D ), если для всех i,j . Задачи о назначениях, определяемые эквивалентными матрицами, являются эквивалентными (т.е. оптимальные решения одной из них будут оптимальными и для второй, и наоборот).
Описание алгоритма венгерского метода
Алгоритм состоит из предварительного этапа и не более чем (n -2) последовательно проводимых итераций. Каждая итерация связана с эквивалентными преобразованиями матрицы, полученной в результате проведения предыдущей итерации, и с выбором максимального числа независимых нулей. Окончательным результатом итерации является увеличение числа независимых нулей на единицу. Как только количество независимых нулей станет равным n , проблему выбора оказывается решенной, а оптимальный вариант назначений определяется позициями независимых нулей в последней матрице.
Предварительный этап. Разыскивают максимальный элемент в j - м столбце и все элементы этого столбца последовательно вычитают из максимального. Эту операцию проделывают над всеми столбцами матрицы С . В результате образуется матрица с неотрицательными элементами, в каждом столбце которой имеется, по крайней мере, один нуль.
Далее рассматривают i - ю строку полученной матрицы, разыскивают ее минимальный элемент a i и из каждого элемента этой строки вычитают минимальный. Эту процедуру повторяют со всеми строками. В результате получим матрицу С 0 (С 0 ~ C ), в каждой строке и столбце которой имеется, по крайней мере, один нуль. Описанный процесс преобразования С в С 0 называется приведением матрицы.
Находим произвольный нуль в первом столбце и отмечаем его звездочкой. Затем просматриваем второй столбец, и если в нем есть нуль, расположенный в строке, где нет нуля со звездочкой, то отмечаем его звездочкой. Аналогично просматриваем один за другим все столбцы матрицы С 0 и отмечаем, если возможно, следующие нули знаком "*". Очевидно, что нули матрицы С 0 , отмеченные звездочкой, являются независимыми. На этом предварительный этап заканчивается.
(k +1)-ая итерация. Допустим, что k -я итерация уже проведена и в результате получена матрица С k . Если в ней имеется ровно n нулей со звездочкой, то процесс решения заканчивается. В противном случае переходим к (k +1) - й итерации.
Каждая итерация начинается первым и заканчивается вторым этапом. Между ними может несколько раз проводиться пара этапов: третий - первый. Перед началом итерации знаком "+" выделяют столбцы матрицы С k , которые содержат нули со звездочками.
Первый этап. Просматривают невыделенные столбцы С k . Если среди них не окажется нулевых элементов, то переходят к третьему этапу. Если же невыделенный нуль матрицы С k обнаружен, то возможен один из двух случаев: 1) строка, содержащая невыделенный нуль, содержит также и нуль со звездочкой; 2) эта строка не содержит нуля со звездочкой.
Во втором случае переходим сразу ко второму этапу, отметив этот нуль штрихом.
В первом случае этот невыделенный нуль отмечают штрихом и выделяют строку, в которой он содержится (знаком "+" справа от строки). Просматривают эту строку, находят нуль со звездочкой и уничтожают знак "+" выделения столбца, в котором содержится данный нуль.
Далее просматривают этот столбец (который уже стал невыделенным) и отыскивают в нем невыделенный нуль (или нули), в котором он находится. Этот нуль отмечают штрихом и выделяют строку, содержащую такой нуль (или нули). Затем просматривают эту строку, отыскивая в ней нуль со звездочкой.
Этот процесс за конечное число шагов заканчивается одним из следующих исходов:
1) все нули матрицы С k выделены, т.е. находятся в выделенных строках или столбцах. При этом переходят к третьему этапу;
2) имеется такой невыделенный нуль в строке, где нет нуля со звездочкой. Тогда переходят ко второму этапу, отметив этот нуль штрихом.
Второй этап. На этом этапе строят следующую цепочку из нулей матрицы С k : исходный нуль со штрихом, нуль со звездочкой, расположенный в одном столбце с первым нулем со штрихом в одной строке с предшествующим нулем со звездочкой и т.д. Итак, цепочка образуется передвижением от 0 " к 0 * по столбцу, от 0 * к 0 " по строке и т.д.
Можно доказать, что описанный алгоритм построения цепочки однозначен и конечен, при этом цепочка всегда начинается и заканчивается нулем со штрихом.
Далее над элементами цепочки, стоящими на нечетных местах (0 ") -, ставим звездочки, уничтожая их над четными элементами (0 *). Затем уничтожаем все штрихи над элементами С k и знаки выделения "+". Количество независимых нулей будет увеличено на единицу. На этом (k+ 1) -я итерация закончена.
Третий этап. К этому этапу переходят после первого, если все нули матрицы С k выделены. В таком случае среди невыделенных элементов С k выбирают минимальный и обозначают его h (h >0). Далее вычитают h из всех элементов матрицы С k , расположенных в невыделенных строках и прибавляют ко всем элементам, расположенным в выделенных столбцах. В результате получают новую матрицу С " k , эквивалентную С k . Заметим, что при таком
преобразовании, все нули со звездочкой матрицы С k остаются нулями и в С " k , кроме того, в ней появляются новые невыделенные нули. Поэтому переходят вновь к первому этапу. Завершив первый этап, в зависимости от его результата либо переходят ко второму этапу, либо вновь возвращаются к третьему этапу.
После конечного числа повторений очередной первый этап обязательно закончится переходом на второй этап. После его выполнения количество независимых нулей увеличится на единицу и (k+ 1)- я итерация будет закончена.
Пример 3.4. Решить задачу о назначениях с матрицей
При решении задачи используем следующие обозначения:
Знак выделения "+", подлежащий уничтожению, обводим кружком; цепочку, как и ранее, указываем стрелками.
Предварительный этап. Отыскиваем максимальный элемент первого столбца - 4. Вычитаем из него все элементы этого столбца. Аналогично для получения второго, третьего, четвертого и пятого столбцов новой матрицы вычитаем все элементы этих столбцов от п"яти, трех, двух и трех соответственно. Получим матрицу С " (C " ~C ). Так как в каждой строке С " есть нуль, то С " = С 0 и процесс приведения матрицы заканчивается. Далее ищем и отмечаем знаком "*" независимые нули в С 0 , начиная с первой строки.
Первая итерация . Первый этап. Выделяем знаком "+" первый, второй, и четвертый столбцы матрицы С 0 , которые содержат 0 * .
Просматриваем невыделенный третий столбец, находим в нем невыделенный нуль С 23 = 0, отмечаем его штрихом и выделяем знаком "+" вторую строку. Просматриваем эту строку, находим в ней элемент С 22 = 0 * и уничтожаем знак выделения второго столбца, содержащего 0 * . Затем просматриваем второй столбец - в нем нет невыделенных элементов. Переходим к последнему невыделенному столбцу (пятому), ищем в нем невыделенные нули. Поскольку невыделенных нулей нет, то переходим к третьему этапу.
Третий этап. Находим минимальный элемент в невыделенной части матрицы С 0 (т.е. элементы, которые лежат в столбцах и строках, не отмеченных знаком "+"). Он равен h = 1.
Вычтем h = 1 из всех элементов невыделенных строк (т.е. всех, кроме второго) и прибавим ко всем элементам выделенных столбцов (первого и четвертого). Получим матрицу С " 1 и перейдем к первому этапу.
Первый этап. Перед его началом вновь выделяем знаком "+" первый, второй и четвертый столбцы. Просматриваем невыделенный третий столбец, находим в нем невыделенный нуль С 23 = 0, отмечаем его знаком штрих. Поскольку во второй строке есть 0 * (элемент С 22), то выделяем знаком "+" вторую строку, далее уничтожаем знак выделения второго столбца, где лежит 0 * . Потом просмотрим второй столбец, находим в нем невыделенный нуль С 12 = 0, отмечаем его знаком штрих. Поскольку в первой строке есть нуль со звездочкой С 14 = 0 * , то выделяем его знаком "+", и уничтожаем знак выделения четвертого столбца, где находился этот знак 0 * . Затем пересматриваем четвертый столбец и находим в нем невыделенный нуль С 54 = 0. Так как в строке, где он находится, нет нуля со звездочкой, то отметив этот 0 штрихом, переходим ко второму этапу.
Предположим, что у нас имеются $4$ склада $A_1,\ A_2,\ A_3,\ A_4$ и $4$ магазина $B_1,\ B_2,\ B_3,\ B_4$. Расстояния от каждого склада до каждого магазина заданы с помощью следующей матрицы:
Например, расстояние от $A_1$ до $B_1$ равно элементу $a_{11}=10$, расстояние от $A_2$ до $B_2$ равно элементу $a_{12}=20$, и т.д.
Требуется так прикрепить склады к магазинам, чтобы суммарное расстояние получилось минимальным. Такая задача называется задачей о назначениях. Решать ее можно с помощью так называемого венгерского алгоритма.
Венгерский алгоритм
- В каждой строке матрицы назначения находим минимальный элемент и вычитаем его из всех элементов строки.
- В каждом столбце полученной матрицы находим минимальный элемент и вычитаем его из всех элементов столбца.
- Находим строку с одним нулем. Этот ноль заключаем в квадрат и называем отмеченным. В столбце, где стоит отмеченный ноль, все остальные нули зачеркиваем и в дальнейшем не рассматриваем. Этот шаг продолжаем, пока возможно.
- Находим столбец с одним нулем и этот ноль отмечаем. В строке, где стоит отмеченный ноль, все остальные нули зачеркиваются. Этот шаг продолжаем, пока возможно.
- Если после выполнения шагов $3$ и $4$ еще остаются неотмеченные нули, то отмечаем любой их них, а в строке и столбце, где стоит отмеченный ноль, все остальные нули зачеркиваются.
- Если каждая строка и каждый столбец матрицы содержит ровно один отмеченный ноль, то получено оптимальное решение. Каждый из отмеченных нулей прикрепляет поставщика к потребителю. В противном случаем проводим минимальное количество пересекающихся вертикальных и горизонтальных прямых через все нули. Среди не зачеркнутых этими прямыми чисел ищем минимум. Этот минимум вычитаем их всех не зачеркнутых чисел и прибавляем ко всем числам на пересечении прямых. К полученной матрице применяем вышеприведенный алгоритм, начиная с шага $3$.
Пример решения
Находим минимальный элемент в каждой строке матрицы и вычитаем его из всех элементов строки.
В полученной матрице проделываем тоже самое со столбцами, то есть находим в каждом столбце минимальный элемент и вычитаем его из всех элементов столбца.
В первой строке полученной матрицы находится ровно один ноль. Отмечаем его, а в столбце, где стоит этот ноль все остальные нули зачеркиваем. Получим матрицу:
Следующая строка, в который находится ровно один ноль, это $4$-я. С ней поступаем точно так же. Больше нет строк, содержащих ровно один ноль, но имеются столбцы с одним нулем. Второй столбец содержит ровно один ноль, который мы и отметим. Поскольку этот ноль находится в $3$-й строке, то вычеркиваем все нули, находящиеся в $3$-й строке. Получим матрицу:
Видим, что в матрице больше нет нулей. Полученное распределение не является оптимальным, поскольку во второй строке нет отмеченных нулей. Проводим минимальное количество пересекающихся вертикальных и горизонтальных прямых через все нули.
Находим минимальный элемент среди не зачеркнутых этими прямыми чисел: ${\min \left(5,\ 13,\ 7,\ 2,\ 11,\ 8\right)\ }=2$. Вычитаем найденный минимум из всех не зачеркнутых чисел и прибавляем его ко всем числам, стоящими на пересечении прямых. Получим матрицу:
Полученное распределение не является оптимальным, поскольку в $4$-й строке нет отмеченных нулей. Проводим прямые:
${\min \left(11,\ 5,\ 9,\ 6,\ 6,\ 1\right)\ }=1$. Вычитаем найденный минимум из всех не зачеркнутых чисел и прибавляем его ко всем числам, стоящими на пересечении прямых. Получим матрицу:
К полученной матрицы применяем вышеописанный алгоритм:
Видим, что в каждой строке и в каждом столбце матрицы находится ровно один отмеченный ноль. Получено оптимальное распределение. $A_1$ прикрепляем к $B_4$, $A_2$ - к $B_1$, $A_3$ - к $B_2$, $A_4$ - к $B_3$. Для того, чтобы найти суммарное распределение, нужно сложить числа, расположенные в исходной матрице на месте отмеченных нулей. Получим: $5+3+8+8=24$.
Стоит отметить, что задача о назначениях может решаться и на максимум (чтобы суммарное расстояние было максимальным). В этом случае каждый элемент матрицы умножается на $-1$ и к полученной матрице применяется вышеописанный алгоритм.
Шаг 1. (Редукция строк и столбцов). Цель данного шага состоит в получении максимально возможного числа нулевых элементов в матрице стоимостей. Для этого из всех элементов каждой строки вычитают минимальный элемент соответствующей строки, а затем из всех элементов каждого столбца полученной матрицы вычитают минимальный элемент соответствующего столбца. В результате получают редуцированную матрицу стоимостей и переходят к поиску назначений.
Шаг 2. (Определение назначений). На этом шаге можно использовать алгоритм поиска «наибольшего паросочетания с матрицей двудольного графа (существуют и другие возможности), если все =0 матрицы заменить на «1», а >0 на «0».
Если нельзя найти полного назначения, то необходима дальнейшая модификация матрицы стоимостей, т.е. перейти к шагу 3.
Шаг 3 . (Модификация редуцированной матрицы). Для редуцированной матрицы стоимостей:
а) Вычислить число нулей в каждой невычеркнутой строке и каждом невычеркнутом столбце.
б) Вычеркнуть строку или столбец с максимальным числом нулей.
в) Выполнять пункты а) и б) до тех пор, пока не будут вычеркнуты все нули.
г) Из всех невычеркнутых элементов вычесть минимальный невычеркнутый элемент и прибавить его к каждому элементу, расположенному на пересечении двух линий.
Перейти к шагу 2.
Замечание 3 .Если исходная задача является задачей максимизации, то все элементы матрицы стоимостей следует умножить на (-1) и сложить их с достаточно большим числом так, чтобы матрица не содержала бы отрицательных элементов. Затем задачу следует решать как задачу минимизации.
Пример 13.5. Покажем работу венгерского алгоритма на примере задачи о назначениях со следующей матрицей стоимостей:
Итерация 1
Шаг 1 . Редукция строк и столбцов.
Значения минимальных элементов строк 1, 2, 3 и 4 равны 2, 4, 11 и 4 соответственно. Вычитая из элементов каждой строки соответствующее минимальное значение, получим следующую матрицу:
Значения минимальных элементов столбцов 1, 2, 3 и 4 равны 0, 0, 5 и 0 соответственно. Вычитая из элементов каждого столбца соответствующее минимальное значение, получим следующую матрицу.
Шаг 2 . Поиск допустимого решения, для которого все назначения имеют нулевую стоимость. Используем алгоритм поиска наибольшего паросочетания. Преобразуем матрицу в матрицу двудольного графа, затем в рабочую таблицу:
Находим паросочетание:
Это паросочетание не совершенное, т.е. полного назначения нет. На Шаг 3.
Шаг 3. Модификация редуцированной матрицы.
а) Число нулей в строках 1, 2, 3 и 4 равно 1, 1, 2 и 1 соответственно. Для столбцов соответствующие величины равны 2, 1, 1 и 1.
б) Максимальное число нулей, по два, содержат строка 3 и столбец 1. Выбираем строку 3 и вычеркиваем все ее элементы горизонтальной линией.
в) Число невычеркнутых нулей в строках 1, 2 и 4 равно 1, 1 и 1 соответственно. Для столбцов соответствующие значения равны 2, 1, 0, и 0. Поэтому мы должны выбрать столбец 1 и вычеркнуть его вертикальной линией. После этого останется только один невычеркнутый нуль – элемент (2,2). Поэтому можно вычеркнуть либо строку 2, либо столбец 2. Вычеркивая строку 2 горизонтальной линией, получаем следующую матрицу:
г) Значение минимального невычеркнутого элемента равно 2. Вычитая его из всех невычеркнутых элементов и складывая его со всеми элементами, расположенными на пересечении двух линий, получаем новую матрицу стоимостей.