Книга: Величайшие математические задачи
Назад: 10. Какой формы сфера? Гипотеза Пуанкаре
Дальше: 12. Потоковое мышление. Уравнение Навье — Стокса

11. Не могут они все быть легкими. Задача P/NP

В настоящее время математики используют компьютеры для решения самых разных задач, даже великих, и не считают это чем-то из ряда вон выходящим. Компьютеры хороши в числовых расчетах, но математика — это далеко не только «суммирование», так что ввести задачу в компьютер, как правило, очень непросто. Часто самое сложное — это преобразовать ее в такой вид, в каком ее можно решить путем компьютерных расчетов, и даже в этом случае компьютер иногда сопротивляется. Поэтому и в наше время решения многих великих задач находятся без или почти без участия компьютеров. Примерами тому — Великая теорема Ферма и гипотеза Пуанкаре.
В тех случаях, когда компьютеры использовались при решении великих задач (к примеру, теоремы о четырех красках или гипотезы Кеплера), они эффективно выступали в роли прислуги или помощников. Но иногда роли меняются, и математика становится служанкой компьютерной науки. Большая часть работы по первоначальному проектированию компьютеров шла в математическом ключе. Значительную роль в ней сыграла связь между булевой алгеброй — алгебраическим выражением формальной логики — и коммутационными схемами, разработанными, в частности, инженером Клодом Шенноном, создателем теории информации. Сегодня компьютеры и в практическом, и в теоретическом аспекте опираются на широкое использование многих самых разных областей математики.
Одна из задач тысячелетия по версии Института Клэя лежит в пограничной области между математикой и информатикой. В данном случае ситуацию можно рассматривать двояко: то ли информатика находится на службе у математики, то ли наоборот. На самом же деле требуется, да и развивается нечто другое, более сбалансированное, — партнерство. Задача касается компьютерных алгоритмов — математических скелетов, из которых вырастают компьютерные программы. Принципиальное значение здесь имеет концепция эффективности алгоритма: за сколько вычислительных шагов будет получен результат при определенном количестве входных данных. Практически эффективность говорит о том, сколько времени потребуется компьютеру на решение задачи заданного размера.
Слово «алгоритм» восходит к Средним векам, когда Мухаммад ибн-Муса аль-Хорезми написал один из первых трудов по алгебре. Еще раньше Диофант ввел в обращение элементы, которые мы сегодня прочно связываем с алгеброй: символы. У него они, однако, использовались как сокращения, а методы решения уравнений были представлены при помощи конкретных — хотя и типичных — примеров. Там, где мы сегодня написали бы что-нибудь вроде «x + a = y, следовательно, x = y — a», Диофант написал бы: «Положим x + 3 = 10, тогда x = 10 − 3 = 7» — и считал бы, что читатели должны сами сообразить, что эта идея будет работать и для любых других чисел вместо 3 и 10. Он готов был объяснить свой иллюстративный пример с применением символов, но никогда не стал бы оперировать символами как таковыми. Аль-Хорезми подробно разработал эту общую рекомендацию. Он сделал это при помощи слов, а не символов, но общая идея была верной, и именно он считается отцом алгебры. Более того, сам этот термин образован из названия его книги: она называлась «Краткая книга о вычислении посредством восполнения и противопоставления» («Аль-китаб аль-мухтасар фи хисаб аль-джебр ва-ль-мукабала»). Слово «аль-джебр», от которого и пошла алгебра, при этом означало «восполнение» и имело отношение к решению уравнений. А слово «алгоритм» произошло от средневековой латинизированной версии прозвища аль-Хорезми (т. е. «из Хорезма») — Алгорисмус — и означает в настоящее время специализированный математический процесс решения задачи, который при достаточно длительном ожидании гарантирует нахождение ответа на нее.
Традиционно в математике задача считалась решенной, если для нее в принципе можно было записать алгоритм, ведущий к ответу. Слово «алгоритм» использовалось редко: математики предпочитали представлять, скажем, формулу решения — частный случай алгоритма на языке символов. При этом было не слишком важно, может ли эта формула быть применена на практике: она сама по себе являлась решением. Но появление компьютеров изменило эту ситуацию. Формула, слишком сложная для ручных вычислений, вполне могла оказаться применимой, если привлечь на помощь компьютер. Зато ситуации, когда формула оказывалась слишком сложной даже для компьютера, стали вызывать раздражение, а такое тоже иногда случалось: конечно, любой алгоритм можно было попытаться просчитать на компьютере, но иногда расчет шел слишком медленно и не позволял получить ответ. Поэтому внимание ученых сместилось к поиску эффективных алгоритмов. И математики, и компьютерщики были кровно заинтересованы в получении алгоритмов, которые действительно позволяли бы за разумный промежуток времени получить ответ.
Если алгоритм имеется, относительно несложно оценить, сколько времени (измеряемого числом необходимых вычислительных операций) потребуется на решение задачи при определенном количестве входных данных. Это может требовать усилий и технических навыков, но зато вам известно, о каком именно процессе идет речь и, по крайней мере в общих чертах, что он делает. Гораздо сложнее разработать эффективный алгоритм, если тот, с которого вы начали, неэффективен. Еще сложнее решить, насколько плохим или хорошим может быть наилучший с точки зрения эффективности алгоритм для данной задачи, — ведь для этого нужно рассмотреть все возможные варианты, а вам неизвестно, что они собой представляют.
Первые работы по этому вопросу привели к грубому, но удобному разделению алгоритмов на эффективные (в простом, но неточном смысле) и неэффективные. Если продолжительность расчетов с увеличением количества входных данных растет относительно медленно, данный алгоритм эффективен, а задача проста. Если же продолжительность расчетов с увеличением количества входных данных растет очень быстро, то данный алгоритм неэффективен, а задача сложна. Опыт подсказывает, что, хотя встречаются задачи, которые в этом смысле можно назвать простыми, большинство задач к таковым не относятся и являются сложными. В самом деле, если бы все математические задачи были простыми, математики остались бы без работы. Соответствующая задача тысячелетия заключается в том, чтобы строго доказать, что существует по крайней мере одна сложная задача или что, вопреки нашему опыту, все задачи являются простыми. Эта задача известна как задача P/NP, и никто пока не представляет, как ее нужно решать.

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

