Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[4]

Время работы в худшем случае и в среднем

Итак, мы видим, что время работы в худшем случае и в лучшем случае могут сильно различаться. Большей частью нас будет интересовать время работы в худшем случае (worst-case running time), которое определяется как максимальное время работы для входов данного размера. Почему? Вот несколько причин.

•Зная время работы в худшем случае, мы можем гарантировать, что выполнение алгоритма закончится за некоторое время, даже не зная, какой именно вход (данного размера) попадётся.

•На практике «плохие» входы (для которых время работы близко к максимуму) могут часто попадаться. Например, для базы данных плохим запросом может быть поиск отсутствующего элемента (довольно частая ситуация).

•Время работы в среднем может быть довольно близко к времени работы в худшем случае. Пусть, например, мы сортируем случайно расположенные га чисел в помощью процедуры Insertion-Sort. Сколько раз придётся выполнить цикл в строках 5-8? В среднем около половины элементов массива А[1.. j - 1] болье A[j], так что tj в среднем можно считать равным j/2, и время Т(п) квадратично зависит от га.

В некоторых случаях нас будет интересовать также среднее время работы (average-case running time, expexted running time) алгоритма на входах данной длины. Конечно, эта величина зависит от выбранного распределения вероятностей (обычно рассматривается равномерное распределение), и на практике реальное распределение входов может оказаться совсем другим. (Иногда его можно преобразовать в равномерное, используя датчик случайных чисел.)

Порядок роста

Наш анализ времени работы процедуры Insertion-Sort был основан на нескольких упрощающих предположениях. Сначала мы предположили, что время выполнения г-ж строки постоянно и равно С{. Затем мы огрубили оценку до an2 А-ЬпА-с. Сейчас мы пойдём ещё дальше и скажем, что время работы в худшем случае имеет порядок роста (rate of growth, order of growth) га2, отбрасывая члены меньших порядков (линейные) и не интересуясь коэффициентом при га2. Это записывают так: Т(п) = 0(га2) (подробное объяснение обозначений мы отложим до следующей главы).

Алгоритм с меньшим порядком роста времени работы обычно предпочтителен: если, скажем, один алгоритм имеет время работы 0(га2), а другой - 0(га3), то первый более эффективен (по крайней мере для достаточно длинных входов; будут ли реальные входы таковыми - другой вопрос).


Упражнения

1.2-1 Будем сортировать массив из га элементов так: просмотрим его и найдём минимальный элемент, который скопируем в первую ячейку другого массива. Затем просмотрим его снова и найдём следующий элемент, и так далее. Такой способ сортировки можно назвать сортировкой выбором (selection sort). Запишите этот алгоритм с помощью псевдокода. Укажите время его работы в лучшем и худшем случаях, используя О-обозначения.

1.2-2 Вернёмся к алгоритму линейного поиска (упр. 1.1-3).

Сколько сравнений потребуется в среднем этому алгоритму, если искомым элементом может быть любой элемент массива (с одинаковой вероятностью)? Каково время работы в худшем случае и в среднем? Как записать эти времена с помощью О-обозначений?

1.2-3 Дана последовательность чисел х±, Х2, , хп. Покажите, что за время ©(га log га) можно определить, есть ли в этой последовательности два одинаковых числа.

1.2-4 Даны коэффициенты ао, а\,..., ап-\ многочлена; требуется найти его значение в заданной точке х. Опишите естественный алгоритм, требующий времени ©(га2). Как выполнить вычисления за время О (га), не используя дополнительного массива? Используйте «схему Горнера»:

п-1

агхг = (... {an-ix + а„ 2)ж + ... + at)x + а0.

8 = 0

1.2-5 Как записать выражение га3/1000 - 100га2 - 100га + 3 с помощью О-обозначений?

1.2-6 Почти любой алгоритм можно немного изменить, радикально уменьшив время его работы в лучшем случае. Как?

1.3. Построение алгоритмов

Есть много стандартных приёмов, используемых при построении алгоритмов. Сортировка вставками является примером алгоритма, действующего по шагам (incremental approach): мы добавляем элементы один за другим к отсортированной части массива.

В этом разделе мы покажем в действии другой подход, который называют «разделяй и властвуй» (divide-and-conquer approach), и построим с его помощью значительно более быстрый алгоритм сортировки.


1.3.1. Принцип «разделяй и властвуй»

Многие алгоритмы по природе рекурсивны (recursive algorithms): решая некоторую задачу, они вызывают самих себя для решения её подзадач. Идея метода «разделяй и властвуй» состоит как раз в этом. Сначала задача разбивается на несколько подзадач меньшего размера. Затем эти задачи решаются (с помощью рекурсивного вызова- или непосредственно, если размер достаточно мал). Наконец, их решения комбинируются и получается решение исходной задачи.

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

Нетривиальной частью является соединение двух упорядоченных массивов в один. Оно выполняется с помощью вспомогательной процедуры Merge (А, р, q, г). Параметрами этой процедуры являются массив А и числа р, q, г, указывающие границы сливаемых участков. Процедура предполагает, что р q < г и что участки А\р. .q] и A[q + 1. .г] уже отсортированы, и сливает (merges) их в один участок А[р..г].

