Ми знаємо, що проблему рюкзака можна розв’язати за складності O (nW) за допомогою динамічного програмування. Але ми говоримо, що це проблема, яка повна NP. Я відчуваю, що тут важко зрозуміти.
(n - кількість предметів. W - максимальний обсяг.)
Ми знаємо, що проблему рюкзака можна розв’язати за складності O (nW) за допомогою динамічного програмування. Але ми говоримо, що це проблема, яка повна NP. Я відчуваю, що тут важко зрозуміти.
(n - кількість предметів. W - максимальний обсяг.)
Відповіді:
O(n*W)виглядає як поліноміальний час, але це не так , це псевдополіном .
Складність часу вимірює час, який приймає алгоритм як функцію довжини в бітах його вводу. Рішення для динамічного програмування справді має лінійне значенняW , але експоненціальне за довжиноюW - і ось що важливо!
Точніше, часова складність динамічного рішення проблеми рюкзака в основному задається вкладеним циклом:
// here goes other stuff we don't care about
for (i = 1 to n)
for (j = 0 to W)
// here goes other stuff
Таким чином, складність часу очевидно O(n*W).
Що означає лінійно збільшувати розмір вводу алгоритму? Це означає використання прогресивно довші масиви записи (так n, n+1, n+2, ...) і прогресивний більше W(так, якщо Wце xбіти, після одного кроку ми використовуємо x+1біти, потім x+2біти, ...). Але значення з Wекспоненціально зростає з збільшенням x, таким чином , алгоритм не надто Поліном, це експоненціальне (але, схоже , що поліном, звідси і назва: «псевдо-многочлен»).
Wі nтут представляють кількість ітерацій циклу. Ви можете кодувати їх як завгодно, і цей цикл все ще буде повторюватися n * Wразів. Я вважаю, що причина цього "псевдо-полінома" полягає в тому n, що це фактичний розмір вхідних даних, і він Wможе бути набагато більшим, ніж nце не може справедливо трактуватися як константа.
forцикл, який йде від 1до n(де nвхід); у цьому випадку, коли ваш цикл робить 10 ^ 12 ітерацій, розмір вводу все ще становить близько 40 бітів. Кількість ітерацій зростає швидше, ніж кількість бітів для кодування вхідних даних. Складність часу не є лінійною. 2) знову розглянемо forцикл, який ітерацію над вхідним масивом (із розміром n) від 1до n; якщо у вас є 10 ^ 12 ітерацій, то це означає, що ваш масив містить 10 ^ 12 елементів. Кількість ітерацій зростає з однаковим темпом, як і розмір вхідних даних. Час компл. є лінійним.
У проблемі рюкзака 0/1 нам потрібні 2 входи (1 масив і 1 ціле число) для вирішення цієї проблеми:
Припустимо, що n = 10 і W = 8:
отже, тимчасова складність T (n) = O (nW) = O (10 * 8) = O (80)
Якщо подвоїти розмір n :
n = [n1, n2, n3, ..., n10 ] -> n = [n1, n2, n3, ..., n20 ]
отже, складність часу T (n) = O (nW) = O (20 * 8) = O (160)
але оскільки ви подвоюєте розмір W , це не означає W = 16, але довжина буде вдвічі більше:
W = 1000 -> W = 10000000 у двійковому виразі (8-бітний)
так T (n) = O (nW) = O (10 * 128) = O (1280)
необхідний час збільшується в експоненціальному вираженні, тож це проблема NPC.
Все залежить від того, які параметри ви ввели всередину O(...).
Якщо цільова вага обмежена кількістю W, то проблема має O(n*W)складність, як ви вже згадували.
Але якщо ваги занадто великі і вам потрібен алгоритм зі складністю, що не залежить від W, тоді проблема NP-повна. ( O(2^n*n)у більшості наївних реалізацій).
Це пояснюється тим, що проблема рюкзака має псевдополіноміальне рішення, і тому її називають слабо NP-повною (і не сильно NP-повною ).
Розмір вхідних даних - це log(W)біти для ваги (а також O(n)для масивів "значення" та "вага").
Отже, введений розмір ваги j = log(W)(і не просто W). Отже, W = 2ʲ(як використовується двійковий файл).
Остаточна складність O(n * W)
Це
O(n * W)можна переписати якO(n * 2ʲ), який експоненціально за розміром вводу.
Отже, це рішення не є поліномним.
Ви можете прочитати це коротке пояснення: NP-комплектність рюкзака .
Щоб зрозуміти NP-повноту , вам доведеться вивчити трохи теорії складності. Однак, в основному, це NP-повно, оскільки ефективний алгоритм для проблеми рюкзака також буде ефективним алгоритмом для SAT , TSP та решти.