긴 글입니다. 저를 참아주세요. 삶은 기수 정렬 알고리즘이 있습니까?
예비
나는 정렬하고 싶은 문자 "A", "C", "G"및 "T"(예, 당신은 짐작했습니다 : DNA ) 만 사용하는 작은 고정 길이 문자열이 많이 있습니다 .
현재 STL 의 모든 일반적인 구현에서 introsort 를 사용 std::sort
하는을 사용합니다 . 이것은 꽤 잘 작동합니다. 그러나 기수 정렬이 내 문제 세트에 완벽하게 부합하고 실제로 훨씬 더 잘 작동한다고 확신합니다 .
세부
나는 매우 순진한 구현 으로이 가정을 테스트했으며 비교적 작은 입력 (약 10,000 정도)에 대해서는 이것이 사실입니다 (최소한 두 배 이상 빠름). 그러나 문제 크기가 커지면 런타임이 크게 저하됩니다 ( N > 5,000,000).
기수 정렬은 전체 데이터를 복사해야합니다 (실제로 순진한 구현에서는 두 번 이상). 이것은 ~ 4GiB를 메인 메모리에 넣어 성능을 저하시키는 것을 의미합니다. 그렇지 않은 경우에도 문제 크기가 실제로 더 커지기 때문에이 많은 메모리를 사용할 여유가 없습니다.
사용 사례
이상적으로이 알고리즘은 DNA 및 DNA5 (추가 와일드 카드 문자 "N"허용) 또는 IUPAC 모호성 코드 (16 개의 다른 값)가있는 DNA의 경우 2에서 100 사이의 모든 문자열 길이에서 작동해야합니다 . 그러나 이러한 모든 경우를 다룰 수는 없다는 점을 알고 있으므로 속도 향상에 만족합니다. 코드는 어떤 알고리즘을 디스패치할지 동적으로 결정할 수 있습니다.
연구
불행하게도 기수 정렬에 대한 Wikipedia 기사 는 쓸모가 없습니다. 전체 변형에 대한 섹션은 완전 쓰레기입니다. 기수 정렬 의 NIST-DADS 섹션 은 존재하지 않는 옆에 있습니다. 알고리즘“MSL”을 설명하는 Efficient Adaptive In-Place Radix Sorting 이라는 유망한 소리의 논문이 있습니다. 불행하게도이 논문 역시 실망 스럽다.
특히 다음과 같은 것들이 있습니다.
첫째, 알고리즘에는 몇 가지 실수가 포함되어 있으며 설명 할 수없는 부분이 많습니다. 특히, 재귀 호출을 자세히 설명하지 않습니다 (현재 쉬프트 및 마스크 값을 계산하기 위해 포인터를 늘리거나 줄이는 것으로 가정합니다). 또한, 기능 사용 dest_group
과 dest_address
정의를 제공하지 않고 있습니다. 나는 이것을 효율적으로 구현하는 방법을 보지 못했습니다 (즉, O (1); 적어도 dest_address
사소하지는 않습니다).
마지막으로,이 알고리즘은 배열 인덱스를 입력 배열 내부의 요소와 교체하여 적절한 위치에 도달합니다. 이것은 분명히 숫자 배열에서만 작동합니다. 문자열에 사용해야합니다. 물론, 나는 강한 타이핑을 망쳐 놓고 메모리가 내 인덱스가 아닌 인덱스를 저장할 수 있다고 가정 할 수 있습니다. 그러나 이것은 32 비트 정수로 가정하여 문자열을 32 비트 메모리로 압축 할 수있는 한 작동합니다. 16 자에 불과합니다 (16> log (5,000,000) 인 순간 무시).
저자 중 한 사람의 다른 논문은 전혀 정확한 설명을 제공하지는 않지만 MSL의 런타임을 하위 선형으로 제공하여 잘못 전개됩니다.
요약 : DNA 문자열에서 작동하는 작업 기준 구현 또는 작업 가능한 기수 정렬에 대한 의사 코드 / 설명을 찾을 희망이 있습니까?