일반적인 접근 방식 (적어도 나에게 공통적)은 비트 문자열을 여러 청크로 나누고 이러한 청크에 대해 사전 필터 단계와 같은 정확한 일치를 쿼리하는 것입니다. 파일로 작업하는 경우 각 청크가 앞에있는 청크 (예 : 여기에서는 4 개)가있는만큼의 파일을 만든 다음 파일을 정렬합니다. 바이너리 검색을 사용할 수 있으며 보너스를 위해 일치하는 청크 위와 아래로 검색을 확장 할 수도 있습니다.
그런 다음 반환 된 결과에 대해 비트 해밍 거리 계산을 수행 할 수 있습니다. 이는 데이터 파일 또는 SQL 테이블을 사용하여 수행 할 수 있습니다.
요약하자면, DB 또는 파일에 32 비트 문자열이 있고 "쿼리"비트 문자열의 3 비트 해밍 거리 내에있는 모든 해시를 찾으려고한다고 가정 해 보겠습니다.
4 개의 열이있는 테이블을 만듭니다. 각 열에는 32 비트 해시의 8 비트 (문자열 또는 정수) 조각이 포함됩니다. islice 1 ~ 4입니다. 또는 파일을 사용하는 경우 4 개의 파일을 만듭니다. 각 파일은 다음을 갖는 조각의 순열입니다. 각 "행"의 앞쪽에 하나의 "섬"
qslice 1에서 4로 동일한 방식으로 쿼리 비트 문자열을 슬라이스합니다.
이 테이블을 쿼리하여 qslice1=islice1 or qslice2=islice2 or qslice3=islice3 or qslice4=islice4
. 이렇게하면 8 - 1
쿼리 문자열의 7 비트 ( ) 내에있는 모든 문자열이 제공됩니다 . 파일을 사용하는 경우 동일한 결과에 대해 4 개의 순열 된 파일 각각에서 이진 검색을 수행하십시오.
반환 된 각 비트 문자열에 대해 쿼리 비트 문자열과 쌍으로 정확한 해밍 거리를 계산합니다 (DB 또는 치환 된 파일에서 4 개의 슬라이스에서 인덱스 측 비트 문자열 재구성).
4 단계의 연산 수는 전체 테이블의 전체 쌍별 해밍 계산보다 훨씬 적어야하며 실제로 매우 효율적입니다. 또한 병렬 처리를 사용하여 더 빠른 속도가 필요하므로 더 작은 파일로 파일을 쉽게 분할 할 수 있습니다.
이제 물론 귀하의 경우에는 일종의 자체 조인, 즉 서로 어느 정도 거리 내에있는 모든 값을 찾고 있습니다. 동일한 접근 방식이 여전히 IMHO로 작동하지만, 시작 청크를 공유하는 순열 (파일 또는 목록 사용)의 시작점에서 위아래로 확장하고 결과 클러스터에 대한 해밍 거리를 계산해야합니다.
파일 대신 메모리에서 실행하는 경우 100M 32 비트 문자열 데이터 세트는 4GB 범위에 있습니다. 따라서 4 개의 순열 된 목록에는 약 16GB 이상의 RAM이 필요할 수 있습니다. 대신 메모리 매핑 파일로 우수한 결과를 얻고 비슷한 크기의 데이터 세트에 대해서는 RAM을 줄여야합니다.
사용 가능한 오픈 소스 구현이 있습니다. 공간에서 가장 좋은 것은 IMHO입니다. Moz , C ++ 에서 Simhash를 위해 수행 했지만 32 비트가 아닌 64 비트 문자열 용으로 설계되었습니다.
이 경계 happing 거리 방법은 첫째로 AFAIK를 설명한 모 시스 샤리 카르 는 "simhash"정액에 종이 와 해당 Google의 특허 :
- 해밍 공간에서 가장 가까운 이웃 검색
[...]
각각 d 비트로 구성된 비트 벡터가 주어지면 비트의 N = O (n 1 / (1+)) 임의 순열을 선택합니다. 각 임의 순열 σ에 대해 σ에 의해 순열 된 비트의 사전 식 순서로 비트 벡터의 정렬 된 순서 O σ를 유지합니다. 쿼리 비트 벡터 q가 주어지면 다음을 수행하여 근사 근사치를 찾습니다.
각 순열 σ에 대해 O σ에 대해 이진 검색을 수행하여 q에 가장 가까운 두 비트 벡터를 찾습니다 (σ에 의해 순열 된 비트로 얻은 사전 순서대로). 이제 우리는 q와 일치하는 가장 긴 접두사의 길이 순서로 이진 검색에서 반환 된 위치의 위와 아래 요소를 검사하는 정렬 된 순서 O σ 각각에서 검색합니다.
Monika Henziger 는 "거의 중복 된 웹 페이지 찾기 : 알고리즘에 대한 대규모 평가"라는 논문에서이를 확장했습니다 .
3.3 알고리즘 C의 결과
우리는 각 페이지의 비트 열을 12 개의 겹치지 않는 4 바이트 조각으로 분할하여 20B 조각을 만들고, 적어도 하나의 공통 조각이있는 모든 페이지의 C 유사성을 계산했습니다. 이 접근 방식은 최대 11 개의 차이 (예 : C 유사성 373)가있는 모든 페이지 쌍을 찾을 수 있도록 보장하지만 더 큰 차이에서는 일부를 놓칠 수 있습니다.
이는 Gurmeet Singh Manku, Arvind Jain 및 Anish Das Sarma의 웹 크롤링 을 위한 거의 중복 된 항목 감지 문서에서도 설명합니다 .
- 해밍 거리 문제
정의 : f 비트 지문 모음과 쿼리 지문 F가 주어지면 기존 지문이 최대 k 비트에서 F와 다른지 여부를 식별합니다. (위 문제의 배치 모드 버전에서는 단일 쿼리 지문 대신 일련의 쿼리 지문이 있습니다.)
[...]
직관 : 2 개의 df-bit 진정한 무작위 지문으로 구성된 정렬 된 표를 고려하십시오. 테이블에서 가장 중요한 d 비트에만 집중하십시오. 이러한 d- 비트 번호의 목록은 (a) 2d 비트 조합이 상당히 많고 (b) d- 비트 조합이 거의 복제되지 않는다는 점에서 "거의 카운터"에 해당합니다. 반면에 최하위 f-d 비트는 "거의 무작위"입니다.
이제 | d − d | 작은 정수입니다. 테이블이 정렬 되었기 때문에 단일 프로브는 d 가장 중요한 비트 위치에서 F와 일치하는 모든 지문을 식별하는 데 충분합니다. | d − d | 이후 적기 때문에 그러한 경기의 수도 적을 것으로 예상됩니다. 일치하는 각 지문에 대해 최대 k 비트 위치에서 F와 다른지 여부를 쉽게 파악할 수 있습니다 (이러한 차이는 자연스럽게 f-d 최하위 비트 위치로 제한됨).
위에서 설명한 절차는 k 비트 위치에서 F와 다른 기존 지문을 찾는 데 도움이되며, 모두 F의 최하위 f-d 비트 중 하나로 제한됩니다. 이것은 상당한 수의 경우를 처리합니다. 모든 경우를 다루기 위해 다음 섹션에 공식적으로 설명 된대로 몇 개의 추가 정렬 된 테이블을 작성하는 것으로 충분합니다.
참고 : 관련 DB 전용 질문에 유사한 답변을 게시했습니다.