Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4 основи програмування книга.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.77 Mб
Скачать

10.6.* Метод “розділяй і володій”

Один з найбільш відомих методів проектування ефективних алгоритмів – метод “розділяй і володій” полягає у зведенні задачі, що розв’язується, до рішення однієї або кількох більш простих задач.

Якщо спрощення задачі полягає в зменшенні її параметрів, таке зведення дає рекурсивний опис алгоритму. Зокрема, зменшення параметра може означати зменшення кількості даних, з якими працює алгоритм.

Характерна ознака методу – зведення до декількох задач рівних за складністю підзадач. Ефективність отриманого алгоритму залежить від, по-перше, від кількості дій, затрачених на зведення задачі до підзадач, по-друге – від балансу складностей підзадач.

Класичний приклад застосування методу – бінарний пошук у впорядкованому масиві. Масив розбивається на дві рівні частини. Використовуючи потім два порівняння, алгоритм або знаходить елемент, або визначає ту половину, в якій його треба шукати – тобто зводить задачу розміром n до задачі розміром n/2. Цей же прийом використовується в алгоритмах Хоара сортування і пошуку, в алгоритмі піднесення числа в натуральну степінь, у деяких інших раніше сформульованих задачах. Розглянемо відомий розв’язок задачі пошуку мінімального і максимального елемента в масиві.

Нехай A[1..n] – числовий масив. Треба знайти Max(A) і Min(A). Припустимо, що n = 2 k. Таке припущення дає можливість завжди ділити масиви, отримані навпіл.

Опишемо основну процедуру MaxMin. Нехай S – деяка множина і |S| = m. Розіб’ємо S на рівні за числом елементів частини: S = S1  S2, Знайдемо Max1, Min1 як результат MaxMin(S1) і Max2, Min2 як результат MaxMin(S2).

Потім Max := Max(Max1, Max2); Min := Min(Min1, Min2);

Procedure MaxMin(L, R : Integer Var Max, Min : Real);

Var

Max1, Min1, Max2, Min2 : Real;

Begin { L, R - межі індексів масиву A }

If R - L = 1

then If A[L] > A[R] { вибір Маx, Min за одне порівняння}

then begin

Max := A[l];

Min := A[R]

end

else begin

Max := A[R];

Min := A[L]

end

else begin

C := (R + L - 1) div 2;

MaxMin(L, C, Max1, Min1);

MaxMin(C+1, R, Max2, Min2);

If Max1 > Max2

then Max := Max1

else Max := Max2;

If Min1 < Min2

then Min := Min1

else Min := Min2

end

End;

Нехай С(n) - оцінка складності процедури MaxMin в термінах порівнянь. Тоді, очевидно

С(2) = 1,

C(n) = 2 C(n/2) + 2 при n > 2

Звідси С(n) = 2 (n/4 + n/8 + ... + 1) + n/2 = 2(n/2 - 1) + n/2;

C(n) = 3/2 n - 2

Для порівняння відзначимо, що алгоритм пошуку Max і Min методом послідовного перегляду масиву потребує 2n-2 порівнянь. Таким чином, застосування метода “розділяй і володій” зменшило часову складність задачі в фіксоване число раз. Зрозуміло, істинна причина поліпшення – не в застосуванні рекурсії, а в тому, що максимуми і мінімуми двох елементів масиву, що стоять поруч, відшукуються за одне порівняння! Метод дозволив просто і природно описати обчислення.

Довжина ланцюжка рекурсивних викликів в алгоритмі дорівнює log2 n -1, і в кожній копії використовується 4 локальних змінних. Тому алгоритм використовує допоміжну пам’ять об’єму O(log2 n), що розподіляється динамічно. Це – плата за економію часу.