Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PEREBOR_lec.doc
Скачиваний:
1
Добавлен:
05.09.2019
Размер:
97.28 Кб
Скачать

8

7. Переборные задачи

На практике неоднократно встречаются задачи, где требуется обработать (пере­брать) все элементы некоторого конечного множества. В простейших слу­чаях элемент множества можно представить числом. При­мер такой задачи — по­иск заданного числа в одномерном массиве. Здесь для указа­ния элемента массива достаточно задать его индекс.

Более слож­ные случаи, когда элементы интересую­щего нас множества сами имеют некото­рую структуру. (Именно такие задачи обычно относят к переборным.) Во многих случаях элементы множества естест­венно записывать в виде последовательно­сти чисел фиксированного или перемен­ного размера. Очень многие переборные задачи можно свести к перебору последова­тельно­стей.

В некоторых задачах (см. например, задачу о коммивоя­жере в главе 1) требу­ется генерировать последовательности путем всевозмож­ных перестановок компо­нент некоторой заданной последовательности фиксирован­ной длины. Правила генерации последовательностей могут меняться в за­висимости от задачи:

  • случайным образом,

  • в лексикографическом порядке,

  • пу­тем различных сочетаний компонент

  • и т. п.

Примером такой задачи (в действительно­сти она эквивалентна задаче пере­бора последовательностей) явля­ется задача прохождения (обхода) деревьев. Де­рево — это граф без циклов, в кото­ром выделена одна вершина, называемая кор­нем. Для каждой вершины де­рева существует единственный путь в нее из корня. Задача состоит в том, чтобы «обойти» все вершины дерева. Если перенумеровать все ребра, выходящие из каж­дой вершины, то путь из корня, однозначно сопоставляе­мый каждой вершине, можно будет в свою очередь задать с помощью по­следовательности номеров проходи­мых ребер. Лексикографический порядок перебора последовательностей отвечает способу прохождения дерева, известному как перебор в глубину. Нахо­дясь в какой-либо вершине, мы сначала пытаемся пойти «в глубину», т. е. уда­литься от корня; если это невозможно, то мы возвраща­емся назад и пытаемся пойти в глубину по следующему ребру.

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

7.1. Полный перебор.

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

Для решения переборных задач обычно используются разновидности следую­щей схемы программы:

Схема 1

Var x :элемент множества;

x := первый элемент;

обработать x; While x<> последний элемент Do Begin x: =следующий за x;

обработать x;

End;

Иногда удается добавить к множеству еще один, фиктивный элемент, не подле­жащий обработке, который располагается перед первым обрабатываемым элементом, либо вслед за последним В этом случае обработку первого элемента можно выполнить наряду со всеми в цикле:

Схема 2 Схема 3

x:=фиктивный элемент; x:=первый элемент;

Repeat Repeat

x:=следующий за x; обработать x;

обработать x; x:=следующий за x;

Until x = последний элемент; Until x = фиктивный элемент;

Для конкретизации этих схем необходимо ответить на два вопроса.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]