На четвертом проходе ничего не происходит, так что мы понимаем, что программа завершила работу. Обратите внимание, как слово АКТ постепенно всплывает вверх (т. е. к началу списка).
Если в списке четыре слова, алгоритм на каждом шагу проводит три сравнения, а всего шагов получается четыре. Если слов в списке n, то на каждом проходе проводится n − 1 сравнение, а проходов необходимо n, так что всего требуется n (n − 1) шагов. Это чуть меньше, чем n², так что время работы программы полиномиально, более того, квадратично. Алгоритм может прекратить работу раньше, но в самом худшем случае, если окажется, что слова в списке стоят точно в обратном порядке, ему потребуется n (n − 1) шагов. Пузырьковый алгоритм сортировки очевиден и относится к классу P, но это далеко не самый эффективный алгоритм. Самый быстрый алгоритм сортировки — алгоритм сравнения — организован более хитро и выполняется за nlogn шагов.
Простой алгоритм с экспоненциальным временем работы — алгоритм класса E — это, к примеру, задание «распечатать список всех n-значных двоичных чисел». В таком списке 2n чисел, и на печать (и вычисление) каждого уходит примерно n шагов, так что полное время работы составляет приблизительно 2nn, что больше, чем 2n, но меньше, чем 3n для достаточно больших n. Однако это довольно глупый пример, поскольку медленным его делает не сложность вычислений, а всего лишь размер выходных данных, и позже это наблюдение окажется весьма важным.
Более типичный алгоритм класса E решает задачу о коммивояжере. Этот странствующий продавец должен посетить некоторое количество городов. Делать это он может в произвольном порядке. Какой путь следует избрать, чтобы суммарное расстояние оказалось минимальным? Наивный способ решения этой задачи состоит в том, чтобы выписать все возможные маршруты, рассчитать для каждого суммарное расстояние и найти минимальное из всех. Для n городов у нас получится
n! = n (n — 1) × (n — 2) × … × 3 × 2 × 1
маршрутов (читается «n факториал»). Эта величина растет быстрее, чем любая экспоненциальная величина. Более эффективный метод, известный как динамическое программирование, позволяет решить задачу о коммивояжере за экспоненциальное время. Первый подобный метод — алгоритм Хелда — Карпа — находит кратчайший маршрут за 2nn2 шагов; при достаточно больших n это опять же попадает в интервал между 2n и 3n.
Несмотря на то что эти алгоритмы «неэффективны», при помощи специальных уловок можно ускорить расчет в случае, если число городов велико по человеческим меркам, но не слишком велико для применения подобных хитростей. В 2006 г. Д. Эпплгейт, Р. Биксби, В. Шваталь и У. Кук решили задачу о коммивояжере для 85 900 городов. На середину 2012 г. это достижение все еще оставалось рекордным.

 

