МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «СЕВЕРО-КАВКАЗСКАЯ ГОСУДАРСТВЕННАЯ АКАДЕМИЯ» КАФЕДРА ПРИКЛАДНОЙ ИНФОРМАТИКИ Контрольная работа по дисциплине: «СТРУКТУРЫ И АЛГОРИТМЫ КОМПЬЮТЕРНОЙ ОБРАБОТКИ ДАННЫХ» Вариант №_2_ Выполнил: обучающийся __3__ курса группы _ПИЮ -3-211__ ЗФО направления подготовки 09.03.03 Прикладная информатика напр.(профиль) Прикладная информатика в экономике (юриспруденции) ФИО Апсов М.Р. Приняла: Эркенова М.У. Черкесск, 2024 Вариант 2 1. Основные методы построения алгоритмов: «разделяй и властвуй», динамическое программирование. 2. Линейные списки. Основные операции. Представление и реализация. 3. Какой из критериев эффективности сортировки определяется формулой M=0,01*n*n+10*n ? a)число сравнений; b)время, затраченное на написание программы; c)количество перемещений; d)время, затраченное на сортировку. 4. Элементы числового массива Х(15) упорядочены по возрастанию. Найти номер элемента массива, равного заданному числу У. Использовать следующий метод бинарного поиска: сравнить У со средним элементом массива (или элементом около середины), если эти числа равны, поиск завершается, если же У меньше среднего элемента, то У надо искать в левой половине массива, а иначе - в правой, к выбранной половине принимается этот же алгоритм. Ответы: 1. Метод «разделяй и властвуй» Решения задач аддитивного характера можно осуществлять путем их разделения на части и получить решение всей задачи путем решения ее частей. Для этого используется известный метод проектирования эффективных алгоритмов, который называется методом декомпозиции, или методом «разделяй и властвуй», методом разбиения. Метод предполагает декомпозицию (разбиение) задачи размера n на частные задачи, решение которых позволяет получить решение общей, исходной задачи. Такой метод может применяться в сортировке слиянием, в деревьях двоичного поиска и других и характеризуется легкостью разработки и достаточной эффективностью. Такой подход позволяет использовать параллельную обработку массива данных. При этом задание начальных значений элементов массива осуществляется для всего массива и выполняется с помощью тех же начальных значений для частей массива. Матричные операции сложения и вычитания выполняются таким же способом, так как эти операции определены для отдельных элементов. Примерами использования этого метода может быть решение задач: численного интегрирования; двойного бухгалтерского учета, когда итоги по столбцам вычисляются для различных категорий, включающих дебиты и кредиты, после чего результаты в нужных сочетаниях сравниваются; вычисления площади неправильного многоугольника путем разбиения его на треугольники и вычисления их площадей по отдельности с последующим суммированием для определения исходной площади многоугольника; сортировки слиянием, выполняющейся разделением n элементов списка на две группы, их отдельной сортировки и последующего слияния; сортировки Шелла, основанной на разбиении списка на n/2 подсписков, содержащих по два элемента каждый, их сортировки и на последующих циклах сортировки n/4 четырехэлементных, затем n/8 восьмиэлементных списков; поиск пути в лабиринте, при котором лабиринт разделяется на четыре части, через каждую из них отыскивается путь и конечные точки сравниваются между собой, а затем, объединяя в каждом из квадрантов сообщающиеся между собой входные и выходные точки, получают соответствующие пути для всего лабиринта; составления графика проведения теннисного турнира и др. Метод динамического программирования Понятие метода динамического программирования связано с методом планирования многоэтапных процессов принятия решения и может рассматриваться как: метод математического программирования; метод решения задач оптимизации, представленных через последовательность этапов принятия решений. Метод математического программирования охватывает прикладные задачи и вычислительные методы для задач оптимизации, которые формулируются как задачи максимизации или минимизации функции (целевой функции) на ограниченном множестве пространства действительных n-компонентных векторов. Оптимизационные методы представляют процесс нахождения наилучшего решения задачи, которое определяется по некоторому заранее установленному критерию. В программировании метод оптимизации используется при разработке алгоритма генерации программы, которая наилучшим способом использует ресурсы ЭВМ (объем памяти, время исполнения и др.). При этом различают три формы оптимизации: глобальная оптимизация — оптимизация, используемая для переупорядочивания установленной последовательности выполнения команд программы с целью исключения избыточности вычисления; регистровая оптимизация — оптимизация, связанная с привязкой машинных регистров памяти к переменным и промежуточным численным результатам с целью минимизации числа случаев «холостого» резервирования регистров для их загрузки в дальнейшем; локальная оптимизация — оптимизация, обеспечивающая адаптацию программы к конкретным особенностям архитектуры машины и устранение избыточности локальных операций типа загрузки в регистр величины, которая уже хранится в нем. Как метод разработки алгоритмов динамическое программирование заключается в одновременном использовании прямого и обратного проходов для решения задачи. Перемещение в одном направлении позволяет получить одно из возможных решений, а в другом — обеспечивает альтернативное решение. После сравнения этих решений выбирается лучшее. Примером использования этого метода является решение варианта задачи о коммивояжере, где требуется найти кратчайшее расстояние между двумя пунктами, которые могут обозначать один и тот же город. При этом найденный путь представляет кратчайший циклический маршрут, следуя которому коммивояжер не повторяет ни один из участков пути. В этом случае можно получить хороший, но не обязательно лучший маршрут. Кроме этого, рассматриваемый метод может быть использован для нахождения кратчайшего пути через лабиринт. В рамках теории управления в наиболее общей форме динамическое программирование представляет процесс пошагового решения задач» при котором на каждом шаге выбирается одно решение из множества допустимых на этом шаге решений, притом такое, которое оптимизирует заданную целевую функцию или функцию критерия. В основе теории динамического программирования лежит принцип оптимальности Беллмана: оптимальное поведение обладает тем свойством, что каковы бы ни были первоначальное состояние и решение (то есть управление), последующие решения должны составлять оптимальное поведение относительно состояния, получающегося в результате первого решения. От противного: если не использовать наилучшим образом то, чем мы располагаем сейчас, то и в дальнейшем не удастся наилучшим образом распорядиться тем, что могли бы иметь. Таким образом, если имеется оптимальная траектория, то и любой ее участок представляет собой оптимальную траекторию. На основе этого принципа формулируется эффективный метод решения широкого класса многошаговых задач. Общим для задач динамического программирования является то, что переменные в модели рассматриваются не вместе, а последовательно, одна за другой. Строится вычислительная система, в которой вместо одной задачи со многими переменными строится много задач с малым числом переменных в каждой, что сокращает объем вычислений. Такое преимущество достигается только при выполнении двух условий: при использовании аддитивного критерия оптимальности, когда общее оптимальное решение является суммой оптимальных решений каждого шага; будущие результаты не зависят от предыстории того состояния системы, при котором принимается решение. Из этого принципа оптимальности Беллмана вытекает основной прием — нахождение правил доминирования, на основе которых на каждом шаге производится сравнение вариантов будущего развития и заблаговременное отсечение заведомо бесперспективных вариантов. Реализация этих правил формальными выражениями, однозначно определяющими элементы последовательности один за другим, носит название разрешающих правил. Процесс решения этих правил состоит из этапов: на первом этапе процесс ведется «с конца», где для каждого из различных предположений о содержании окончания предпоследнего шага находится условное оптимальное управление на последнем шаге, то есть управление, которое надо применить, если предпоследний шаг закончился определенным образом. Такая процедура проводится до самого начала; на втором шаге процедура выполняется от начала к концу, в результате находятся не условные, а действительно оптимальные шаговые управления на всех шагах операции. Рассмотренный метод, несмотря на выигрыш в сокращении вычислений, по сравнению с методами имеет перебор возможных вариантов. В силу этого размерность решаемых практических задач должна быть незначительной, что ограничивает применение метода. С учетом этого выделяют следующие общие классы задач, для которых может быть применим метод динамического программирования: задачи планирования деятельности экономических объектов; задачи оптимального распределения ресурсов между различными направлениями во времени. Кроме этого метод может быть использован для решения следующих задач: определения вероятности победы в спортивных турнирах; триангуляции многоугольника и др. Триангуляция многоугольника — выбор совокупности хорд (линий между несмежными вершинами), таких, что никакие две хорды не будут пересекаться, а весь многоугольник будет разбит на треугольники. Если общая длина хорд будет минимальной, то такая триангуляция будет называться минимальной. 2. Линейный список (или просто список) - это структура данных, в которой элементы хранятся последовательно, каждый из них связан с предыдущим и/или последующим элементом. Основные операции над линейными списками включают 1. Вставка элемента: - Вставка в начало списка: новый элемент становится первым элементом списка. - Вставка в конец списка: новый элемент добавляется в конец списка. 2. Удаление элемента: - Удаление элемента из списка: элемент удаляется из списка, при этом связи между соседними элементами перестраиваются. 3. Поиск элемента: - Поиск элемента в списке: осуществляется обход списка для нахождения нужного элемента. Представление линейных списков: 1. Односвязный список: - Каждый элемент содержит данные и ссылку на следующий элемент. - Прост в реализации и требует меньше памяти, чем двусвязный список. 2. Двусвязный список: - Каждый элемент содержит данные, ссылку на предыдущий и следующий элементы. - Обеспечивает более эффективные операции вставки и удаления за счет наличия ссылки на предыдущий элемент. Реализация линейных списков: 1. Односвязный список: - Реализуется через структуру узла, содержащего данные и указатель на следующий узел. - Операции вставки, удаления и поиска реализуются изменением указателей между узлами. 2. Двусвязный список: - Каждый узел содержит указатели на предыдущий и следующий узлы. - Операции вставки, удаления и поиска более эффективны благодаря наличию указателя на предыдущий узел. Линейные списки широко используются в программировании для организации данных, так как обеспечивают гибкость при добавлении и удалении элементов. 3. Формула M = 0,01*n^2 + 10*n представляет собой функцию, которая описывает количество операций (сравнений и перемещений) в алгоритме сортировки в зависимости от количества элементов n, которые нужно отсортировать. Здесь n - количество элементов, а M - количество операций. Первое слагаемое 0,01*n^2 представляет количество сравнений, а второе слагаемое 10*n представляет количество перемещений. Таким образом, данная формула описывает общее количество операций, необходимых для сортировки n элементов в конкретном алгоритме сортировки. А)С) 4. ```pascal program BinarySearch; const N = 15; // Размер массива var X: array[1..N] of Integer; // Объявляем массив X i, U, left, right, mid: Integer; // Переменные для циклов и поиска begin // Инициализируем массив X for i := 1 to N do begin X[i] := i * 2; // Пример: элементы массива X увеличиваются на 2 end; // Задаем число, которое хотим найти в массиве X U := 10; // Пример: ищем элемент равный 10 // Начальные значения для поиска left := 1; right := N; // Начинаем бинарный поиск while left <= right do begin mid := (left + right) div 2; // Если нашли число U if X[mid] = U then begin writeln('Элемент ', U, ' найден в массиве. Номер элемента: ', mid); break; end // Если U меньше значения в середине массива else if U < X[mid] then begin right := mid - 1; end // Если U больше значения в середине массива else begin left := mid + 1; end; end; // Если элемент не найден if left > right then writeln('Элемент ', U, ' не найден в массиве.'); end. ```