О назначениях венгерский метод на max лекция. Смотреть страницы где упоминается термин метод венгерский

  • Tutorial

Привет, друзья! В этой статье хотел бы рассказать про интересный алгоритм из дисциплины «Исследование операций» а именно про Венгерский метод и как с его помощью решать задачи о назначениях. Немного затрону теории про то, в каких случаях и для каких задач применим данный алгоритм, поэтапно разберу его на мною выдуманном примере, и поделюсь своим скромным наброском кода его реализации на языке R. Приступим!

Пару слов о методе

Для того чтобы не расписывать много теории с математическими терминами и определениями, предлагаю рассмотреть пару вариантов построения задачи о назначениях, и я думаю Вы сразу поймете в каких случаях применим Венгерский метод:
  • Задача о назначении работников на должности. Необходимо распределить работников на должности так, чтобы достигалась максимальная эффективность, или были минимальные затраты на работу.
  • Назначение машин на производственные секции. Распределение машин так, чтобы при их работе производство было максимально прибыльным, или затраты на их содержание минимальны.
  • Выбор кандидатов на разные вакансии по оценкам. Этот пример разберем ниже.
Как Вы видите, вариантов для которых применим Венгерский метод много, при этом подобные задачи возникают во многих сферах деятельности.

В итоге задача должна быть решена так, чтобы один исполнитель (человек, машина, орудие, …) мог выполнять только одну работу, и каждая работа выполнялась только одним исполнителем.

Необходимое и достаточное условие решения задачи – это ее закрытый тип. Т.е. когда количество исполнителей = количеству работ (N=M). Если же это условие не выполняется, то можно добавить вымышленных исполнителей, или вымышленные работы, для которых значения в матрице будут нулевыми. На решение задачи это никак не повлияет, лишь придаст ей тот необходимый закрытый тип.

Step-by-step алгоритм на примере

Постановка задачи: Пусть намечается важная научная конференция. Для ее проведения необходимо настроить звук, свет, изображения, зарегистрировать гостей и подготовиться к перерывам между выступлениями. Для этой задачи есть 5 организаторов. Каждый из них имеет определенные оценки выполнения той, или иной работы (предположим, что эти оценки выставлены как среднее арифметическое по отзывам их сотрудников). Необходимо распределить организаторов так, чтобы суммарная их оценка была максимальной. Задача имеет следующий вид:


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


В каждой строке и в каждом столбце должен быть только один выбранный ноль. (т.е. когда выбрали ноль, то остальные нули в этой строке или в этом столбце уже не берем в расчет). В этом случае это сделать невозможно:


(Если задача решается на минимум, то необходимо начинать с этого шага ). Продолжаем решение далее. Редукция матрицы по строкам (ищем минимальный элемент в каждой строке и вычитаем его из каждого элемента соответственно):


Т.к. все минимальные элементы – нулевые, то матрица не изменилась. Проводим редукцию по столбцам:


Опять же смотрим чтобы в каждом столбце и в каждой строке был только один выбранный ноль. Как видно ниже, в данном случае это сделать невозможно. Представил два варианта как можно выбрать нули, но ни один из них не дал нужный результат:


Продолжаем решение дальше. Вычеркиваем строки и столбцы, которые содержат нулевые элементы (ВАЖНО! Количество вычеркиваний должно быть минимальным ). Среди оставшихся элементов ищем минимальный, вычитаем его из оставшихся элементов (которые не зачеркнуты) и прибавляем к элементам, которые расположены на пересечении вычеркнутых строк и столбцов (то, что отмечено зеленым – там вычитаем; то, что отмечено золотистым – там суммируем; то, что не закрашено – не трогаем):


Как теперь видно, в каждом столбце и строке есть только один выбранный ноль. Решение задачи завершаем!


Подставляем в начальную таблицу месторасположения выбранных нулей. Таким образом мы получаем оптимум, или оптимальный план, при котором организаторы распределены по работам и сумма оценок получилась максимальной:


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

Реализация на языке программирования R

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

Данные для решения задачи берутся из файла example.csv который имеет вид:


#Подключаем библиотеку для удобства расчетов library(dplyr) #Считываем csv фаил (первый столбик - названия строк; первая строка - названия столбцов) table <- read.csv("example.csv",header=TRUE,row.names=1,sep=";") #Проводим расчеты unique_index <- hungarian_algorithm(table,T) #Выводим cat(paste(row.names(table)," - ",names(table)),sep = "\n") #Считаем оптимальный план cat("Оптимальное значение -",sum(mapply(function(i, j) table, unique_index$row, unique_index$col, SIMPLIFY = TRUE))) #____________________Алгоритм венгерского метода__________________________________ hungarian_algorithm <- function(data,optim=F){ #Если optim = T, то будет искаться максимальное оптимальное значение if(optim==T) { data <- data %>% apply(1,function(x) (x-max(x))*(-1)) %>% t() %>% as.data.frame() optim <- F } #Редукция матрицы по строкам data <- data %>% apply(1,function(x) x-min(x)) %>% t() %>% as.data.frame() #Нахождение индексов всех нулей zero_index <- which(data==0, arr.ind = T) #Нахождение всех "неповторяющихся" нулей слева-направо unique_index <- from_the_beginning(zero_index) #Если количество "неповторяющихся" нулей не равняется количеству строк в исходной таблице, то.. if(nrow(unique_index)!=nrow(data)) #..Ищем "неповторяющиеся" нули справа-налево unique_index <- from_the_end(zero_index) #Если все еще не равняется, то продолжаем алгоритм дальше if(nrow(unique_index)!=nrow(data)) { #Редукция матрицы по столбцам data <- data %>% apply(2,function(x) x-min(x)) %>% as.data.frame() zero_index <- which(data==0, arr.ind = T) unique_index <- from_the_beginning(zero_index) if(nrow(unique_index)!=nrow(data)) unique_index <- from_the_end(zero_index) if(nrow(unique_index)!=nrow(data)) { #"Вычеркиваем" строки и столбцы которые содержат нулевые элементы (ВАЖНО! количество вычеркиваний должно быть минимальным) index <- which(apply(data,1,function(x) length(x)>1)) index2 <- which(apply(data[-index,],2,function(x) length(x)>0)) #Среди оставшихся элементов ищем минимальный min_from_table <- min(data[-index,-index2]) #Вычитаем минимальный из оставшихся элементов data[-index,-index2] <- data[-index,-index2]-min_from_table #Прибавляем к элементам, расположенным на пересечении вычеркнутых строк и столбцов data <- data+min_from_table zero_index <- which(data==0, arr.ind = T) unique_index <- from_the_beginning(zero_index) if(nrow(unique_index)!=nrow(data)) unique_index <- from_the_end(zero_index) #Если все еще количество "неповторяющихся" нулей не равняется количеству строк в исходной таблице, то.. if(nrow(unique_index)!=nrow(data)) #..Повторяем весь алгоритм заново hungarian_algorithm(data,optim) else #Выводим индексы "неповторяющихся" нулей unique_index } else #Выводим индексы "неповторяющихся" нулей unique_index } else #Выводим индексы "неповторяющихся" нулей unique_index } #_________________________________________________________________________________ #__________Функция для нахождения "неповторяющихся" нулей слева-направо___________ from_the_beginning <- function(x,i=0,j=0,index = data.frame(row=numeric(),col=numeric())){ #Выбор индексов нулей, которые не лежат на строках i, и столбцах j find_zero <- x[(!x[,1] %in% i) & (!x[,2] %in% j),] if(length(find_zero)>2){ #Записываем индекс строки в вектор i <- c(i,as.vector(find_zero)) #Записываем индекс столбца в вектор j <- c(j,as.vector(find_zero)) #Записываем индексы в data frame (это и есть индексы уникальных нулей) index <- rbind(index,setNames(as.list(find_zero), names(index))) #Повторяем пока не пройдем по всем строкам и столбцам from_the_beginning(find_zero,i,j,index)} else rbind(index,find_zero) } #_________________________________________________________________________________ #__________Функция для нахождения "неповторяющихся" нулей справа-налево___________ from_the_end <- function(x,i=0,j=0,index = data.frame(row=numeric(),col=numeric())){ find_zero <- x[(!x[,1] %in% i) & (!x[,2] %in% j),] if(length(find_zero)>2){ i <- c(i,as.vector(find_zero)) j <- c(j,as.vector(find_zero)) index <- rbind(index,setNames(as.list(find_zero), names(index))) from_the_end(find_zero,i,j,index)} else rbind(index,find_zero) } #_________________________________________________________________________________