Приведенные примеры алгоритмов не просто иллюстрируют концепцию эффективности. Кроме этого, они помогают донести до читателя мысль о сложности нахождения улучшенных алгоритмов и еще большей сложности нахождения алгоритмов максимальной эффективности. Все известные алгоритмы для задачи о коммивояжере относятся к классу E экспоненциального времени, но это не означает, что эффективного алгоритма для нее не существует в принципе. Это лишь показывает, что мы пока такого алгоритма не нашли. И здесь возможны два варианта: мы не нашли лучшего алгоритма потому, что нам не хватает ума, или мы не нашли лучшего алгоритма потому, что его попросту не существует.
Можно вспомнить все ту же вторую главу. Пока команда Агравала не придумала свой алгоритм класса P для проверки на простоту, наилучший известный алгоритм принадлежал классу не-P. Тем не менее он тоже был достаточно хорош, считал за время nlogn для n-значных чисел, а это, вообще говоря, лучше, чем показатели алгоритма Агравала — Каяла — Саксены, пока мы не достигаем чисел с 101000 знаками. До открытия этого алгоритма мнения о статусе испытания на простоту разделялись. Некоторые специалисты считали, что это задача класса P и подходящий алгоритм рано или поздно будет найден. Другие были уверены, что этого не произойдет. Новый алгоритм возник практически ниоткуда: его породила одна из бесчисленных идей, которые можно было попробовать, и данная конкретная идея сработала. Это отрезвляющий прецедент: мы не знаем истинного положения вещей, не можем предсказать его заранее, и догадки лучших экспертов могут быть как верными, так и ошибочными.
Великая задача, которая нас в данный момент интересует, заключается в поиске ответа на более фундаментальный вопрос. Существуют ли сложные задачи? Могут ли все задачи оказаться простыми, если, конечно, приложить достаточно ума и сообразительности? На самом деле здесь есть одна тонкость, потому что мы уже видели одну несомненно сложную задачу: распечатку списка всех n-значных двоичных чисел. Я уже упоминал о том, что это глупый пример: сложность заключается не в расчетах, а в простой монотонной работе по распечатке очень длинного ответа. Нам известно, что никакие уловки здесь не помогут, поскольку ответ будет таким длинным по определению. Если бы он был короче, он не был бы ответом.
Чтобы поставить вопрос разумным образом, необходимо исключить подобные тривиальные примеры. Для этого введем еще один класс алгоритмов, класс NP. Это не класс не-P — это класс алгоритмов, работа которых занимает недетерминированное полиномиальное время. В переводе с математического это означает, что, сколько бы времени ни требовалось алгоритму на поиск ответа, убедиться в верности этого ответа мы можем за полиномиальное время. Задача поиска ответа может быть сложной, но если ответ найден, то существует простой способ проверки его корректности.
Слово «недетерминированный» здесь используется потому, что существует возможность решить NP-задачу при помощи просто вдохновенной догадки. Сделав это, можно проверить и убедиться, что ответ действительно верен (или нет). К примеру, если задача заключается в разложении на простые множители числа 11 111 111 111, то вы можете предположить, что одним из множителей является простое число 21 649. Пока это всего лишь догадка, однако ее легко проверить: достаточно разделить исходное число на 21 649 и посмотреть, что получится. Частное равняется 513 239 точно, без остатка. Таким образом, ваша догадка оказалась верной. А если бы я догадался, что делителем должно быть 21 647 — тоже простое число, то деление привело бы к ответу 513 286 с остатком 9069. Таким образом, догадка оказалась бы неверной.
В данном случае правильное предположение можно сделать только чудом или при помощи обмана (я, кстати, прежде чем высказывать «предположение», разложил 11 111 111 111 на простые множители). Но, по существу, мы хотим именно этого. Если бы наша догадка не была чудесной, то можно было бы превратить алгоритм класса NP в алгоритм класса P очень простым способом: нужно было бы делать предположения одно за другим до тех пор, пока одно из них не оказалось бы верным. Мой пример позволяет увидеть, что так не получится: понадобилось бы слишком много попыток. В самом деле, то, что мы пытаемся делать, это всего лишь «пробное деление» на все возможные простые числа до тех пор, пока одно из них не сработает. Из главы 2 мы знаем, что это далеко не лучший способ искать делители.
Класс NP исключает глупые примеры вроде уже упоминавшегося очень длинного списка. Если кто-то в порыве вдохновения выдаст список всех n-значных двоичных чисел, то экспоненциальное время уйдет не только на то, чтобы их распечатать, но и на то, чтобы их прочесть, и еще больше времени — на то, чтобы проверить список. Это потребовало бы громадных корректорских усилий. Класс P определенно входит составной частью в класс NP. Если ответ можно найти за полиномиальное время, да еще с гарантией его корректности, то это будет означать, что вы его уже проверили. Так что проверка автоматически может быть произведена за полиномиальное время. Если бы кто-то представил вам предполагаемый ответ, то вы могли бы просто прогнать весь алгоритм еще раз — это и стало бы проверкой.
Теперь мы можем сформулировать задачу тысячелетия. Превосходит ли класс NP по размеру класс P или они суть одно и то же? Или короче: равен ли класс P классу NP?
Если ответ «да», то это значит, что существует принципиальная возможность отыскать быстрые и эффективные алгоритмы для автоматического составления расписаний авиарейсов, оптимизации работы завода, выполнения миллиона других важных практических задач. Если ответ «нет», то у нас будет железная гарантия того, что все вроде бы сложные задачи на самом деле сложны, и мы сможем остановиться и не тратить больше времени на поиск быстрых алгоритмов для них. В том и другом случае мы выигрываем. А вот не знать, как в реальности обстоят дела, очень неприятно.
Математикам было бы гораздо легче жить, если бы ответ был «да», поэтому пессимист, живущий в каждом человеческом существе, не может не заподозрить, что на самом деле все не так просто и ответ, скорее всего, окажется «нет». В противном случае мы все получаем бесплатный бонус, который ничем не заработали и которого не заслуживаем. Я, правда, подозреваю, что большинство математиков предпочло бы, чтобы ответ оказался «нет», потому что в этом случае им была бы гарантирована работа до конца времен. Математики самоутверждаются, решая сложные задачи. В общем, по разным причинам большинство математиков и компьютерщиков ожидают, что ответ на вопрос «Совпадает ли P с NP?» будет «Нет». И мало кто ждет, что ответом на самом деле окажется «да».
Помимо этого, возможны еще два варианта. Не исключено, что можно доказать эквивалентность P и NP, не находя в реальности полиномиальных алгоритмов для каждой конкретной NP-задачи. Математике свойственно предлагать нам неконструктивные доказательства существования: они утверждают, что нечто существует, но не говорят, что оно собой представляет и как его найти. В качестве примеров можно назвать методы проверки на простоту, которые бодро сообщают нам, что данное число не является простым, но не называют ни одного конкретного делителя, или теоремы теории чисел, уверяющие нас, что решения некоего диофантова уравнения ограничены, т. е. не превосходят некоторого предела, но не называющие никакого конкретного ограничения. В конце концов, полиномиальный алгоритм может быть настолько сложным, что записать его, в принципе, невозможно. Тогда естественный пессимизм в отношении бесплатного сыра окажется оправдан даже при положительном ответе на вопрос.
Некоторые исследователи высказываются еще более резко: они считают, что вопрос может оказаться нерешаемым в рамках современной математики, ограниченной формальной логикой. Если так, то невозможно доказать ни да ни нет. Не потому, что мы слишком глупы, чтобы найти доказательство, а потому, что такового не существует. Эта идея появилась на свет в 1931 г., когда Курт Гедель выпустил кошку противоречивости охотиться в стаю философских голубей, населявших подвалы математики (он доказал, что некоторые заявления в арифметике неразрешимы). В 1936 г. Алан Тьюринг нашел неразрешимую задачу попроще — задачу об остановке машины Тьюринга. Всегда ли при заданном алгоритме существует доказательство либо того, что машина остановится, либо того, что она будет считать вечно? Как ни удивительно, ответ Тьюринга был «нет». Для некоторых алгоритмов не существует доказательства ни того ни другого. Не исключено, что задача P/NP окажется такой же. Это объяснило бы, почему никто не может ни доказать, ни опровергнуть соответствующее утверждение. Но никто не может также доказать или опровергнуть утверждение о том, что задача P/NP неразрешима. Может быть, ее неразрешимость сама по себе неразрешима…

 

