"Информатика (базовый уровень)", Гейн А.Г., Гейн А.А.
Применимость алгоритма доказывают, чтобы убедиться: на каждом допустимом наборе исходных данных он завершится и выдаст ответ, удовлетворяющий условию задачи. Нескольких успешных запусков для этого недостаточно — они показывают лишь отдельные случаи. Для циклов обычно выбирают инвариант: утверждение о промежуточных результатах, которое сохраняется при каждом повторении. Затем проверяют начало работы, сохранение инварианта, окончание цикла и связь полученного состояния с требуемым ответом.
Текст подготовлен нейронной сетью по теме параграфа и не заменяет учебник — важные факты и формулировки сверяйте с ним.
Применимость алгоритма — выполнение алгоритма на любом допустимом наборе исходных данных с получением предусмотренного результата. Допустимыми называют входы, которые удовлетворяют ограничениям задачи. Это понятие нужно, чтобы оценить алгоритм целиком, а не только отдельный удачный запуск.
Корректность алгоритма — соответствие полученного результата условию задачи для каждого допустимого входа. Иными словами, недостаточно получить какое-нибудь значение: оно должно быть именно ответом на поставленный вопрос. Проверка корректности позволяет обосновать смысл результата.
Инвариант цикла — утверждение, истинное до начала каждой итерации и сохраняющее истинность после её выполнения. Итерация — одно повторение тела цикла. Инвариант нужен, чтобы описать, как связаны промежуточные значения и уже обработанные данные.
Доказательство по индукции — обоснование утверждения через доказательство базового случая и сохранения утверждения на следующем шаге. Сначала устанавливают, что оно верно в начале, а затем доказывают переход от одного шага к следующему. Так можно обосновать инвариант для всех повторений цикла, а не проверить их по одному.
Несколько удачных запусков не доказывают применимость, потому что каждый запуск проверяет только конкретный вход. Даже если программа прошла много тестов, может остаться допустимое значение, при котором она ошибётся или зациклится. Поэтому вместо перебора примеров строят рассуждение, охватывающее все входы, удовлетворяющие условию задачи.
Применимость раскладывают на два вопроса: верен ли результат и завершится ли работа. Корректный алгоритм может сохранять правильное промежуточное значение, но повторять действия бесконечно. И наоборот, алгоритм может быстро остановиться, но вывести неверный ответ. Значит, нужны отдельные обоснования обоих свойств для каждого допустимого входа.
Чтобы выбрать инвариант цикла, подумайте, что уже обработано к началу очередного повторения и какой факт об этом должен оставаться верным. Утверждение связывают с условием задачи и промежуточными результатами: например, накопленная сумма должна совпадать с суммой обработанных чисел. Если такое утверждение не помогает объяснить будущий ответ, оно не подходит, даже когда истинно.
Инвариант доказывают по индукции. Сначала проверяют начальное состояние — оно должно быть истинным перед первой итерацией; затем предполагают, что утверждение верно перед некоторым повторением, и показывают, что действия цикла сохраняют его. Тогда инвариант верен перед каждой итерацией, которая действительно начинается. Важно также рассмотреть выход из цикла: инвариант должен быть применим в последнем состоянии.
После остановки соединяют инвариант с условием, при котором цикл закончился: вместе они должны означать, что найден именно требуемый результат. Это доказывает корректность. Завершение обосновывают отдельно: находят величину, которая при каждом повторении строго уменьшается (или увеличивается), оставаясь в ограниченных пределах. Например, неотрицательное целое число не может уменьшаться бесконечно, поэтому цикл остановится.
| Этап | Что проверяют | Как обосновывают | Что получают |
|---|---|---|---|
| Допустимость исходных данных | Вход удовлетворяет ограничениям задачи | Формулируют ограничения и проверяют, что алгоритм рассчитан на такие входы | Область входов, для которой ведётся доказательство |
| Начальная ситуация | Верно ли выбранное утверждение до первой итерации | Подставляют начальные значения переменных и данных | Базовый случай доказан |
| Сохранение инварианта | Остаётся ли утверждение верным после шага цикла | Рассматривают действия одной итерации и их влияние на переменные | Инвариант верен при каждом повторении |
| Завершение алгоритма | Может ли цикл продолжаться бесконечно | Показывают ограниченное строгое изменение выбранной величины | Алгоритм обязательно остановится |
| Соответствие результата условию задачи | Получен ли нужный ответ после выхода | Соединяют инвариант с условием окончания цикла | Доказана корректность результата |
Таблицу удобно использовать как контрольный список: по каждому этапу нужно записать конкретное обоснование, а не просто поставить отметку. Если алгоритм не содержит цикла, всё равно проверяют завершение его действий. Применимость доказана, когда подтверждены и остановка, и правильность результата на допустимых входах.
Задача 1. Для алгоритма вычисления суммы 1 + 2 + … + n докажите правильность результата и завершение цикла при натуральном n. Пусть переменная s сначала равна 0, а цикл по очереди прибавляет к ней числа от 1 до n. Нужно понять, что хранит s в ходе работы, и почему цикл не может повторяться бесконечно.
Ответ: алгоритм завершится и выдаст сумму, заданную условием. Доказаны и завершение, и корректность.
Задача 2. Докажите применимость алгоритма Евклида для нахождения НОД двух натуральных чисел a и b. Алгоритм заменяет пару (a, b) на (b, a mod b), пока второе число не станет равным нулю. Нужно обосновать, почему замена не меняет искомый НОД и почему повторения закончатся.
Ответ: алгоритм Евклида останавливается и возвращает НОД исходных чисел.
Задача 3. Докажите корректность и завершение двоичного поиска элемента в упорядоченном массиве. На каждом шаге сравнивают искомое значение со средним элементом и оставляют половину, в которой оно может находиться. Если совпадения нет, отрезок поиска сужают до пустого.
Ответ: инвариант обосновывает верность найденной позиции, а пустой отрезок — отсутствие элемента; уменьшение длины отрезка доказывает завершение.
Для таких доказательств нужны понятия алгоритма, цикла, условия и переменной, а также математическая индукция: без них трудно описать шаги работы и доказать сохранение утверждения. Необходимо уметь формулировать условие задачи и отличать допустимые входы от недопустимых, иначе непонятно, для каких данных требуется доказательство. Метод применяют при обосновании программ, циклических алгоритмов, поиска, сортировки и вычислительных процедур. В каждом случае рассуждение связывает ход вычислений с требуемым результатом.
Почему нельзя доказать применимость алгоритма, проверив его на большом числе примеров?
Даже тысячи тестов охватывают только конечное число входов, а допустимых наборов может быть бесконечно много. Тестирование помогает найти ошибки, но доказательство должно обосновать работу алгоритма для каждого допустимого входа.
Как понять, какое утверждение выбрать инвариантом цикла?
Свяжите утверждение с тем, что цикл уже сделал, и с условием задачи: например, какая часть данных обработана и что вычислено для неё. Проверьте, что утверждение верно до первой итерации, сохраняется после неё и вместе с условием выхода позволяет получить ответ.
Обязательно ли отдельно доказывать завершение алгоритма?
Да: правильные промежуточные действия не гарантируют, что алгоритм когда-нибудь остановится. Для завершения обычно находят целую или натуральную величину, которая при каждом шаге строго уменьшается и не может уменьшаться бесконечно.
Может ли алгоритм быть корректным, но неприменимым?
Да, если он выдаёт правильный ответ в тех случаях, когда заканчивает работу, но для некоторых допустимых входов зацикливается. Тогда корректность результата не означает применимость: не доказано завершение.
Чем доказательство применимости отличается от тестирования программы?
Тестирование запускает программу на выбранных данных и помогает обнаруживать ошибки на этих примерах. Доказательство рассуждением охватывает все допустимые входы и отдельно обосновывает правильность результата и завершение.
§ 48. Как доказывают применимость алгоритма