배낭 문제가 의사 다항식 인 이유는 무엇입니까?


87

KnapsackDP로 해결할 수 있지만 NP 완전 하다는 것을 알고 있습니다. 그들은 DP 솔루션이 pseudo-polynomial"입력 길이"(즉, 입력을 인코딩하는 데 필요한 비트 수)에서 지수이기 때문에 라고 말합니다 . 불행히도 나는 그것을 얻지 못했습니다. 아무도 그 pseudo-polynomial일을 천천히 설명 할 수 있습니까 ?


답변:


89

실행 시간은 항목 및 N 크기의 배낭 W. W와 바운드 배낭 문제에 대한 O (NW)에 그것이 무엇이 인 것처럼 입력의 길이 다항식하지 않다 를 의사 -polynomial.

W = 1,000,000,000,000을 고려하십시오. 이 숫자를 표현하는 데 40 비트 만 필요하므로 입력 크기 = 40이지만 계산 런타임은 인수 1,000,000,000,000, 즉 O (2 40 )를 사용합니다.

따라서 런타임은 더 정확하게 O ( W의 N.2 비트 ) 라고 말하며 이는 지수 적입니다.

참조 :


1
"0-1 배낭 문제에 대한 동적 프로그래밍의 복잡성"을 참조하는 링크 # 3은 죽었습니다.
dev_nut

1
죄송합니다. 인식하지 못했습니다. 시간 복잡도가 O (N) 인 알고리즘이있는 경우 O (2 ^ (N의 비트))가 있는데 이는 지수 적입니까? 감사합니다 ~
Lusha Li

3
@LushaLi 이것은 나를 도왔습니다 : youtube.com/watch?v=9oI7fg-MIpE . N이 각 요소에 고정 된 최대 크기 입력이있는 배열이고 (배열의 각 요소가 32 비트 이하)이 배열에서 for 루프를 한 번 실행하면 입력에서 다항식 시간 알고리즘입니다. 배열의 크기 N. 그러나 N이 정수이고 N에 대해 루프를 실행하면 N은 제한되지 않고이를 나타내는 데 필요한 비트 수에서 기하 급수적으로 증가합니다. 따라서 N에 대한 간단한 for 루프는 실제로 지수 적입니다. 배열의 경우 배열에있는 각 요소의 크기가 상한이었습니다.
max_max_mir

나는 확신하지 못했습니다. "의사 다항식"이 아닌 동일한 속성을 가진 알고리즘이 많이 있습니다. Sieve of Eratosthenes (또는 다른 소수 찾기)의 복잡성은 무엇입니까?
Ofir A.

31

대부분의 문제에서 우리는 표준 int / float 데이터 유형에 편안하게 맞는 많은 숫자 목록을 다루고 있습니다. 대부분의 프로세서가 추가 비용없이 한 번에 4-8 바이트 숫자를 처리하도록 구축 된 방식 (예 : 1 바이트에 맞는 숫자에 비해) 때문에 숫자를 늘리거나 실제 문제에서 발생하는 범위 내에서 아래로 내려갑니다. 따라서 지배적 인 요소는 우리가 익숙한 n 또는 m 요소 인 순수한 양의 데이터 포인트로 남아 있습니다.

(Big-O 표기법이 데이터 당 32 비트 또는 64 비트를 나누는 상수 요소를 숨기고 있으며, 각 숫자가 해당 수 이하의 비트에 맞을 때마다 데이터 포인트 수만 남긴다고 상상할 수 있습니다. )

그러나 다른 알고리즘으로 재 작업하여 큰 정수 (표현하는 데 8 바이트 이상이 필요한 숫자)와 관련된 데이터 세트에 대해 조치를 취하고 런타임에 어떤 영향을 미치는지 확인하십시오. 관련된 숫자의 크기는 바이너리 정렬과 같은 다른 알고리즘에서도 항상 차이를 만듭니다. 기존 프로세서의 버퍼를 넘어 확장하면 4-8 바이트 배치를 처리하여 "무료"를 제공합니다.

