Методички / Лаб_4_Алгоритмы поиска
.docxЛабораторная работа 4: Алгоритмы поиска
Цель работы:
Изучить основные алгоритмы поиска в последовательностях, реализовать их на языке Python и сравнить их поведение на разных типах данных.
Задание 1. Реализация алгоритмов поиска
Необходимо реализовать на языке Python четыре алгоритма поиска:
модифицированный линейный поиск;
бинарный поиск;
интерполяционный поиск;
экспоненциальный поиск.
Для каждого алгоритма программа должна принимать массив и искомое значение, выполнять поиск и возвращать индекс найденного элемента. Если элемент в массиве отсутствует, программа должна вернуть специальное значение, указывающее на неуспешный поиск.
При выполнении задания необходимо учитывать особенности применения каждого метода. Модифицированный линейный поиск должен быть реализован с использованием барьерного элемента. Бинарный, интерполяционный и экспоненциальный поиск необходимо применять только к отсортированным массивам. Для проверки корректности работы следует выполнить тестирование на нескольких наборах данных, включающих как успешный поиск, так и случай отсутствия элемента в массиве.
После выполнения необходимо кратко объяснить принцип работы каждого алгоритма, указать, какие алгоритмы можно применять к неотсортированным данным, а какие требуют предварительной сортировки, и сделать вывод о различии между универсальными и специализированными методами поиска.
Задание 2. Исследование интерполяционного поиска на массивах с различным распределением значений
Известно, что эффективность интерполяционного поиска сильно зависит от того, как распределены значения элементов в отсортированном массиве. Если значения расположены достаточно равномерно, алгоритм может работать быстрее бинарного поиска. Если же распределение сильно неравномерно, его преимущество может исчезнуть.
Необходимо исследовать работу интерполяционного поиска на массивах одинакового размера, но с различным распределением значений. Требуется рассмотреть следующие случаи:
равномерное распределение;
квадратичное распределение;
экспоненциальное распределение;
случайные отсортированные данные с перекосами.
Для каждого вида распределения необходимо сгенерировать массив, выполнить серию поисков, измерить время работы интерполяционного поиска и при необходимости дополнительно сравнить его с бинарным поиском. Результаты исследования следует представить в виде таблицы или графика.
После выполнения задания необходимо объяснить, почему интерполяционный поиск работает особенно эффективно на равномерно распределённых данных, по какой причине его эффективность ухудшается при неравномерном распределении значений и чем это объясняется с точки зрения предсказания предполагаемой позиции искомого элемента.
Задание 3. Исследование порога, при котором выгоднее сортировать массив и использовать бинарный поиск
Предположим, что имеется неотсортированный массив размера N, и по нему требуется выполнить K поисковых запросов. В такой ситуации возникает вопрос: что выгоднее каждый раз выполнять линейный поиск в исходном массиве или сначала один раз отсортировать массив, а затем выполнять бинарный поиск?
Необходимо провести вычислительное исследование для фиксированного размера массива N. Для разных значений K требуется:
выполнить серию из K поисков линейным методом в неотсортированном массиве;
выполнить один раз сортировку массива и затем серию из K бинарных поисков;
измерить полное время обоих подходов;
определить, при каком значении K стратегия с предварительной сортировкой становится выгоднее.
Результаты исследования необходимо представить графически. Следует построить график зависимости времени выполнения от числа запросов K, на котором должны быть показаны две кривые:
Linear total;
Sort + Binary total.
После выполнения задания необходимо объяснить, почему при малом числе запросов линейный поиск может быть выгоднее из-за отсутствия затрат на сортировку, а при большом числе запросов предварительная сортировка начинает окупаться. Также следует сделать вывод о том, как число запросов влияет на выбор стратегии поиска.
Задание 4. Подсчёт не только времени работы, но и внутренних характеристик алгоритмов
При сравнении алгоритмов поиска полезно оценивать не только время выполнения, но и внутренние характеристики, показывающие, как именно работает алгоритм. К таким характеристикам относятся число сравнений, число выполненных итераций цикла и число изменений границ или указателей.
Необходимо модифицировать реализации всех четырёх алгоритмов поиска так, чтобы каждая функция возвращала не только результат поиска, но и дополнительную статистику работы. Для каждого алгоритма требуется подсчитывать:
количество сравнений с искомым элементом;
количество итераций основного цикла;
количество сдвигов границ, индексов или указателей.
После этого необходимо выполнить серию поисков на одинаковых наборах данных и представить результаты в виде таблицы. В таблице следует показать, как отличаются алгоритмы по внутренним характеристикам, даже если время их выполнения оказывается близким.
После выполнения задания необходимо объяснить, почему число сравнений и количество итераций можно рассматривать как более “чистую” алгоритмическую характеристику, чем время исполнения, и как эти показатели помогают лучше понять различия между алгоритмами поиска.
Задание 5. Сравнение поиска на стандартном списке Python и на массиве NumPy
В практических задачах поиск можно реализовывать не только вручную, но и с помощью встроенных или библиотечных средств. Поэтому важно сравнить учебные реализации алгоритмов с готовыми инструментами Python и NumPy. Необходимо провести сравнительное исследование следующих способов поиска:
собственной реализации поиска на стандартном списке Python list;
использования встроенных средств Python, например in и .index();
использования numpy.searchsorted для отсортированного массива NumPy.
Для корректного сравнения необходимо использовать одинаковые массивы и одинаковые наборы поисковых запросов. Следует измерить время работы каждого способа и представить результаты в виде таблицы или графика.
После выполнения задания необходимо объяснить, почему библиотечные средства могут работать заметно быстрее пользовательских реализаций, в чём состоит отличие между “учебным” алгоритмом и оптимизированной библиотечной функцией, а также сделать вывод о том, когда имеет смысл писать алгоритм самостоятельно, а когда рациональнее использовать готовые средства.
Задание 6. Исследование влияния размера массива на эффективность алгоритмов поиска
Одним из важнейших факторов, влияющих на эффективность алгоритма поиска, является размер массива. Необходимо исследовать, как изменяется время работы алгоритмов поиска при увеличении числа элементов в массиве.
Требуется провести вычислительный эксперимент для следующих размеров массива:
N = 10^3;
N = 10^4;
N = 10^5;
N = 10^6.
Для каждого значения N необходимо:
сгенерировать массив;
выполнить серию поисков для каждого из реализованных алгоритмов;
измерить среднее время поиска;
сравнить полученные результаты.
Результаты необходимо представить графически. Следует построить график, где по оси X откладывается размер массива N, а по оси Y — среднее время поиска. На одном графике должны быть показаны кривые для всех исследуемых алгоритмов.
После выполнения задания необходимо объяснить, почему время работы линейного поиска растёт почти линейно, почему бинарный поиск увеличивается значительно медленнее, в каких условиях интерполяционный поиск может показывать лучшие результаты, а также почему экспоненциальный поиск по характеру поведения близок к бинарному, но в отдельных ситуациях может иметь преимущества.
Контрольные вопросы:
Что такое линейный поиск?
Что такое бинарный поиск?
Почему бинарный поиск требует сортировки?
Что даёт барьер в модифицированном линейном поиске?
В чём идея интерполяционного поиска?
Почему он хорошо работает на равномерных данных?
В чём идея экспоненциального поиска?
Когда выгодно сортировать массив перед поиском?
Почему нужно считать не только время, но и число сравнений?
Чем пользовательская реализация отличается от библиотечной?