Результат выполнения программы:

Предположим, что у нас имеются $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$, и т.д.

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

Венгерский алгоритм

  1. В каждой строке матрицы назначения находим минимальный элемент и вычитаем его из всех элементов строки.
  2. В каждом столбце полученной матрицы находим минимальный элемент и вычитаем его из всех элементов столбца.
  3. Находим строку с одним нулем. Этот ноль заключаем в квадрат и называем отмеченным. В столбце, где стоит отмеченный ноль, все остальные нули зачеркиваем и в дальнейшем не рассматриваем. Этот шаг продолжаем, пока возможно.
  4. Находим столбец с одним нулем и этот ноль отмечаем. В строке, где стоит отмеченный ноль, все остальные нули зачеркиваются. Этот шаг продолжаем, пока возможно.
  5. Если после выполнения шагов $3$ и $4$ еще остаются неотмеченные нули, то отмечаем любой их них, а в строке и столбце, где стоит отмеченный ноль, все остальные нули зачеркиваются.
  6. Если каждая строка и каждый столбец матрицы содержит ровно один отмеченный ноль, то получено оптимальное решение. Каждый из отмеченных нулей прикрепляет поставщика к потребителю. В противном случаем проводим минимальное количество пересекающихся вертикальных и горизонтальных прямых через все нули. Среди не зачеркнутых этими прямыми чисел ищем минимум. Этот минимум вычитаем их всех не зачеркнутых чисел и прибавляем ко всем числам на пересечении прямых. К полученной матрице применяем вышеприведенный алгоритм, начиная с шага $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$ и к полученной матрице применяется вышеописанный алгоритм.

Задача о назначениях

Алгоритм решения задачи о назначении на узкие места

Задача о назначении на узкие места

ЛЕКЦИЯ 13. Задачи о назначении. Венгерский алгоритм

Эта задача решается описанным выше алгоритмом. Вот ее постановка.

Имеется n рабочих мест на некотором конвейере и n рабочих, которых нужно на эти рабочие места расставить; известна производительность c ij рабочего i на рабочем месте j . Тот факт, что при некотором распределении на рабочие места рабочий i k попадает на рабочее место j k можно описать следующей таблицей:

Имея способ s назначения на рабочие места, можно найти конкретную для этого способа минимальную производительность и заметить, что именно эта минимальная производительность и определяет скорость и производительность конвейера. То рабочее место, на котором реализуется минимальная производительность и называют узким местом в назначении.

Задача состоит в том, чтобы максимизировать

Шаг 0. Фиксируем матрицу производительностей и любое назначение на рабочие места. Пусть s - минимальная производительность при этом назначении. Построим рабочую таблицу тех же размеров, что и матрица C ; в клетку с номером (ij ) в этой таблице проставим символ «´», если ; в противном случае эту клетку оставим пустой.

Шаг 1. Рассматривая рабочую таблицу, построенную на предыдущем шагу, как рабочую таблицу в алгоритме для выбора наибольшего паросочетания в двудольном графе, найдем соответствующее наибольшее паросочетание. Если в нем окажется n ребер, то по ним восстанавливается новое назначение на рабочие места и с новой, более высокой, минимальной производительностью. Обозначим ее снова через s и вернемся к Шагу 0. Если же число ребер окажется меньше n , то имеющееся назначение на рабочие места уже оптимально.

Постановки задачи:

Пример 13.1 . Требуется распределить m работ (или исполнителей) по n станкам. Работа i (i =1,...,m ), выполняемая на станке j (j=1,...,n ), связана с затратами. Задача состоит в таком распределении работ по станкам (одна работа выполняется на одном станке), которое соответствует минимизации суммарных затрат c ij .

