На этом шаге мы рассмотрим основные понятия сложности задач.
Под задачей понимается некоторый вопрос, на который нужно найти (вычислить) ответ. Задачи бывают общие (массовые - сравните со свойством алгоритма) и частные (индивидуальные). Общая задача определяется:
Частная задача получается из общей задачи, если всем параметрам общей задачи придать конкретные значения (задать исходные данные). Для алгоритма сказали бы: на место формальных параметров подставить фактические.
Для любой разрешимой задачи существует множество различных алгоритмов, ее решающих, предположим, что сложность самого простого из таких алгоритмов можно считать сложностью задачи. Процесс поиска для данной задачи алгоритма минимальной сложности был назван оптимизацией алгоритма. К сожалению, в большинстве случаев этот процесс не удается довести до конца и вместо оптимизации получаем лишь некоторое улучшение. Поэтому оценивать сложность задачи через анализ текста оптимального алгоритма обычно невозможно, а другого способа у нас пока нет.
Тем не менее, сложность задачи (чисто математической или естественнонаучной, выраженной с помощью некоторого формального языка) представляется одной из фундаментальных характеристик в познании той Вселенной, в которой мы существуем. Характеристикой не менее значимой, чем физические константы - скорость света в вакууме, постоянная Хаббла (значение плотности вещества во Вселенной, разделяющее замкнутую и открытую космогонические модели); чем известные математические константы и др.
Компьютерные науки делают пока только первые шаги в классификации задач по сложности. Естественно, что начинаем с дихотомии: попытки разделить все задачи на два класса - легкие и трудные. Границу между ними можно проводить по-разному, но все сошлись во мнении, что задачи, для решения которых требуется выполнить O(n), O(n2), O(n3), ... операций - это легкие задачи (здесь n - параметр сложности исходных данных). Задачи же с оценкой сложности O(2n) и более - сложные. Первую группу задач называют задачами полиномиальной сложности, поскольку их временная сложность ограничивается сверху некоторым полиномом (быть может, очень большой, но конечной степени n). Обозначим множество таких задач Р. Вторую группу называют задачами экспоненциальной сложности, поскольку в общем случае (т. е. для исходных данных, наиболее "неудобных" для любого из алгоритмов, решающих задачу) требуется количество операций, увеличивающееся с ростом n, по крайней мере, экспоненциально. Обозначим множество этих задач ЕХР.
Такое разграничение практически оправдано. Представим себе, что на самом быстром из доступных нам компьютеров решаем две задачи, полиномиальную Р1 с параметром сложности исходных данных и, и экспоненциальную Р2 с параметром n2. Эти две задачи решаются примерно одинаковое время T и находятся на грани того, чтобы испытывать наше терпение: согласны ждать время T, но ни секунды больше! И вот, наконец, мы получили новый компьютер, работающий в несколько (k) раз быстрее, чем старый. Вопрос: насколько более сложные задачи можно решать на новом компьютере (как изменятся n и n2?), если наши возможности ожидания решения не изменились?
Простой анализ показывает, что доступная сложность полиномиальной задачи увеличилась В несколько раз, стала равной m*n1, а доступная сложность экспоненциальной задачи увеличилась на несколько единиц, стала равной n2+l. Здесь m и l вычисляются через k. Например, если первая задача имеет линейную сложность, а вторая - 2n, то ускорение компьютера в два раза (k=2) приводит к значениям 2n1 и n2+l. Это действительно качественно различные результаты.
Известны многие представители класса задач полиномиальной сложности:
Хотелось бы, чтобы все задачи были легкими, но сегодня для ряда задач известны только экспоненциальные алгоритмы! В связи с попыткой классификации сразу возникает много вопросов. Существуют ли неполиномиальные задачи или для любой задачи может быть построен полиномиальный алгоритм? Если существуют, то где проходит граница между полиномиальными и неполиномиальными задачами, как ее описать (иными словами, найти легко вычислимую характеристическую функцию множества Р)?
Для ответа на эти и другие вопросы нужно навести порядок в множестве задач, выделить некоторые полезные типы задач (так называемые переборные задачи) и ввести хотя бы минимальную формализацию. Кроме этого понадобится:
На следующем шаге мы рассмотрим понятие переборной задачи (задачи, решаемой методом полного перебора).