효율적으로 메모리 오버 헤드가 적은 복제본 제거


9

결과 집합 만 저장 해야하는 방식으로 중복 정수 목록을 효율적으로 필터링하고 싶습니다.

한 가지 방법은 이것을 볼 수 있습니다.

  • 우리는 정수의 범위를 가지고 있습니다 S={1,,N}N 큰 (말 240)
  • 우리는 기능이있다 f:SS 아마도 많은 충돌과 함께 (이미지는 S)
  • 우리는 다음 저장해야합니다 f[S], 그건 {f(x)|xS}

나는 무엇에 대한 상당히 정확한 (확률 적) 추정을 가지고 있습니다. |f[S]| 따라서 데이터 구조를 미리 할당 할 수 있습니다 (예 : |f[S]|230).

몇 가지 아이디어가 있었지만 가장 좋은 방법은 무엇인지 잘 모르겠습니다.

  • 입력 세트가 메모리에 맞지 않기 때문에 비트 세트에 문제가 없습니다.
  • 해시 테이블이지만 (1) 150 %의 메모리 오버 헤드가 필요합니다. |f[S]| (2) 메모리 오버 헤드로 인해 추가 시간이 필요한 빌드시 테이블을 탐색해야합니다.
  • "바로"정렬, 바람직하게는 O(N)복잡성 (비 비교 정렬). 그것에 대해, bucket sortflashsort 의 주요 차이점이 무엇인지 잘 모르겠습니다 .
  • 이진 검색 트리가있는 간단한 배열이지만 O(Nlog|f[S]|) 시각.
  • 아마도 사용하는 블룸 필터 또는 유사한 데이터 구조는 문제의 (잘못된 반응로) 완화에 도움이 될 수 있습니다.

stackoverflow에 대한 몇 가지 질문은 이런 종류의 문제와 관련이있는 것 같습니다 ( /programming/12240997/sorting-array-in-on-run-time , /programming/3951547/java -array-finding-duplicates ), 그러나 내 요구 사항과 일치하는 것은 없습니다.


2
f [S] (무엇이든)를 열거해야합니까, 아니면 일부 x가 들어 있는지 여부를 빠르게 알 수 있어야합니까?
Gilles 'SO- 악마 중지'

@Gilles : f [S]에서 명백한 구조를 찾을 수 없기 때문에 두 솔루션은 동일하다고 생각합니다.
doc

당신의 숫자는 합산되지 않습니다. 크기 영역에서 임의 함수의 예상 이미지N 대략 (11/e)N. 또 다른 문제는256슈퍼 컴퓨터 나 대규모 클러스터가없는 한 시간이 오래 걸릴 것입니다.
Yuval Filmus

1
이진 검색 트리의 시간은 O(Nlog|f[S]|)에 근접하거나 근접하지 않을 수 있습니다. O(NlogN)실제로는 더 정확합니다.
jmad

1
N256선형 시간 알고리즘도 금지되지 않습니까? (내 계산에서 한 요소를 고려하더라도S1 나노초 안에 2 년이면 좋을 것입니다!).
Aryabhata

답변:


1

왜 빈과 체인을 사용하지 않습니까?

아이디어는 다음과 같이 나타낼 수있는 양의 정수를 저장하는 것입니다. n=k+m 배열의 비트 A2k 값 범위를 나타내는 항목 : 항목 A[y], y0, 범위를 나타냅니다 [2my,2m(y+1)1]. 어떠한 것도1x<2n 우리는 쓸지도 모른다 x=2my+z 어디 y 있다 k 비트와 z 있다 m비트. 저장하려고z (아니 x!) 위치 y:

  • 언제 A[y]=z 이미 아무것도하지 마십시오 : x 중복입니다.

  • 언제 A[y] 초기화되지 않은, 저장 z ...에서 A[y].

  • 그렇지 않으면 인덱스를 체인에 사용되는 별도의 배열에 저장하십시오. z의 (에 충돌 한 y)를 링크 된 목록에 있습니다. 제목이있는 목록을 선형으로 검색해야합니다.A[y] 검색 결과에 따라 잠재적으로 삽입 z 목록으로.

결국 f(S) 초기화 된 항목을 반복하여 복구하기 쉽습니다. A 그리고 단지 두 개의 비트 열을 연결함으로써 각각을 재 조립 z 위치에서 발견 y (직접 또는 체인 내에서 참조 된) 원래 값으로 x=2my+z.

분포가 균일 할 때 2k 초과 N체인이 많지 않고 (일반적인 방법으로 평가할 수 있음) 체인이 짧을 수 있습니다. 분포가 균일하지 않은 경우 알고리즘은 계속 작동하지만 2 차 타이밍에 도달 할 수 있습니다. 이것이 가능하다면 체인보다 효율적인 것을 사용하십시오 (그리고 스토리지에 약간의 오버 헤드를 지불하십시오).

필요한 스토리지는 최대 2n 비트 A22k 체인의 비트 (가정) mk). 이것은 정확하게 저장하는 데 필요한 공간입니다2k ~의 가치 n각각 비트. 균일성에 확신이있는 경우 체인의 스토리지를 할당 할 수 없습니다. 불균일 가능성이있는 경우 증가시킬 수 있습니다k 체인 스토리지를 완전히 옹호하십시오.

이 솔루션에 대해 생각할 수있는 다른 방법은 해시 테이블이 특히 훌륭 하다는 것 입니다 .k 가장 중요한 비트) 및 그로 인해 가장 중요한 비트 만 저장하면됩니다. m=nk 테이블의 비트.

체인의 스토리지를 스토리지와 오버레이하는 방법이 있습니다. A 그러나 많은 비용을 절약하지 않기 때문에 귀찮은 가치가없는 것 같습니다 ( m 보다 훨씬 작다 k) 공간을 확보하고 코드를 개발, 디버그 및 유지 관리하기 어렵게 만듭니다.


1
나는 두 번째에서 마지막 단락이 여기의 중심 단락이라고 생각합니다 (아마도). "bin and chain"이라는 용어를 모르겠습니다 (소식을 읽은 후에는 의미가 있지만). 이 아이디어는 시도 로 확장 될 수 있습니다 .
Raphael

그래서 이것은 Θ(n2)잘못 분배 된 입력에. 이것이 얼마나 효율적인지 모르겠습니다.
einpoklum

@einpoklum이 답변은 솔루션이 효율적인 조건을 명시 적으로 설명합니다.
whuber
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.