Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы на графах, Окулов.doc
Скачиваний:
46
Добавлен:
14.11.2018
Размер:
4.15 Mб
Скачать

3.10. Методы приближенного решения задачи коммивояжера

3.10.1. Метод локальной оптимизации

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

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

Шаг 2. Пока происходит улучшение решения, выполнять следующий шаг, иначе перейти на шаг 4.

Шаг 3. Для всех пар номеров городов i,j, удовлетворяющих неравенству (1i<jn), проверить:

di-1,i +di,j +dj,j+1 >di-1,j +dj,i +di,j+1 для смежных городов, то есть j=i+1

di-1,i +di,i+1 +dj-1,j +dj,j+1 >di-1,j +dj,i+1 +dj-1,i +di,j+1 для несмежных городов.

Примечание. На рисунке даны графические иллюстрации первого и второго неравенств. “Жирными” линиями обозначены участки старых маршрутов, “тонкими” - новых.

Если одно из неравенств выполняется, то найдено лучшее решение. Следует откорректировать ранее найденное решение и вернуться на шаг 2.

Шаг 4. Закончить работу алгоритма.

Для реализации логики (из рассмотренных в предыдущем алгоритме структур данных) достаточно матрицы расстояний (А) и массива для хранения пути коммивояжера (Way). Вид общей логики:

begin

init;{Ввод из файла матрицы расстояний, инициализация глобальных переменных}

one_way;{Поиск первого варианта пути коммивояжера}

local;{Локальная оптимизация}

out;{Вывод результата}

end.

Примечание. Владение технологиями “сверху вниз” и “снизу вверх” - необходимые составляющие структурной парадигмы мышления.

Продолжим уточнение логики. Работа процедур init, one_way, out достаточно очевидна. Естественным приемом является вынесение ее в самостоятельную часть работы школьников на занятии. Нам необходимо уточнить процедуру local. Работаем не с частностями, а на содержательном уровне. Предположим, что мы имеем функции best1 и best2, их параметры - индексы элементов массива way, определяющих номера городов в пути коммивояжера, а выход естественный - истина или ложь, в зависимости от того, выполняются неравенства или нет. Рассуждаем дальше. Если неравенство выполняется, то нам необходимо изменить путь (соответствующие элементы массива way). Пока не будем заниматься деталями. Пусть эту работу выполняет процедура swap, ее параметры - индексы элементов массива way). Эта процедура, вероятно, должна сообщать о том, что она «что-то изменила», ибо нам необходимо продолжать работу до тех пор, пока что-то меняется, происходят улучшения. Итак, логика процедуры local.

Procedure local;

var i,j:integer; change:boolean;

<здесь функции best1 и best2, а также процедура swap>;

begin

repeat

change:=false;

for i:=1 to n-1 do

for j:=i+1 to n do

if i=j+1 then begin if best1(i,j) then swap(i,j);end

else if (i=1) and (j=n) then begin if best1(i,j) then swap(i,j); end{Об этой проверке лучше первоначально умолчать, чтобы было о чем спросить, «если совсем будет плохо» - все понимают и нет вопросов}

else if best2(i,j) then swap(i,j);

until not(change);

end.