Мы оставляем подробную разработку этой процедуры читателю (упр. 1.3-2), но довольно ясно, что время работы процедуры Merge есть ©(га), где га - общая длина сливаемых участков (га = г - Это легко объяснить на картах. Пусть мы имеем две стопки карт, и в каждой карты идут сверху вниз в возрастающем порядке. Как сделать из них одну? На каждом шаге мы берём меньшую из двух верхних карт и кладём её (рубашкой вверх) в результирующую стопку. Когда одна из исходных стопок становится пустой, мы добавляем все оставшиеся карты второй стопки к результирующей стопке. Ясно, что каждый шаг требует ограниченного числа действий, и общее число действий есть ©(га).

Теперь напишем процедуру сортировки слиянием Merge-Sort(A,р, г), которая сортирует участок А[р..г] массива А, не меняя остальную часть массива. При р г участок содержит максимум один элемент, и тем самым уже отсортирован. В противном случае мы отыскиваем число q, которое делит участок на две примерно равные части А[р..д] (содержит [га/2] элементов) и A[q + l..r] (содержит [п/2\ элементов). Здесь через [ж] мы обозначаем целую часть ж (наибольшее целое число, меньшее или равное ж), а через [ж] - наименьшее целое число, большее или равное ж.



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196] [стр.197] [стр.198] [стр.199] [стр.200] [стр.201] [стр.202] [стр.203] [стр.204] [стр.205] [стр.206] [стр.207] [стр.208] [стр.209] [стр.210] [стр.211] [стр.212] [стр.213] [стр.214] [стр.215] [стр.216] [стр.217] [стр.218] [стр.219] [стр.220] [стр.221] [стр.222] [стр.223] [стр.224] [стр.225] [стр.226] [стр.227] [стр.228] [стр.229] [стр.230] [стр.231] [стр.232] [стр.233] [стр.234] [стр.235] [стр.236] [стр.237] [стр.238] [стр.239] [стр.240] [стр.241] [стр.242] [стр.243] [стр.244] [стр.245] [стр.246] [стр.247] [стр.248] [стр.249] [стр.250] [стр.251] [стр.252] [стр.253] [стр.254] [стр.255] [стр.256] [стр.257] [стр.258] [стр.259] [стр.260] [стр.261] [стр.262] [стр.263] [стр.264] [стр.265] [стр.266] [стр.267] [стр.268] [стр.269] [стр.270] [стр.271] [стр.272] [стр.273] [стр.274] [стр.275] [стр.276] [стр.277] [стр.278] [стр.279] [стр.280] [стр.281] [стр.282] [стр.283] [стр.284] [стр.285] [стр.286] [стр.287] [стр.288] [стр.289] [стр.290] [стр.291] [стр.292] [стр.293] [стр.294]