작은 메모리 풋 프린트로 구현 구현 찾기


9

세트 데이터 유형의 구현을 찾고 있습니다. 즉, 우리는

  • 동적 서브 세트 유지 (크기의 우주에서) 크기의 USnU={0,1,2,3,,u1}u
  • 작업 insert(x)(추가 원소 xS 등) find(x)(요소가 있는지 확인 x하는 부재 인 S ).

다른 작업은 신경 쓰지 않습니다. 오리엔테이션을 위해 작업중 인 응용 프로그램에는 u1010 있습니다.

O (1) 시간에 두 작업을 모두 제공하는 구현에 대해 알고 O(1)있으므로 데이터 구조의 크기에 대해 대부분 걱정합니다. 나는 수십억 개의 항목을 기대 하지만 가능한 한 많이 교환하지 않기를 원합니다.

필요한 경우 런타임을 기꺼이 희생합니다. O (\ log n) 의 상각 런타임은 O(logn)내가 인정할 수있는 것입니다. \ omega (\ log n)의 예상 런타임 또는 런타임은 ω(logn)허용되지 않습니다.

내가 가진 한 가지 아이디어는 S 가 범위의 합집합으로 표현 [xmin, xmax]될 수 있다면 성능이 약간 저하 된 가격으로 스토리지 크기를 절약 할 수 있다는 것입니다. 또한와 같은 일부 다른 데이터 패턴이 가능합니다 [0, 2, 4, 6].

그런 식으로 할 수있는 데이터 구조를 알려주시겠습니까?



어떻게 숫자 않습니다 요소는 사진을 입력? 즉, 요소가 삽입되어 있고 이미 이 있으면 어떻게됩니까 ? nn
vonbrand

@vonbrand- n는 세트 S의 크기입니다. 모든로 증가 insert하거나 요소 x가 이미 세트에있는 경우 동일하게 유지 될 수 있습니다 .
HEKTO

3
약간의 오 탐지를 받아 들일 수 있습니까? 그렇다면 블룸 필터가 이상적 일 수 있습니다. en.wikipedia.org/wiki/Bloom_filter
Joe

1
@AlekseyYakovlev, 블룸 필터의 오 탐지율은 유니버스 크기 (해시 함수의 수 , 데이터 구조의 크기 및 항목 수 에만 해당)와 관련이 없지만 실제로는 가까우면 (예 를 들어 작은 상수 ) 공간의 총 비트 만으로 생각하는 간단한 비트 벡터보다 더 잘 수행하기가 쉽지 않습니다 . kmnnuu=ncccn
Joe

답변:


8

Joe의 답변은 매우 훌륭하며 모든 중요한 키워드를 제공합니다.

간결한 데이터 구조 연구는 아직 초기 단계에 있으며 많은 결과는 대체로 이론적입니다. 제안 된 데이터 구조는 구현하기가 상당히 복잡하지만 대부분의 복잡성은 유니버스 크기와 저장된 요소 수 모두에서 점근 적 복잡성을 유지해야하기 때문입니다. 이들 중 하나가 비교적 일정하면 많은 복잡성이 사라집니다.

컬렉션이 반 정적 인 경우 (즉, 삽입물이 드물거나 최소한 소량) 업데이트와 함께 구현하기 쉬운 정적 데이터 구조 (Sadakane의 sdarray가 좋습니다)를 고려할 가치가 있습니다. 은닉처. 기본적으로 기존 데이터 구조 (예 : B- 트리, 트리, 해시 테이블)에 업데이트를 기록하고 "메인"데이터 구조를 주기적으로 대량 업데이트합니다. 반전 된 인덱스는 검색에 많은 이점이 있지만 그 자리에서 업데이트하기 어렵 기 때문에 정보 검색에서 매우 널리 사용되는 기술입니다. 이 경우 의견에 알려주십시오.이 답변을 수정하여 몇 가지 조언을 드리겠습니다.

삽입이 더 빈번하다면 간결한 해싱을 제안합니다. 기본 아이디어는 여기에 설명하기에 간단합니다. 그렇게하겠습니다.

따라서 기본 정보 이론적 결과는 항목 의 유니버스에서 요소를 저장 하고 다른 정보가없는 경우 (예 : 요소 간의 상관 관계가없는 경우) 그것을 저장하는 비트. (달리 명시되지 않는 한 모든 로그는 밑이 2입니다.) 이 비트 가 필요 합니다. 그 주위에 방법이 없습니다.nulog(un)+O(1)