Пример 13.2. C= (c ij ) – стоимость производства детали i на станке j нужно найти распределение станков так чтобы суммарная стоимость производства была минимальной.

Пример 13.3. Транспортная задача. Заданы пункты производства товара, пункты потребления товара. Требуется определить оптимальное взаимно-однозначное соответствие между пунктами производства и пунктами потребления, исходя из матрицы стоимостей перевозок C между соответствующими пунктами (т.е. минимизировать суммарную стоимость перевозки).

Здесь работы представляют «исходные пункты», а станки – «пункты назначения». Предложение в каждом исходном пункте равно 1. Аналогично спрос в каждом пункте назначения равен 1. Стоимость «перевозки» (прикрепления) работы i к станку j равна c ij . Если какую-либо работу нельзя выполнять на некотором станке, то соответствующая стоимость берется равной очень большому числу.

Прежде чем решать такую задачу необходимо ликвидировать дисбаланс, добавив фиктивные работы или станки в зависимости от начальных условий. Поэтому без потери общности можно положить m = n .

Пусть = 0, если j -я работа не выполняется на i -м станке, = 1, если j -я работа выполняется на i -м станке. Таким образом, решение задачи может быть записано в виде двумерного массива . Допустимое решение называется назначением . Допустимое решение строится путем выбора ровно одного элемента в каждой строке матрицы и ровно одного элемента в каждом столбце этой матрицы.

Замечание 1. Для заданного значения n существует n ! допустимых решений.

Математическая модель задачи:

Минимизировать функцию , при ограничениях:

, (12.1)

, (12.2)

Ограничения (12.1) необходимы для того, чтобы каждая работа выполнялась ровно один раз. Ограничения (12.2) гарантируют, что каждому станку будет приписана ровно одна работа.

Пример 13.4. Для иллюстрации задачи о назначениях рассмотрим таблицу с тремя работами и тремя станками. Стоимость производства детали i на станке j :

Нужно найти распределение станков так чтобы суммарная стоимость производства была минимальной.

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

Замечание 2 . Оптимальное решение задачи не изменится, если из любой строки или столбца матрицы стоимостей вычесть произвольную постоянную величину.

Приведенное замечание 2 показывает, что если можно построить новую матрицу с нулевыми элементами и эти нулевые элементы или их подмножество соответствуют допустимому решению, то такое решение будет оптимальным.

.

Оптимальное назначение: , , , остальные , .

К сожалению, не всегда удается определить решение так просто. Для таких случаев рассмотрим следующий алгоритм.

Шаг 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 соответственно. Вычитая из элементов каждого столбца соответствующее минимальное значение, получим следующую матрицу.

ВЕНГЕРСКИЙ МЕТОД

Венгерский метод является одним из интереснейших и наиболее распространенных методов решения транспортных задач.

Рассмотрим сначала основные идеи венгерского метода на примере решения задачи выбора (задачи о назначениях), которая является частным случаем Т-задачи, а затем обобщим этот метод для произвольной Т-задачи.

Венгерский метод для задачи о назначениях

Постановка задачи. Предположим, что имеется различных работ и механизмов , каждый из которых может выполнять любую работу, но с неодинаковой эффективностью. Производительность механизма при выполнении работы обозначим , и = 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 штрихом, переходим ко второму этапу.

Предварительный этап .

Шаг 1 . При максимизации целевой функции С найти максимальный элемент и каждый элемент этого столбца вычесть из максимального. При минимизации целевой функции (суммы показателей эффективности назначений) в каждом столбце матрицы С найти минимальный элемент и вычесть его из каждого элемента этого столбца.

С с неотрицательными элементами. В каждом столбце матрицы С имеется, по крайней мере, один нуль.

Шаг 2 . В каждой строке матрицы С найти минимальный элемент и вычесть его из каждого элемента этой строки.

В результате образуется матрица С 0 с неотрицательными элементами. В каждом столбце и каждой строке матрицы С 0 имеется, по крайней мере, по одному нулю.