Самый очевидный подход к задаче P/NP состоит в том, чтобы выбрать какую-нибудь задачу, о которой известно, что она относится к классу NP, предположить существование полиномиального алгоритма ее решения — и каким-то образом прийти к противоречию. Некоторое время математики пытались применить эту методику к различным задачам, но в 1971 г. Стивен Кук понял, что выбор задачи часто не играет никакой роли. С определенной точки зрения все подобные задачи — с точностью до некоторых технических особенностей — совершенно равноправны. Кук ввел понятие NP-полной задачи. Такая NP-задача обладает следующим свойством: если для ее решения существует алгоритм класса P, то любая NP-задача может быть решена при помощи алгоритма класса P.
Кук нашел несколько NP-полных задач, включая SAT — задачу о выполнимости булевых формул. В ней спрашивается, можно ли сделать заданное логическое выражение истинным при помощи подходящего выбора значений (истинности или ложности) его переменных. Кроме того, он получил более глубокий результат: задача SAT с дополнительными ограничениями (3-SAT) также является NP-полной. Здесь логическая формула должна быть записана в виде «A, или B, или C, или… или Z», где A, B, C…Z — логические формулы, содержащие по три переменные. Спешу добавить, что переменные не обязаны каждый раз быть одними и теми же. Большинство доказательств того, что та или иная задача является NP-полной, восходят к теореме Кука о 3-SAT.
Определение Кука подразумевает, что все NP-полные задачи существуют на равных основаниях. Доказать, что одна из них на самом деле относится к классу P, означает доказать, что к классу P относятся все такие задачи. Это открывает некоторые тактические возможности: может оказаться, что с некоторыми NP-полными задачами работать проще, чем с остальными. Но стратегически это означает, что с тем же успехом можно выбрать любую конкретную NP-полную задачу и работать именно с ней. Все NP-полные задачи ведут себя одинаково, и поэтому на любой из них можно моделировать все остальные. А любую NP-задачу можно конвертировать в частный случай NP-полной задачи при помощи процедуры «шифрования» — с использованием шифра, на применение которого требуется полиномиальное время.
Чтобы представить себе характер этой процедуры, рассмотрим типичную NP-полную задачу: поиск гамильтонова цикла в сети. Требуется найти замкнутый маршрут по ребрам сети, которые прошел бы через каждый узел (т. е. через каждую точку) ровно один раз. «Замкнутый» означает, что в конце концов маршрут возвращается в начальную точку. Размер входных данных здесь — это число ребер, меньшее или равное квадрату числа точек, поскольку каждое ребро соединяет две точки. (Считаем, что любую заданную пару соединяет не больше одного ребра.) Нам не известно ни одного алгоритма класса P, который решал бы эту задачу, но предположим — гипотетически, — что такой алгоритм существует. Теперь выберем какую-нибудь другую задачу и назовем ее задачей X. Пусть задача X может быть переформулирована в терминах поиска такого маршрута в некоей сети, связанной с задачей X. Если метод перевода данных задачи X в данные об этой сети и наоборот, может быть применен за полиномиальное время, то мы автоматически получаем алгоритм класса P для задачи X. Примерно так:
1. Переводим задачу X в задачу поиска гамильтонова цикла в связанной с задачей сети. Это можно сделать за полиномиальное время.
2. Находим такой цикл за полиномиальное время при помощи того самого гипотетического алгоритма для задачи с сетью.
3. Переводим полученный гамильтонов цикл обратно в решение задачи X, что опять же можно проделать за полиномиальное время.

 

