Изменить размер шрифта - +
В самом деле, если бы все математические задачи были простыми, математики остались бы без работы. Соответствующая задача тысячелетия заключается в том, чтобы строго доказать, что существует по крайней мере одна сложная задача или что, вопреки нашему опыту, все задачи являются простыми. Эта задача известна как задача P/NP, и никто пока не представляет, как ее нужно решать.

 

В главе 2 мы уже сталкивались с приближенной оценкой эффективности. Алгоритм относится к классу P, если он имеет полиномиальное время работы. Иными словами, если число шагов, которые необходимо сделать для получения ответа, пропорционально количеству входных данных в какой-либо постоянной степени (скажем, в квадрате или кубе). Такие алгоритмы эффективны в самом широком смысле. Если входные данные представлены числом, то их количество — это не само число, а количество знаков в нем. Причина в том, что количество информации, необходимой для представления числа, соответствует месту, которое оно занимает в памяти компьютера, а это место пропорционально количеству цифр. Задача относится к классу P, если существует алгоритм класса P, который ее решает.

Любой другой алгоритм (или задача) принадлежит к классу не-P, и большинство таких алгоритмов неэффективны. Среди них есть алгоритмы, время работы которых экспоненциально по отношению к входным данным, т. е. примерно равно некоему фиксированному числу в степени, соответствующей размеру входных данных. Такие алгоритмы относятся к классу E и определенно неэффективны.

Некоторые алгоритмы настолько эффективны, что выполняют работу намного быстрее, чем за полиномиальное время. К примеру, чтобы определить четность или нечетность числа, достаточно посмотреть на его последнюю цифру. Если (в десятичной записи) это цифра 0, 2, 4, 6 или 8, число — четное, в противном случае — нечетное. Весь алгоритм включает в себя не более шести шагов:

 

Последняя цифра — 0? Если да, то СТОП. Число четное.

Последняя цифра — 2? Если да, то СТОП. Число четное.

Последняя цифра — 4? Если да, то СТОП. Число четное.

Последняя цифра — 6? Если да, то СТОП. Число четное.

Последняя цифра — 8? Если да, то СТОП. Число четное.

СТОП. Число нечетное.

 

Итак, время выполнения программы ограничено шестью шагами, вне зависимости от размера входных данных. Такой алгоритм относится к классу алгоритмов «постоянного времени».

Расстановка слов в списке в алфавитном порядке представляет собой задачу класса P. Простейший способ выполнить эту задачу — это так называемый «пузырьковый» метод, получивший название потому, что слова, находящиеся ниже по списку, чем следует, при этом «всплывают» вверх, как пузырьки в стакане газировки. Алгоритм раз за разом просматривает список, сравнивает соседние слова и меняет их местами, если порядок не соответствует алфавитному. Пусть, к примеру, список вначале выглядит так:

 

РОГ ДОМ БОТ АКТ

 

Сначала происходит следующее:

 

ДОМ РОГ БОТ АКТ

ДОМ БОТ РОГ АКТ

ДОМ БОТ АКТ РОГ

 

Полужирным шрифтом выделены те слова, сравнение которых проводилось только что и которые были (или не были) переставлены. При втором проходе получаем:

 

БОТ ДОМ АКТ РОГ

БОТ АКТ ДОМ РОГ

БОТ АКТ ДОМ РОГ

 

Третий проход:

 

АКТ БОТ ДОМ РОГ

АКТ БОТ ДОМ РОГ

АКТ БОТ ДОМ РОГ

 

На четвертом проходе ничего не происходит, так что мы понимаем, что программа завершила работу. Обратите внимание, как слово АКТ постепенно всплывает вверх (т. е. к началу списка).

Если в списке четыре слова, алгоритм на каждом шагу проводит три сравнения, а всего шагов получается четыре.

Быстрый переход