Корректность эмпирических алгоритмов обычно проверяют экспериментально. Какую-то уверенность в их корректности можно получить, если их многократное применение всегда приводит к необходимому результату. Однако одно только многократное экспериментальное подтверждение еще не вселяет полной уверенности.
Полная уверенность в корректности эмпирического алгоритма возникает лишь в том случае, когда полученные c его помощью результаты не только подтверждаются экспериментально, но и согласуются со всеми другими накопленными и объединенными в научную теорию фактами данной области науки или техники.
Если хотя бы один из даваемых алгоритмом результатов противоречит хотя бы одному из ранее установленных и получивших признание фактов, эмпирический алгоритм нельзя признать корректным (хотя после проверки может оказаться некорректным не алгоритм, а тот факт, которому он противоречит). Корректность теоретически обусловленных алгоритмов гарантируется наличием соответствующих доказательств.
Очень интересен вопрос об установлении корректности алгоритмов, полученных на основе других, ранее разработанных и заведомо корректных алгоритмов. Решение этого вопроса зависит от приема, который был применен для получения нового алгоритма.
Перечислим наиболее часто применяемые приемы.
1) Конструирование алгоритмов. Этот прием заключается в том, что новый алгоритм получают комбинированием уже известных алгоритмов как составных частей.
2) Эквивалентные преобразования алгоритмов. Два алгоритма называют эквивалентными, если: а) всякий вариант исходного данного, допустимый для одного из них, допустим и для другого; б) применимость одного алгоритма к какому-либо исходному данному гарантирует, что и другой алгоритм применим к этому исходному данному; в) результаты, даваемые этими алгоритмами для одного и того же исходного данного, между собой одинаковы. Замечу, что совершенно неправильно эквивалентные алгоритмы называть различными формами одного и того же алгоритма.
Всякое изменение алгоритма, в результате которого снова получается алгоритм (а не что-нибудь иное) и при этом эквивалентный исходному алгоритму, называется эквивалентным преобразованием алгоритма. Примером эквивалентного преобразования алгоритма является его перевод с одного языка на другой (если, конечно, он точен). Но известны и другие эквивалентные преобразования. С помощью эквивалентных преобразований можно существенно изменять алгоритмы. Конечно, разработчика алгоритмов интересуют такие эквивалентные преобразования, в результате которых можно получить алгоритм, который чем-то лучше исходного.
3) Сужающие преобразования. Они приводят к алгоритмам решения задач, являющихся частными случаями тех задач, для решения которых были предназначены исходные алгоритмы. Обычно вслед за таким сужением производят эквивалентное преобразование, при котором используют возникающие при сужении возможности улучшения алгоритма.
4) Применение формального метода к нематематической проблеме. Этот прием заключается в том, что нематематическую проблему (принадлежащую какой-либо технической, естественнонаучной или социально-экономической дисциплине) формулируют математически. При этом может оказаться, что известен алгоритм решения получившейся математической задачи. Этот алгоритм и принимается за искомый. Если готового алгоритма не окажется, то делают попытку его разработки, тем самым обращаясь ко второму из указанных выше источников для получения алгоритмов.
Корректность алгоритмов, полученных путем конструирования, не вызывает сомнений, если алгоритмы, использованные в качестве «строительного материала», дают точные результаты. Если же их результаты являются приближенными, как это часто бывает на практике, то обоснование корректности может требовать сложных исследований.
Доказательством корректности алгоритмов, полученных с помощью эквивалентных преобразований, является правильность преобразований. Мы не можем пока более определенно говорить об эквивалентных преобразованиях, потому что накопленные нами, читатель, знания об алгоритмах еще недостаточны.
Корректность алгоритмов, полученных путем сужающих преобразований, обеспечивается проверкой (доказательством) того, что каждый результат, получаемый суженным алгоритмом, тождествен с результатом, который для того же варианта исходного данного дает исходный алгоритм.
Наконец, корректность алгоритма, полученного в результате применения формального метода, выясняется либо так же, как для эмпирических алгоритмов, либо а) оценкой так называемой адекватности полученной математической задачи (т. е. возможности получения при ее решении результата, достаточно близкого к искомому результату) и б) доказательством корректности алгоритма решения математической задачи.
Алгоритмы, полученные в результате изобретательности разработчика, также требуют обоснования. Обычно с ними поступают либо как с эмпирическими, либо (уже после их получения) проделывают все действия, предусматриваемые формальным методом.
§ 3. Задачи на построение алгоритмов
Можно было бы продолжить изложение и обоснование различных алгоритмов, накопленных в математике. Взамен этого мы лишь перечислим некоторые из них, для того чтобы создать у читателя правильное впечатление об их разнообразии и многочисленности. Алгоритмами являются правила для решения систем алгебраических линейных уравнений (существует большое число таких правил), правила дифференцирования функций и правила интегрирования, изучаемые в курсе математического анализа, правило Штурма — Лиувилля нахождения приближенного значения корня произвольного уравнения f(х)=0. Алгоритмами являются также и многие другие правила для решения различных задач с помощью циркуля и линейки, известные читателю из школьного курса. Если бы мы вздумали приводить здесь все эти алгоритмы и обосновывать их корректность, то, безусловно, не довели бы эту работу до конца из-за ее большого объема.
Читатель уже представляет себе, как появляются алгоритмы. Обычно алгоритм разрабатывают, имея в виду какую-нибудь задачу. Для ее решения и создают алгоритм. При этом перед математиком возникает задача, коренным образом отличающаяся от той, для решения которой должен быть создан алгоритм. Эту задачу можно сформулировать так: «Задан такой-то класс исходных данных и такая-то задача (проблема), для которой эти исходные данные допустимы. Требуется найти алгоритм, решающий указанную проблему», т. е. перед математиком возникает задача нахождения алгоритма.
Очень большое число таких задач на нахождение алгоритма математики успешно решили. Но целый ряд задач на построение алгоритмов упорно не поддавался решению. Приведем одну из них.
В 1742 г. математик X. Гольдбах, петербургский академик, в письме к Л. Эйлеру выдвинул проблему: доказать, что каждое целое число, которое больше или равно шести, может быть представлено в виде суммы трех простых чисел.
Этой проблеме можно придать следующий вид. Найти алгоритм, который позволил бы для любого целого числа, большего, чем 6, найти хотя бы одно разложение на три простых слагаемых. В ответном письме Л. Эйлер заметил, что для четных чисел эта проблема эквивалентна проблеме разложения числа на два простых слагаемых. В 1937 г. И. М. Виноградов доказал, что всякое достаточно большое нечетное число представляется суммой трех простых чисел; впоследствии была указана и нижняя граница, предполагаемая в доказательстве И. М. Виноградова, так что для нечетных чисел проблема Гольдбаха уже решена, но для четных чисел она не решена и до настоящего времени.
Заметим, что алгоритм ее решения был бы очень несложен: если задано четное N, нужно было бы (с помощью алгоритма Эратосфена) найти все не превосходящие его простые числа, далее последовательно отнимать каждое из них от заданного N и смотреть, не содержится ли разность среди уже полученных простых чисел. Беда в том, что до сих пор не удалось доказать корректность этого алгоритма, и потому нельзя его считать алгоритмом разложения любого четного числа на два простых слагаемых.
Интересно отметить, что некоторые задачи на нахождение алгоритма, долго не поддававшиеся решению, оказались неразрешимыми. К их числу, например, относятся той очень древние геометрические проблемы: задача о квадратуре круга, задача о трисекции угла и задача об удвоении куба.
Задача о квадратуре круга заключается в следующем: требуется найти метод (алгоритм) построения с помощью циркуля и линейки квадрата, равновеликого данному кругу. Эта задача является массовой, потому что исходным данным для нее может быть любой круг.
Задача трисекции угла гласит: требуется найти общий метод (алгоритм) деления произвольного угла с помощью циркуля и линейки на три равные части. Проблема тоже является массовой, потому что исходным данным может быть любой угол.
Наконец, задача удвоения куба гласит: требуется найти алгоритм, позволяющий по стороне любого куба с помощью циркуля и линейки построить сторону куба, объем которого вдвое больше объема заданного.
Невозможность решения этих задач была строго доказана. Неудача попыток решения некоторых проблем после того, как была доказана невозможность решения некоторых других проблем, породила определенную «подозрительность». Ученые стали опасаться, что затрачивая без успеха свои усилия на решение некоторых проблем, они стараются достигнуть невозможного. Возникло мнение о необходимости выявления неразрешимых проблем. Для задач на отыскание алгоритма это должно сводиться к разработке методов доказательства несуществования алгоритма.
Нужно подчеркнуть, что алгоритмы для квадратуры круга, трисекции угла и удвоения куба невозможны, если допускать только операции, выполнимые с помощью циркуля и линейки, причем линейка используется только для проведения прямых через пары точек и никак иначе. Уже Архимед предложил метод трисекции угла, в котором допускалась операция, состоящая из двух действий: 1) нанесения на линейке двух точек, копирующих две данные точки чертежа, 2) такого перемещения линейки, чтобы одна из отмеченных на ней точек скользила по прямой, а другая по окружности.