이제 몇 가지 용어 :

  • 데이터를 저장하고 비트의 공간 에서 작업을 지원할 수있는 데이터 구조가있는 경우 이를 암시 적 데이터 구조라고합니다.log(un)+O(1)
  • 데이터를 저장하고 데이터를 저장할 수있는 데이터 구조가있는 경우 비트의 공간을 하면이 데이터를 컴팩트 한 데이터 구조라고합니다. 실제로 이것은 이론상 최소값에 상대적인 상대적 오버 헤드가 일정하다는 것을 의미합니다. 5 % 오버 헤드, 10 % 오버 헤드 또는 10 배 오버 헤드 일 수 있습니다.log(un)+O(log(un))=(1+O(1))log(un)
  • 데이터를 저장하고 작업을 지원할 수있는 데이터 구조가있는 경우 공간의 비트를 하면 간결한 데이터 구조라고합니다.log(un)+o(log(un))=(1+o(1))log(un)

간결함과 컴팩트 함의 차이는 little-oh와 big-oh의 차이입니다. 잠시 동안 절대 값을 무시하는 중 ...

  • g(n)=O(f(n)) 은 모든 , 과 같이 상수 와 숫자 이 있음을 의미합니다 .cn0n>n0g(n)<cf(n)
  • g(n)=o(f(n)) 은 모든 상수 에 대해 , 과 같은 숫자가 있음을 의미합니다 .cn0n>n0g(n)<cf(n)

비공식적으로, big-oh 및 little-oh는 모두 "상수 요소 내"이지만, big-oh를 사용하면 알고리즘 알고리즘, CPU 제조업체, 물리 법칙 등에 의해 상수가 선택되지만 -오직 상수를 직접 선택하면 원하는만큼 작을 수 있습니다 . 간결한 데이터 구조를 사용하면 문제의 크기가 커질수록 상대적인 오버 헤드가 임의로 작아집니다.

물론, 원하는 상대적인 오버 헤드를 실현하기 위해 문제의 크기가 커져야 할 수도 있지만 모든 것을 가질 수는 없습니다.

자, 우리 벨트 아래에 문제에 대한 숫자를 적어 봅시다. 키가 비트 정수 (유니버스 크기는 )라고 가정하고 의 정수 를 저장하려고합니다 . 완벽한 점유율과 낭비없이 이상적인 해시 테이블을 마술처럼 정렬하여 정확히 해시 슬롯이 필요하다고 가정 해 봅시다 .n2n2m2m

조회 작업은 비트 키를 해시하고 비트를 마스크 해제 하여 해시 슬롯을 찾은 다음 테이블의 값이 키와 일치하는지 확인합니다. 여태까지는 그런대로 잘됐다.nm

이러한 해시 테이블은 비트를 사용합니다. 이보다 더 잘할 수 있습니까?n2m

해시 함수 가 뒤집을 수 없다고 가정하십시오 . 그런 다음 각 해시 슬롯에 전체 키를 저장할 필요가 없습니다. 해시 슬롯의 위치는 비트의 해시 값을 제공하므로 남은 비트 만 저장 한 경우이 두 가지 정보 (해시 슬롯 위치 및 저장된 값)에서 키를 재구성 할 수 있습니다. 따라서 비트의 저장 공간 만 있으면 됩니다.hmnm(nm)2m

경우 비교 작 , 스털링 근사 조금 산술 (! 증거 운동 임) 것을 알 :2m2n

(nm)2m=log(2n2m)+o(log(2n2m))

따라서이 데이터 구조는 간결합니다.

그러나 두 가지가 있습니다.

첫 번째 캐치는 "좋은"가역적 인 해시 함수를 만드는 것입니다. 다행히도 이것은보기보다 훨씬 쉽습니다. 암호 전문가는 항상 뒤집을 수없는 기능을 만들고 오직 "암호 자"라고 부릅니다. 예를 들어, Feistel 네트워크를 기반으로 해시 함수를 만들 수 있는데, 이는 비가역 해시 함수에서 비가역 해시 함수를 구성하는 간단한 방법입니다.

두 번째는 생일 역설 덕분에 실제 해시 테이블이 이상적이지 않다는 것입니다. 따라서 더 복잡한 유형의 해시 테이블을 사용하여 유출없이 전체 점유율에 더 가까이 다가 가고 싶습니다. 뻐꾸기 해싱은 이론에 이상적으로 접근 할 수 있고 실제로는 매우 근접 할 수 있기 때문에 완벽합니다.

뻐꾸기 해싱에는 여러 해시 함수가 필요하며 해시 슬롯의 값에 사용 된 해시 함수 태그가 필요합니다. 예를 들어 네 개의 해시 함수를 사용하는 경우 각 해시 슬롯에 추가 2 비트를 저장해야합니다. 이것은 이 자라 면서 간결 하므로 실제로 문제가되지는 않지만 전체 키를 저장하는 것보다 여전히 뛰어납니다.m

아, 당신은 또한 반 엠드 보아스 나무를보고 싶을 수도 있습니다.

더 생각