Шаг 3 . Отме­тить произвольный нуль в первом столбце звездочкой. Начиная со второго столбца просматривать каждый столбец матрицы С 0 и отмечать в нем звездочкой нуль, расположенный в строке, где нет нуля со звездочкой. В каждом столбце можно отметить звездочкой только один нуль. Очевидно, что нули матрицы С 0 , отмеченные звездочкой, являются по построению независимыми. На этом предварительный этап заканчи­вается.

( k + 1)-я итерация . Допустим, что k -я итерация уже проведена и в результате получена матрица С k . Если в матрице С k имеется ровно п нулей со звездочкой, то процесс решения заканчивается. Если же число нулей со звездочкой меньше п , то переходим к (k + 1)-й ите­рации.

Каждая итерация начинается первым и заканчивается вторым эта­пом. Между ними может несколько раз проводиться пара этапов: третий – первый . Перед началом итерации знаком «+» выделяют столбцы матрицы С k , которые содержат нули со звездочкой .

Первый этап . Просмотреть невыделенные столбцы матри­цы С k . Если среди них не окажется нулевых элементов, то перейти к третьему этапу .

Если же невыделенный нуль матрицы С k обнаружен, то возможен один из двух случаев:

    эта строка не содержит нуля со звездочкой.

В первом случае невыделенный нуль отметить штрихом и выделить строку , в которой он содержится, постановкой справа от нее зна­ка «+». Затем уничтожить знак «+», обводя его кружком над тем столбцом , на пересечении которого с данной выделенной строкой со­держится нуль со звездочкой.

 Если такой нуль найден и он единственный в столбце, то отметить его штрихом и выделить строку (строки), содержащую такой нуль (нули), знаком «+». Затем просмотреть эту строку (строки), отыскивая в них нуль со звез­дочкой.

 Если такой нуль в столбце найден, но он не единственный в столбце, то из этих нулей следует выбрать:

    в первую очередь такой нуль, в одной строке с которым, нет 0*;

    во вторую очередь такой нуль, в одной строке с которым имеется 0*, но в одном столбце с этим 0* имеется невыделенный нуль;

    в последнюю очередь такой нуль, в одной строке с которым имеется 0*, но в одном столбце с этим 0* отсутствует невыделенный нуль;

Этот процесс законечное число шагов заканчивается одним изследующих исходов:

Исход 1 . Все нули матрицы С k выделены, т. е. находятся в выделенных строках или столбцах. В этом случае перейти к третьему этапу ;

Исход 2 . Имеется невыделенный нуль в строке, где нет нуля со звездочкой. Тогда перейти ко второму этапу , отметив последний по порядку нуль штрихом .

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

Второй этап . Построить следующую цепочку из элементов матрицы С k : исходный нуль со штрихом, нуль со звездочкой, располо­женный в одном столбце с первым, нуль со штрихом, расположенный в одной строке с предшествующим нулем со звездочкой, и т. д. Итак, цепочка образуется передвижением от 0" к 0* по столбцу , от 0* к 0" по строке и т. д.