우리가 논의한 Knapsack 알고리즘의 트릭은 특정 매개 변수 W의 크기에 비정상적으로 민감하다는 것입니다 (다른 알고리즘에 비해 상대적으로). W에 1 비트를 더하면 알고리즘의 실행 시간이 두 배가됩니다. 우리는이 알고리즘 이전에 다른 알고리즘의 가치 변화에 대한 극적인 반응을 보지 못했습니다. 이것이 우리가 Knapsack을 다르게 취급하는 것처럼 보일 수도있는 이유입니다. 입력 크기 변경.


8

Knapsack 알고리즘의 실행 시간은 입력 크기 (n-항목 수)뿐만 아니라 입력 크기 (W-배낭 용량) O (nW)에도 제한됩니다. 컴퓨터에서 이진수로 표현 (2 ^ n). 계산 복잡성 (즉, 비트를 통해 컴퓨터 내부에서 처리가 수행되는 방식)은 입력크기 / 값이 아닌 입력크기 에만 관련 됩니다 .

잠시 값 / 가중치 목록을 무시하십시오. 배낭 용량이 2 인 인스턴스가 있다고 가정 해 보겠습니다. W는 입력 데이터에서 2 비트를 사용합니다. 이제 나머지 입력을 유지하면서 배낭 용량을 4로 늘릴 것입니다. 입력은 1 비트 만 증가했지만 계산 복잡성은 두 배로 증가했습니다. 용량을 1024로 늘리면 W에 대한 입력의 2 개가 아닌 10 비트 만 가지지 만 복잡성은 512 배 증가했습니다. 시간 복잡성은 이진 (또는 십진수) 표현에서 W의 크기에서 기하 급수적으로 증가합니다. .

의사 다항식 개념을 이해하는 데 도움이 된 또 다른 간단한 예는 순진한 소수성 테스트 알고리즘입니다. 주어진 숫자 n에 대해 2..√n 범위의 각 정수로 균등하게 나뉘 었는지 확인하므로 알고리즘은 √ (n-1) 단계를 수행합니다. 그러나 여기서 n은 크기가 아니라 입력의 크기입니다.

                     Now The regular O(n) case

반대로 주어진 요소에 대한 배열 검색은 다항식 시간 O (n)에서 실행됩니다. 최대 n 단계가 걸리며 여기서 n은 입력의 크기 (배열의 길이)입니다.

[ 여길 봐 ]

10 진수 저장에 필요한 비트 계산


3
마지막 검색 예제에서 n도 바이너리로 간주하지 않는 이유는 무엇입니까? n = 1024이면 10 비트 만 필요하므로 의사 다항식이어야하지 않습니까?
user1024

7

내가 이해하는 방식은 용량 입력 이 W 의 크기를 갖는 [1,2, ..., W]의 배열 이면 용량이 O (W) 였을 것 입니다. 그러나 용량 입력은 그렇지 않습니다. 숫자 배열, 대신 단일 정수입니다. 시간 복잡성은 입력 크기 와 의 관계 에 관한 것 입니다. 정수 의 크기 는 정수의 값이 아니라이를 나타내는 비트 수입니다. 우리는 나중에이 정수 W를 알고리즘에서 배열 [1,2, ..., W]로 변환하여 사람들이 W가 크기라고 잘못 생각하게 만들지 만이 배열은 입력이 아니라 정수 자체입니다.

입력을 "물건의 배열"로 생각하고 크기를 "배열에있는 물건의 수"로 생각하십시오. 항목 입력은 실제로 배열에있는 n 항목의 배열이므로 size = n입니다. 용량 입력은 그 안에 있는 W 숫자의 배열이 아니라 log (W) 비트 배열로 표현되는 단일 정수 입니다. 크기를 1 씩 늘리면 (의미있는 비트 1 개 추가) W가 두 배가되어 런타임이 두 배가되므로 지수 시간이 복잡해집니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.