경우 어딘가에있다 , 다음 약 값과 더 상관 관계가 없다고 가정 때문에 (다시 한번), 당신은 기본적으로 작업을 수행 할 수 비트 벡터보다 낫습니다. 위의 해싱 솔루션은이 경우 효과적으로 해체되지만 (해시 슬롯 당 1 비트를 저장하게 됨) 해시 함수를 사용하는 대신 키를 주소로 사용하는 것이 더 저렴합니다.nu2log(un)u

이 매우 가까운 경우 모든 간결한 데이터 구조 문헌에서 사전의 의미를 뒤집을 것을 권장합니다. 세트에서 발생 하지 않는 값을 저장하십시오 . 그러나 이제 삭제 작업을 효과적으로 지원하고 간결한 동작을 유지하려면 더 많은 요소가 "추가"될 때 데이터 구조를 축소 할 수 있어야합니다. 해시 테이블 확장은 잘 이해 된 작업이지만 계약하지는 않습니다.nu


안녕하세요, 귀하의 답변의 두 번째 단락에 관해서는-모든 전화 에는 동일한 주장으로 insert전화가 올 것으로 기대합니다 find. 따라서 find반환 true하면을 건너 뜁니다 insert. 따라서, 주파수 find호출은 더 다음의 주파수 insert경우에도 통화 n에 가까운되고 u, 다음 insert호출은 매우 드문된다.
HEKTO

그러나 당신은 가 가까워 질 것으로 기대 합니까? un
가명

현실 세계에서 n이 u에 도달 할 때까지 성장하고 있지만 우리는 그것이 일어날 지 예측할 수 없습니다. 데이터 구조는 다음과 같이 잘 작동해야합니다.n <= u
HEKTO

권리. 그렇다면 간결하고 (위의 의미에서) 전체 범위에서이를 달성하는 단일 데이터 구조를 알지 못한다는 것은 공정한 일 입니다. 나는 당신이 일 때 희소 데이터 구조를 원할 것이라고 생각합니다 이 주위에 있을 때 밀도가 높은 것 (예 : 비트 벡터)으로 전환 한 다음 거꾸로 된 희소 데이터 구조 이 가까울 때 감지합니다 . nun<unu2nu
가명

5

동적 멤버쉽 문제에 대한 간결한 데이터 구조를 원하는 것처럼 들립니다 .

리콜는 것을 간결 데이터 구조는 공간 요구 사항은에 "가까운"되는 하나의 정보 이론적 하한하지만 압축 된 데이터 구조와는 달리, 여전히 효율적인 쿼리 할 수 있습니다.

회원 문제는 당신이 당신의 질문에 설명 정확히 :

서브셋 유지 (크기의 우주에서) 크기의 조작으로 :SnU={0,1,2,3,,u1}u

  • find(x)(element x가 의 멤버 인지 확인 )S
  • insert(x)(추가 원소 x에 )S
  • delete(x)(소자 분리 x에서 )S

find작업 만 지원되는 경우 이는 정적 멤버쉽 문제입니다. 둘 중 하나 insert또는 delete둘 다 지원되는 경우 이를 semi-dynamic 이라고 하고 세 가지 작업이 모두 지원되는 경우이를 동적 멤버쉽 문제 라고합니다 .

기술적으로, 반동적 멤버쉽 문제에 대한 데이터 구조 만 요청했지만이 제약 조건을 활용하고 다른 요구 사항을 충족하는 데이터 구조는 알 수 없습니다. 그러나 다음 참조가 있습니다.

정시 및 거의 최소 공간 멤버쉽 기사의 정리 5.1 에서 Brodnik과 Munro는 다음과 같은 결과를 제공합니다.

일정한 시간에 검색을 지원하고 일정한 예상 상각 시간에 삽입 및 삭제를 지원 하는 비트가 필요한 데이터 구조가 있습니다 .O(B)

여기서 은 정보 이론상 필요한 최소 비트 수입니다.B=log(un)

기본 아이디어는 우주를 신중하게 선택한 크기의 범위로 재귀 적으로 나눕니다. 따라서 기술조차도 생각하는 선을 따르는 것처럼 들립니다.

그러나 실제로 구현할 수있는 것을 찾고 있다면 이것이 최선의 방법인지 모르겠습니다. 나는 종이를 훑어 보았고 세부 사항을 설명하려고 시도하는 것이이 답변의 범위를 벗어났습니다. 그들은 와 의 상대적 크기에 따라 다른 전략을 사용하여 솔루션을 매개 변수화합니다 . 그리고 데이터 구조의 동적 버전은 종이에만 스케치되어 있습니다.un


1
Brodnik & Munro 논문 초록은 인서트에 대해 아무 말도하지 않습니다. 그러나 그들의 결과는 우리가 기대할 수있는 것입니다. 인 경우 n = u/2필요한 공간이 최대입니다.
HEKTO

@AlekseyYakovlev 그들은 초록에서 동적 사례를 실제로 언급하지는 않지만 동적 사례를 다루는 정리는 내 대답에 인용되어 있습니다 (섹션 5에서).
Joe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.