Можно доказать, что описанный алгоритм построения цепочки однозначен и конечен. При этом цепочка всегда начинается и закан­чивается нулем со штрихом . Далее над элементами цепочки, стоящими на нечетных местах (0"), поставить звездочки, уничтожая их над четными элементами (0*). Затем уничтожить все штрихи над элементами мат­рицы С k и знаки «+». При этом количество независимых нулей будет увеличено на единицу . (k + 1)-я итерация закончена .

Третий этап . К этому этапу следует переходить после первого этапа в случае, если все нули матрицы С k выделены , т. е. находятся в выделенных строках или столбцах. В таком случае среди невыделенных элементов матрицы С k выбрать минимальный элемент и обозначить его h > 0.

    вычесть h из всех элементов матрицы С k , расположенных в невыделенных стро­ках , и

    прибавить h ко всем элементам матрицы С k , расположенным в выделенных столбцах .

В результате получается новая матрица , эквивалентнаяС k .

Поскольку среди невыделенных элементов матрицы
появятся новые нули (согласно определению), следует перейти к первому этапу, а вместо матрицыС k рассматривать матрицу
.

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

В первом случае после проведения второго этапа итерация закан­чивается .

Во втором случае после проведения третьего этапа получается матрица
~
~С k . В матрице
появятся невыделенные нули, и всю последовательность операций, начиная с первого этапа, надо повторить.После конечного числа повторений очередной первый этап обязательно закончится переходом на второй этап , при выполнении которого количество независимых нулей увеличится на единицу, а после выполнения которого (k + 1)-я итерация за­канчивается .

Пример 9. Решим венгерским методом задачу:

На боевом надводном корабле имеется 5 зенитных огневых средств (ЗОС). На корабль совершается одновременный налет авиации противника в количестве 5 единиц. Поражающий потенциал каждого i –го ЗОС по j –му летательному аппарату противника равен (количество потенциально уничтожаемыхj –х летательных аппаратов за время атаки НК одним ЛА). Предполагается, что любое ЗОС может обстрелять любую цель.

Распределить ЗОС по ВЦ таким образом, чтобы суммарный поражающий потенциал был максимален, при условиях:

    на одну ВЦ может быть назначено только одно ЗОС;

    все цели должны быть обстреляны ЗОС.

Решение :

Предварительный этап .



Первая итерация .

Первый этап .

+ +


В

+ +

торой этап .


Вторая итерация .

П

+ +

ервый этап .


Поскольку все нули матрицы С 1 выделены следует перейти к третьему этапу.

Третий этап .

+ +

+ +

h =1 

Первый этап .

Второй этап .


В результате решения задачи о назначениях венгерским методом получили, что последовательность
=4,
=4,
=3,
=2,
=2 дает максимальное значение целевой функции=15. Из этого следует, что для отражения атаки СВН противника наиболее эффективным будет следующий вариант назначения ЗОС на ВЦ:

Упражнения .

    Найти опорный план транспортной задачи методами «Северо-западного угла», «Наименьшей стоимости», «Фогеля»:

a i

Заявки b j

    Решить транспортную задачу из задания 1 распределительным методом.

    Решить транспортную задачу из задания 1 методом потенциалов.

    Венгерским методом решить задачу назначения при поиске максимума:

    Венгерским методом решить задачу назначения при поиске минимума:

Контрольные вопросы :

    Дайте формулировку транспортной задачи линейного программирования.

    Чем отличается сбалансированная транспортная задача от не сбалансированной транспортной задачи?

    Сколько в сбалансированной транспортной задаче должно быть базисных переменных?

    Дайте определение понятиям: план, допустимый план, опорный допустимый план, оптимальный план, используемым при решении транспортной задачи.

    Сформулируйте алгоритм нахождения опорного плана методом северо-западного угла.

    Сформулируйте алгоритм нахождения опорного плана методом наименьшей стоимости.

    Сформулируйте алгоритм нахождения опорного плана методом Фогеля.

    Сформулируйте алгоритм нахождения оптимального плана распределительным методом.

    Сформулируйте алгоритм нахождения оптимального плана методом потенциалов.

    Дайте формулировку задачи о назначениях.

    Каким образом в задаче о назначениях при разных количествах объектов и средств формируется квадратная матрица назначений?

    Сформулируйте алгоритм решения задачи о назначениях Венгерским методом.

    Каким образом на предварительном этапе формируется исходная матрица назначений при максимизации целевой функции?

    Каким образом на предварительном этапе формируется исходная матрица назначений при минимизации целевой функции?

    В чем заключается суть первого этапа решения задачи о назначениях Венгерским методом?

    В чем заключается суть второго этапа решения задачи о назначениях Венгерским методом?

    В чем заключается суть третьего этапа решения задачи о назначениях Венгерским методом?

    Сколько первых, вторых и третьих этапов может находиться в одной итерации решения задачи о назначениях Венгерским методом? Какова последовательность выполнения этапов в итерации?

    Сколько независимых нулей должно быть в матрице назначений для принятия решения о том, что оптимальное назначение средств на объекты найдено?