Перше, що потрібно зрозуміти, це те, що P і NP класифікують мови , а не проблеми . Щоб зрозуміти, що це означає, нам спочатку потрібні інші визначення.
Алфавіт є непустою кінцевим безліччю символів.
{ 0
, 1
} - це алфавіт, як і набір символів ASCII. {} - це не алфавіт, оскільки він порожній. N (цілі числа) не є алфавітом, оскільки він не є кінцевим.
Нехай Σ - алфавіт. Впорядкована конкатенація кінцевої кількості символів з Σ називається словом над Σ .
Рядок 101
- це слово над алфавітом { 0
, 1
}. Пусте слово (часто пишеться як е ) слово над будь-яким алфавітом. Рядок penguin
- це слово над алфавітом, що містить символи ASCII. Десяткова запис числа Пі слово в алфавіті { .
, 0
, 1
, 2
, 3
, 4
, 5
, 6
, 7
, 8
, 9
} , тому що це не є кінцевим.
Довжина слова ш , записується в вигляді | w |, - кількість символів у ньому.
Наприклад, | hello
| = 5 і | ε | = 0. Для будь-якого слова w , | w | ∈ N і тому скінченна.
Нехай Σ - алфавіт. Множина Σ * містить усі слова над Σ , включаючи ε . Множина Σ + містить усі слова понад Σ , виключаючи ε . Для n ∈ N , Σ n - це набір слів довжиною n .
Для кожного алфавіту Σ , Σ * і Σ + є нескінченними налічуваними множинами . Для набору символів ASCII Σ ASCII , регулярні вирази .*
і .+
позначають Σ ASCII * і Σ ASCII + відповідно.
{ 0
, 1
} 7 є набір 7-бітових кодів ASCII { 0000000
, 0000001
..., 1111111
}. { 0
, 1
} 32 - це набір 32-бітових цілих значень.
Нехай Σ - алфавіт, а L ⊆ Σ * . L називається мовою над Σ .
Для алфавіту Σ порожній набір та Σ * - тривіальні мови над Σ . Перший часто називають порожньою мовою . Порожня мова {} та мова, що містить лише порожнє слово { ε }, відрізняються.
Підмножина { 0
, 1
} 32, що відповідає значенням з плаваючою точкою без NaN IEEE 754, є кінцевою мовою.
Мови можуть містити нескінченну кількість слів, але кожна мова піддається числу. Безліч рядків { 1
, 2
...} , що позначає цілі числа в десятковій системі числення нескінченного мову над алфавітом { 0
, 1
, 2
, 3
, 4
, 5
, 6
, 7
, 8
, 9
}. Нескінченна безліч ланцюжків { 2
, 3
, 5
, 7
, 11
, 13
, ...} , що позначає прості числа в десятковій системі числення є власним підмножиною їх. Мова, що містить усі слова, що відповідають регулярному виразу, [+-]?\d+\.\d*([eE][+-]?\d+)?
є мовою над набором символів ASCII (позначає підмножину дійсних виразів з плаваючою комою, визначених мовою програмування C).
Немає мови, що містить усі реальні числа (у будь-якій нотації), оскільки набір реальних чисел не піддається обліку.
Нехай Σ - алфавіт, а L ⊆ Σ * . Машина D вирішує L, якщо для кожного входу w ∈ Σ * вона обчислює характерну функцію χ L ( w ) у кінцевий час. Характерна функція визначається як
χ L : Σ * → {0, 1}
w ↦ 1, w ∈ L
0, інакше.
Така машина називається вирішальною для L . Пишемо “ D ( w ) = x ” для “заданих w , D виходів x ”.
Існує багато моделей машин. Найбільш загальною, яка сьогодні практична у використанні, є модель машини Тюрінга . Машина Тьюрінга має необмежену лінійну пам’ять, згруповану в комірки. Кожна комірка може містити рівно один символ алфавіту в будь-який момент часу. Машина Тьюрінга виконує свої обчислення як послідовність етапів обчислення. На кожному кроці він може прочитати одну клітинку, можливо перезаписати її значення і перемістити голову читання / запису на одне положення вліво або вправо. Яку дію буде виконувати машина, контролюється автоматикою з кінцевим станом.
Машина з випадковим доступом з обмеженим набором інструкцій і необмеженим зберіганням - ще одна така модель машини, яка настільки ж потужна, як і модель машини Тюрінга.
Заради цього обговорення ми не будемо заважати точній моделі машини, яку ми використовуємо, але досить сказати, що машина має обмежений детермінований блок управління, необмежене зберігання і виконує обчислення як послідовність кроків, які можна підрахувати.
Оскільки ви використовували це у своєму запитанні, я припускаю, що ви вже знайомі з позначенням "big-O", тому тут є лише швидке оновлення.
Нехай f : N → - функція. Множина O ( f ) містить усі функції g : N → N, для яких існують константи n 0 ∈ N і c ∈ N такі, що для кожного n ∈ N з n > n 0 вірно, що g ( n ) ≤ c f ( п ).
Тепер ми готові підійти до реального питання.
Клас P містить усі мови L, для яких існує машина Тьюрінга D, яка визначає L, і константа k ∈ N така, що для кожного вводу w , D зупиняється після щонайбільше T (| w |) кроків для функції T ∈ O ( n ↦ n k ).
Оскільки O ( n ↦ n k ), хоча і математично правильно, незручно писати і читати, більшість людей - якщо чесно, всі, крім мене, - зазвичай пише просто O ( n k ).
Зауважимо, що пов'язана залежить від довжини w . Отже, аргумент, який ви вносите для мови простих ліній, є правильним лише для чисел у кодах unray , де для кодування w числа n - довжина кодування | w | пропорційна n . Ніхто ніколи не використовує таке кодування на практиці. Використовуючи більш досконалий алгоритм, ніж просто спробувати всі можливі фактори, можна виявити, однак, що мова простих чисел залишається в P, якщо входи кодуються у двійковій формі (або до будь-якої іншої бази). (Незважаючи на величезний інтерес, це могли довести лише Манідра Агравал, Нерадж Каял та Нітін Саксена у нагородженому документі 2004 року, тож можна здогадатися, що алгоритм не дуже простий.)
Тривіальні мови {} і Σ * та нетривіальна мова { ε }, очевидно, є в P (для будь-якого алфавіту Σ ). Чи можете ви писати функції улюбленої мови програмування, які беруть рядок як вхідний і повертають булеву інформацію про те, чи є рядок словом з мови для кожного з них, і довести, що ваша функція має складність поліноміального часу виконання?
Кожен регулярний мову (мова описується регулярним виразом) в P .
Нехай Σ - алфавіт, а L ⊆ Σ * . Машина V, яка приймає закодований кортеж з двох слів w , c ∈ Σ * і виводить 0 або 1 після кінцевого числа кроків, є верифікатором для L, якщо він має такі властивості.
- Беручи під увагу ( ш , з ), V виходи 1 тільки тоді , коли W ∈ L .
- Для кожного w ∈ L існує c ∈ Σ * такий, що V ( w , c ) = 1.
З в наведеному вище визначенні, називається свідком (або сертифікат ).
Верификатор дозволяється давати неправдиві негативи для неправильного свідка , навіть якщо вага на насправді знаходиться в L . Однак не можна давати помилкові позитиви. Також потрібно, щоб у кожному слові на мові був принаймні один свідк.
Для мови КОМПОЗИТ, яка містить десяткові кодування всіх цілих чисел, які не є простими, свідченням може бути факторизація. Наприклад, (659, 709)
є свідком для 467231
∈ COMPOSITE. Ви можете легко переконатися, що на аркуші паперу, не маючи свідків, довести, що 467231 не є простим, було б складно без використання комп’ютера.
Ми нічого не говорили про те, як можна знайти відповідного свідка. Це недетермінована частина.
Клас NP містить усі мови L, для яких існує машина Тьюрінга V, яка перевіряє L і константу k ∈ N таким чином, що для кожного входу ( w , c ) V зупиняється після щонайбільше T (| w |) кроків для функції T ∈ O ( n ↦ n k ).
Зауважимо, що з наведеного визначення випливає, що для кожного w ∈ L існує свідок c з | c | ≤ T (| w |). (Машина Тьюрінга, можливо, не може розглянути більше символів свідка.)
NP - це супермножина P (чому?). Невідомо , чи існують мови, які в NP , але не в P .
Цілісна факторизація - це не сама мова. Однак ми можемо побудувати мову, яка представляє пов'язану з нею проблему рішення . Тобто мова, яка містить усі кортежі ( n , m ) такою, що n має фактор d з d ≤ m . Назвемо цю мову ФАКТОР. Якщо у вас є алгоритм для визначення FACTOR, він може бути використаний для обчислення повної факторизації лише з полиноми накладними, виконуючи рекурсивний бінарний пошук кожного основного фактора.
Неважко показати, що ФАКТОР знаходиться в НП . Відповідним свідком буде просто сам фактор d , і все, що повинен зробити верифікатор, це перевірити, що d ≤ m і n mod d = 0. Все це можна зробити за багаточлен. (Згадаймо ще раз, що саме довжина кодування рахується і є логарифмічною в n .)
Якщо ви можете показати, що FACTOR також знаходиться в P , ви можете бути впевнені, що отримаєте багато прикольних нагород. (І ви зламали значну частину сьогоднішньої криптографії.)
Для кожної мови в НП існує алгоритм грубої сили, який визначає це детерміновано. Він просто здійснює вичерпний пошук усіх свідків. (Зверніть увагу, що максимальна довжина свідка обмежена поліномом.) Отже, ваш алгоритм для визначення PRIMES насправді був алгоритмом грубої сили, щоб вирішити КОМПОЗИТ.
Щоб вирішити ваше останнє питання, нам потрібно ввести скорочення . Скорочення є дуже потужною концепцією теоретичної інформатики. Зведення однієї проблеми до іншої в основному означає вирішення однієї проблеми шляхом вирішення іншої проблеми.
Нехай Σ - алфавіт, а A і B - мови понад Σ . A - багаточлен, багато-один зводиться до B, якщо існує функція f : Σ * → Σ * з такими властивостями.
- w ∈ A ⇔ f ( w ) ∈ B для всіх w ∈ Σ * .
- Функція f може бути обчислена машиною Тьюрінга для кожного вводу w за кілька кроків, обмежених поліном у | w |.
В цьому випадку ми пишемо ≤ р B .
Наприклад, нехай A - мова, яка містить усі графіки (закодовані як матриця суміжності), які містять трикутник. (Трикутник - цикл довжиною 3.) Нехай далі B - мова, яка містить усі матриці з ненульовим слідом. (Слід матриці є сумою його основних діагональних елементів.) Тоді поліноміален багато один зводиться до B . Щоб довести це, нам потрібно знайти відповідну функцію перетворення f . У цьому випадку ми можемо встановити f для обчислення 3- ї потужності матриці суміжності. Для цього потрібні два матрично-матричні вироби, кожен з яких має багаточленну складність.
Це тривіально вірно , що L ≤ р л . (Чи можете ви довести це формально?)
Ми застосуємо це до NP зараз.
Мова L є NP- твердою тоді і тільки тоді, коли L '≤ p L для кожної мови L ' ∈ NP .
An NP -Жорсткий мови може або не може бути в НП сам.
Мова L - NP- незавершена, якщо і лише тоді
- L ∈ NP і
- L є NP -Жорсткий.
Найвідомішою NP- неповною мовою є SAT. Він містить усі булеві формули, які можна задовольнити. Наприклад, ( a ∨ b ) ∧ (¬ a ∨ ¬ b ) ∈ SAT. Дійсний свідок - { a = 1, b = 0}. Формула ( a ∨ b ) ∧ (¬ a ∨ b ) ∧ ¬ b ∉ SAT. (Як би ви це довели?)
Не важко показати, що SAT ∈ NP . Показати NP- стійкість SAT є деякою роботою, але це було зроблено в 1971 році Стівеном Куком .
Після того, як була відома одна NP- неповна мова, було досить просто показати NP- неповноту інших мов за допомогою скорочення. Якщо мова A, як відомо, є NP- твердою, то показуючи, що A ≤ p B означає, що B також NP- твердий (через транзитивність “≤ p ”). У 1972 р. Річард Карп опублікував список з 21 мов, які він міг показати, як NP-повне через (транзитивне) зменшення SAT. (Це єдиний документ у цій відповіді, який я насправді рекомендую прочитати. На відміну від інших, це не важко зрозуміти і дає дуже гарне уявлення про те, як працює доведення NP- незавершеності за допомогою скорочення.)
Нарешті, короткий підсумок. Ми будемо використовувати символи NPH та NPC для позначення класів мов NP- твердих та NP- неповних відповідно.
- P ⊆ NP
- NPC ⊂ NP та NPC ⊂ NPH , власне NPC = NP ∩ NPH за визначенням
- ( A ∈ NP ) ∧ ( B ∈ NPH ) ⇒ A ≤ p B
Зауважте, що включення NPC ⊂ NP є правильним навіть у випадку, якщо P = NP . Щоб побачити це, зробити собі ясно , що ні одна нетривіального мова не може бути зведений до тривіального і є тривіальні мови в P , а також нетривіальні мови в НП . Хоча це (не дуже цікавий) кутовий випадок.
Додаток
Вашим основним джерелом плутанини здається, що ви думали про " n " в " O ( n ↦ f ( n ))" як інтерпретацію введення алгоритму, коли воно насправді стосується довжини введення. Це важлива відмінність, оскільки це означає, що асимптотична складність алгоритму залежить від кодування, що використовується для введення.
Цього тижня був досягнутий новий рекорд найбільшого відомого прем'єра Мерсенна . Найбільший на даний момент простий номер - 2 74 207 281 - 1. Це число настільки величезне, що болить у мене, тому я буду використовувати менший на наступному прикладі: 2 31 - 1 = 2 147 483 647. Це може бути кодованим по-різному.
- за його показником Мерсенна як десяткове число:
31
(2 байти)
- як десяткове число:
2147483647
(10 байт)
- як одинарне число:
11111…11
де його …
слід замінити на 2 147 483 640 більше 1
с (майже 2 ГБ)
Усі ці рядки кодують одне і те ж число і з урахуванням будь-якого з них ми можемо легко побудувати будь-яке інше кодування з того ж числа. (Ви можете замінити десяткове кодування двійковим, восьмеричним або шістнадцятковим, якщо ви хочете. Це змінює лише довжину на постійний множник.)
Наївний алгоритм тестування первинності є лише многочленом для одинарних кодувань. Тест первинності AKS є многочленом для десяткової (або будь-якої іншої основи b ≥ 2). Тест простоти люка-Лемера є найбільш відомим алгоритмом для простих чисел Мерсенна М р з р непарне просте число , але він по - , як і раніше експоненту в довжині двійкового кодування Mersenne показника ступеня р (полінома в р ).
Якщо ми хочемо поговорити про складність алгоритму, дуже важливо, щоб нам було дуже зрозуміло, яке представлення ми використовуємо. Загалом можна припустити, що використовується найефективніше кодування. Тобто двійкові для цілих чисел. (Зверніть увагу, що не кожне просте число є простим рівнем Мерсенна, тому використання показника Мерсенна не є загальною схемою кодування.)
У теоретичній криптографії багатьом алгоритмам формально передається абсолютно марний рядок k 1
s як перший параметр. Алгоритм ніколи не розглядає цей параметр, але він дозволяє йому формально бути многочленом в k , що є параметром захисту, який використовується для налаштування безпеки процедури.
Для деяких проблем, щодо яких мова прийняття рішення у двійковому кодуванні є NP- незавершеною, мова рішення більше не є NP- завершеною, якщо кодування вбудованих чисел переключено на одинакове. Мови вирішення інших проблем залишаються NP- незавершеними навіть тоді. Останні називаються сильно NP -повними . Найвідоміший приклад - упаковка у смітник .
Також цікаво спостерігати, як змінюється складність алгоритму, якщо введення стискається . На прикладі праймерів Мерсенна ми побачили три кодування, кожне з яких логарифмічно більш стиснене, ніж його попередник.
У 1983 році Хана Гальперін та Аві Вігдерсон написали цікавий документ про складність загальних алгоритмів графіків, коли вхідне кодування графіка стискається логарифмічно. Для цих входів мова графіків, що містять трикутник зверху (де це було чітко в Р ), раптом стає NP- незавершеною.
І це тому, що мовні класи на зразок P і NP визначені для мов , а не для проблем .