Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
TA / Конспект лекций по теор алгоритм / Конспект лекций / ЭФФЕКТИВНОСТЬ АЛГОРИТМОВ..doc
Скачиваний:
74
Добавлен:
14.04.2015
Размер:
356.35 Кб
Скачать

4.2.2. Прием “разделяй и властвуй”.

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

Рассмотрим для примера задачу нахождения наибольшего (MAXEL) и наименьшего (MINEL) элементов массива S, содержащего n элементов. Для простоты будем считать, что n есть степень числа 2. Очевидно, что MAXEL, MINEL следует искать по отдельности. Например, следующая процедура находит MAXEL множества S, производя n-1 сравнений его элементов :

begin

MAXEL  произвольный элемент из S;

for все другие элементы из S do

if x> MAXEL then MAXEL  x

end

Аналогично можно найти MINEL из остальных n-1 элементов, произведя n-2 сравнений. Итак, для нахождения максимального и минимального элементов при n2 потребуется 2n-3 сравнений.

Применяя прием "разделяй и властвуй", мы разбили бы множество S на два подмножества S1 и S2 по n/2 элементов в каждом. Тогда описанный выше алгоритм нашел бы MAXEL и MINEL в каждой из двух половин с помощью рекурсии. MAXEL и MINEL множества S можно было бы определить, произведя еще два сравнения - наибольших элементов в S1 и S2 и наименьших элементов в них.

Алгоритм 4.3. Нахождение наибольшего и наименьшего элементов множества.

ВХОД. Множество S из n элементов, где n степень числа 2, n2.

ВЫХОД. Наибольший(MAXEL) и наименьший(MINEL) элементы множества S.

МЕТОД. К множеству S применяется рекурсивная процедура MAXMIN. Она имеет один аргумент, представляющий собой множество S, такое, что |S|=2k при некотором k1, и вырабатывает пару (a,b), где a - MAXEL, b - MINEL.

Процедура MAXMIN приведена ниже

procedure MAXMIN(S)

1. if |S|=2 then

begin

2. пусть s={a,b};

3. return ( MAXEL(a,b), MINEL(a,b) )

end

else

begin

4. разбить S на два равных подмножества S1 и S2

5. (max1, min1)MAXMIN(S1);

6. (max2, min2)MAXMIN(S2);

7. return (MAXEL(max1, max2),MINEL(min1, min2) )

end;

Пусть Т(n) - число сравнений элементов множества S, которые надо произвести в процедуре MAXMIN, чтобы найти наибольший и наименьший элементы n-элементного множества. Ясно, что Т(2)=1. Если n>2, то Т(n) - общее число сравнений, произведенных в двух вызовах процедуры MAXMIN (строки 5 и 6), работающей на множестве размера n/2 и еще два сравнения в строке 7. Таким образом,

Решением рекуррентных уравнений (4.18) служит функция Т(n)=3n/2 - 2, что можно доказать индукцией по n.

Можно показать, что для одновременного поиска наибольшего и наименьшего элементов n-элементного множества надо выполнить не менее 3n/2 - 2 сравнений его элементов. Следовательно,алгоритм 4.3 оптимален в смысле числа сравнений между элементами из S, когда n есть степень числа 2.

Временная сложность процедуры определяется числом и размером подзадач и в меньшей степени работой, необходимой для разбиения данной задачи на подзадачи. Так как рекуррентные уравнения вида (4.18) часто возникают при анализе рекурсивных алгоритмов типа “разделяй и властвуй”, рассмотрим решение таких уравнений в общем виде.

Теорема 4.1 Пусть a, b, c - неотрицательные постоянные. Решением рекуррентных уравнений вида

где n- степень числа с,имеет вид

Из теоремы вытекает, что разбиение задачи размера n (за линейное время) на две подзадачи размера n/2 дает алгоритм сложности О(nLog2n). Если бы подзадач было 3, 4 или 16, то получился бы алгоритм сложности порядка, n2 или n4 соответственно. С другой стороны, разбиение задачи на 4 подзадачи размера n/4 дает сложность порядка nlog2n, а на 9 и 16 - порядка и n2 соответственно.

Если n не является степенью числа С, то обычно можно вложить задачу размера n в задачу размера n', где n' - наименьшая степень числа С, большая n. Поэтому порядки роста, приведенные в теореме 4.1, сохраняются для любого n. На практике часто можно разработать рекурсивные алгоритмы, разбивающие задачи произвольного размера на С равных частей, где С велико, насколько возможно. Эти алгоритмы, как правило, эффективнее(на постоянный множитель) тех, которые получаются путем представления размера входа в виде ближайшей сверху степени числа С.