Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
nestudent.ru_46905.doc
Скачиваний:
22
Добавлен:
12.09.2019
Размер:
2.07 Mб
Скачать

Анализ времени выполнения программы

Чтобы проанализировать время выполнения этой процедуры, вы можете определить число вызовов процедуры Hilbert. При каждой рекурсии она вызывает себя четыре раза. Если T(N) — это число вызовов процедуры, когда она вызывается с глубиной рекурсии N, то:

T(1) = 1

T(N) = 1 + 4 * T(N - 1) для N > 1.

Если раскрыть определение T(N), получим:

T(N) = 1 + 4 * T(N - 1)

= 1 + 4 *(1 + 4 * T(N - 2))

= 1 + 4 + 16 * T(N - 2)

= 1 + 4 + 16 * (1 + 4 * T(N - 3))

= 1 + 4 + 16 + 64 * T(N - 3)

= ...

= 40 + 41 + 42 + 43 + ... + 4K * T(N - K)

Раскрыв это уравнение до тех пор, пока не будет выполнено условие остановки рекурсии T(1)=1, получим:

T(N) = 40 + 41 + 42 + 43 + ... + 4N-1

Это уравнение можно упростить, воспользовавшись соотношением:

X0 + X1 + X2 + X3 + ... + XM = (XM+1 - 1) / (X - 1)

После преобразования, уравнение приводится к виду:

T(N) = (4(N-1)+1 - 1) / (4 - 1)

= (4N - 1) / 3

=====90

С точностью до постоянных, эта процедура выполняется за время порядка O(4N). В табл. 5.5 приведены несколько первых значений функции времени выполнения. Если вы внимательно посмотрите на эти числа, то увидите, что они соответствуют рекурсивному определению.

Этот алгоритм является типичным примером рекурсивного алгоритма, который выполняется за время порядка O(CN), где C — некоторая постоянная. При каждом вызове подпрограммы Hilbert, она увеличивает размерность задачи в 4 раза. В общем случае, если при каждом выполнении некоторого числа шагов алгоритма размер задачи увеличивается не менее, чем в C раз, то время выполнения алгоритма будет порядка O(CN).

Это поведение противоположно поведению алгоритма поиска наибольшего общего делителя. Процедура GCD уменьшает размерность задачи в 2 раза при каждом втором своем вызове, и поэтому время ее выполнения порядка O(log(N)). Процедура построения кривых Гильберта увеличивает размер задачи в 4 раза при каждом своем вызове, поэтому время ее выполнения порядка O(4N).

Функция (4N-1)/3 — это экспоненциальная функция, которая растет очень быстро. Фактически, она растет настолько быстро, что вы можете предположить, что это не слишком эффективный алгоритм. В действительности работа этого алгоритма занимает много времени, но есть две причины, по которым это не так уж и плохо.

Во-первых, ни один алгоритм для построения кривых Гильберта не может быть намного быстрее. Кривые Гильберта содержат множество отрезков линий, и любой рисующий их алгоритм будет требовать достаточно много времени. При каждом вызове процедуры Hilbert, она рисует три линии. Пусть L(N) — суммарное число линий, из которых состоит кривая Гильберта порядка N. Тогда L(N) = 3 * T(N) = 4N - 1, поэтому L(N) также порядка O(4N). Любой алгоритм, рисующий кривые Гильберта, должен вывести O(4N) линий, выполнив при этом O(4N) шагов. Существуют другие алгоритмы построения кривых Гильберта, но они занимают почти столько же времени, сколько и этот алгоритм.

@Таблица 5.5. Число рекурсивных вызовов подпрограммы Hilbert

=====91

Второй факт, который показывает, что этот алгоритм не так уж плох, заключается в том, что кривые Гильберта 9 порядка содержат так много линий, что экран большинства компьютерных мониторов при этом оказывается полностью закрашенным. Это неудивительно, так как эта кривая содержит 262.143 отрезков линий. Это означает, что вам вероятно никогда не понадобится выводить на экран кривые Гильберта 9 или более высоких порядков. На каком‑то порядке вы столкнетесь с ограничениями языка Visual Basic и вашего компьютера, но, скорее всего, вы еще раньше будете ограничены максимальным разрешением экрана.

Программа Hilbert, показанная на рис. 5.4, использует этот рекурсивный алгоритм для рисования кривых Гильберта. При выполнении программы не задавайте слишком большую глубину рекурсии (больше 6) до тех пор, пока вы не определите, насколько быстро выполняется эта программа на вашем компьютере.

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