Поскольку все три полиномиальных шага вместе можно проделать тоже за полиномиальное время, этот алгоритм относится к классу P.
Чтобы показать, как это работает, я рассмотрю менее амбициозную версию задачи о поиске гамильтонова цикла, где искомый маршрут не обязан быть замкнутым. В таком виде она называется задачей о поиске гамильтонова пути. Сеть может иметь гамильтонов путь и при этом не иметь цикла (см. пример на рис. 42 слева). Так что решение задачи о поиске гамильтонова цикла может не означать решения задачи о поиске гамильтонова пути. Однако задачу о поиске гамильтонова пути можно переформулировать в задачу о поиске гамильтонова цикла на близкой, но несколько иной сети. Для этого в сеть добавляется одна дополнительная точка, соединенная со всеми точками первоначальной сети, как на рис. 42 справа. Любой гамильтонов цикл в новой сети может быть превращен в гамильтонов путь: для этого достаточно исключить из него добавленный узел и два подходящих к нему ребра цикла. И наоборот, любой гамильтонов путь в первоначальной сети дает цикл в новой: достаточно просто соединить два конца пути с новой точкой. Это «превращение» задачи о поиске пути в задачу о поиске цикла вводит в сеть всего одну новую точку и по одному ребру на каждую точку первоначальной сети, так что эта процедура — и обратная ей тоже — выполняется за полиномиальное время.

 

 

Конечно, я здесь всего лишь зашифровал одну конкретную задачу, превратив ее в задачу о поиске гамильтонова цикла. Чтобы доказать, что такая задача является NP-полной, нам нужно проделать то же самое с любой NP-задачей. Это реально: первое доказательство нашел Ричард Карп в 1972 г. в знаменитой статье, где доказывалась NP-полнота 21 различной задачи.
Задача о коммивояжере является «почти» NP-полной, но здесь есть одна техническая сложность: мы не знаем, относится ли она к классу NP. Известно более 300 конкретных NP-полных задач в различных областях математики, включая логику, теорию графов, комбинаторику и оптимизацию. Доказать, что любая из них может (или не может) быть решена за полиномиальное время, означало бы доказать то же для всех них без исключения. Несмотря на богатство выбора, задача P/NP по-прежнему остается открытой. И я бы не удивился, если бы узнал, что она останется таковой и 100 лет спустя.
Назад: 10. Какой формы сфера? Гипотеза Пуанкаре
Дальше: 12. Потоковое мышление. Уравнение Навье — Стокса

Пупа
Тут что-то перепутали
Грант Геворкян
Доказательство несуществования совершенного кубоида очень просто.