카라추바 알고리즘
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
카라추바 알고리즘은 1960년 아나톨리 카라추바가 개발한 곱셈 알고리즘으로, 두 개의 n자리 숫자를 곱하는 연산의 시간 복잡도를 기존 O(n²)에서 O(n1.585)로 개선했다. 이 알고리즘은 분할 정복 방식을 사용하여 큰 곱셈 문제를 더 작은 곱셈 문제로 나누어 해결하며, 재귀 호출을 통해 구현된다. 카라추바 알고리즘은 덧셈과 자릿수 이동을 통해 곱셈 횟수를 줄여 효율성을 높이며, 충분히 큰 수의 곱셈에서 고전적인 곱셈보다 유리하다.
더 읽어볼만한 페이지
- 컴퓨터 산술 알고리즘 - 컴퓨터 프로그래밍의 예술
도널드 커누스가 집필한 컴퓨터 과학 분야의 대표 저서인 컴퓨터 프로그래밍의 예술은 자료 구조, 알고리즘, 준수치적 알고리즘, 정렬 및 검색, 조합론적 알고리즘 등 프로그래밍 핵심 주제를 깊이 있게 다루고 문제 해결 능력 향상에 기여하며, MIX/MMIX 어셈블리 언어 분석을 통해 튜링상 수상 및 "세기의 과학을 형성한 100여 권의 책"으로 선정되는 등 높은 평가를 받았다. - 컴퓨터 산술 알고리즘 - 장제법
장제법은 12세기부터 사용된 나눗셈 알고리즘으로, 몫과 나머지를 계산하는 과정을 반복하며 불변량을 유지하고, 컴퓨터 과학에서도 다양한 형태로 활용된다. - 곱셈 - 구구단
구구단은 곱셈을 간편하게 계산하도록 곱셈 결과를 표로 정리한 것이며, 1단부터 9단까지 외우는 곱셈 구구가 일반적이고, 덧셈, 뺄셈, 나눗셈 구구 등 다양한 형태가 존재하며, 수학적 개념 이해의 기초가 되고 실생활에도 응용된다. - 곱셈 - 네이피어의 뼈
네이피어의 뼈는 존 네이피어가 1617년에 발명한 계산 도구로, 곱셈을 덧셈으로 변환하여 계산을 간편하게 하고 나눗셈과 제곱근 계산에도 활용되며, 계산 기반과 막대 세트로 구성되어 막대에 표시된 숫자를 이용하여 복잡한 곱셈을 단순화한다.
카라추바 알고리즘 | |
---|---|
알고리즘 개요 | |
종류 | 곱셈 알고리즘 |
고안자 | 아나톨리 카라추바 |
발표 연도 | 1960년 |
시간 복잡도 | O(nlog₂3) ≈ O(n1.585) |
상세 정보 | |
최적 시간 복잡도 | 알려지지 않음 |
평균 시간 복잡도 | 해당 사항 없음 |
공간 복잡도 | 해당 사항 없음 |
2. 역사
1960년 가을, 모스크바 대학교에서 안드레이 콜모고로프가 사이버네틱스 수학 문제 세미나를 열었다. 이 세미나에서 콜모고로프는 n자리 수 곱셈의 복잡도가 일 것이라는 추측을 제기했다. 당시 23세 학생이었던 아나톨리 카라추바는 이 추측을 반증하는 알고리즘을 일주일 만에 발견했다. 콜모고로프는 이 발견에 매우 놀랐으며, 다음 세미나에서 이를 발표하고 세미나를 종료했다[7].
카라추바 알고리즘은 분할 정복 방식을 사용하여 두 큰 수의 곱셈을 더 작은 수들의 곱셈으로 나누어 계산한다. 이 방법은 찰스 배비지가 알고 있던 공식[4]을 이용해 곱셈 횟수를 줄일 수 있다는 아이디어에서 출발했다.
이 알고리즘은 1962년 소비에트 연방 과학 학회(Доклады Академии наук СССР)에 발표되었다[6]. 논문은 콜모고로프가 유리 페트로비치 오프만과 협력하여 작성했지만, 저자는 "A. 카라추바와 Yu. 오프만"으로 등재되었다. 카라추바는 발표된 논문의 별쇄본을 받고 나서야 이 사실을 알게 되었다[7].
3. 알고리즘
일반적인 곱셈 방식에서는 두 수를 곱할 때 여러 번의 곱셈이 필요하지만, 카라추바 알고리즘은 이 횟수를 줄인다. 예를 들어, 피승수 와 승수 를 곱하여 를 구하는 경우(), 와 를 상위와 하위 부분으로 나누고, 분할 기준이 되는 기수 (예: 3자리씩 분할하는 경우 )를 정한다.
:
:
:
카라추바 알고리즘은 다음 공식을 사용하여 을 계산하여 곱셈을 3번으로 줄인다.
:
이 방식은 곱셈 횟수를 줄여 계산 효율성을 높인다.
3. 1. 기본 단계
두 수 ''x''와 ''y''를 ''B''진법의 ''n''자리 수라고 가정하고, ''n''보다 작은 양수 ''m''에 대해 다음과 같이 ''x'', ''y''를 분할할 수 있다.
:''x'' = ''x''1''B''''m'' + ''x''0
:''y'' = ''y''1''B''''m'' + ''y''0
(단, ''x''0과 ''y''0는 ''B''''m''보다 작다.)[4]
이때, ''x''와 ''y''의 곱은 다음과 같이 표현된다.
:''xy'' = (''x''1''B''''m'' + ''x''0)(''y''1''B''''m'' + ''y''0)
::= ''z''2 ''B''2''m'' + ''z''1 ''B''''m'' + ''z''0
여기서,
:''z''2 = ''x''1''y''1
:''z''1 = ''x''1''y''0 + ''x''0''y''1
:''z''0 = ''x''0''y''0
위 식은 곱셈을 4번 해야 한다. 카라추바는 ''z''1을 다음과 같이 계산하여 곱셈 횟수를 줄였다.[4]
:''z''1 = (''x''1 + ''x''0)(''y''1 + ''y''0) - ''z''2 - ''z''0
3. 2. 예
''B'' = 10, ''m'' = 3으로 설정하고 12345와 6789의 곱셈을 계산하는 과정은 다음과 같다.
먼저 입력값을 기수(''B''''m'' = ''1000'')를 사용하여 분해한다.
: 12345 = '''12''' × ''1000'' + '''345'''
: 6789 = '''6''' × ''1000'' + '''789'''
세 개의 부분 결과를 계산하기 위해 더 작은 정수에 대한 세 번의 곱셈을 수행한다.
: ''z''2 = '''12''' × '''6''' = 72
: ''z''0 = '''345''' × '''789''' = 272205
: ''z''1 = ('''12''' + '''345''') × ('''6''' + '''789''') - ''z''2 - ''z''0 = 357 × 795 - 72 - 272205 = 11538
세 부분 결과를 적절히 시프트하여 더하고, 올림수를 고려하여 최종 결과를 얻는다.
: 결과 = ''z''2 × (''B''''m'')''2'' + ''z''1 × (''B''''m'')''1'' + ''z''0 × (''B''''m'')''0''
: 결과 = 72 × ''1000''2 + 11538 × ''1000'' + 272205 = '''83810205'''
이때, 중간 곱셈(''z''1 계산)은 처음 두 곱셈보다 작은 입력 범위에서 작동하며, 출력 범위는 네 배 미만이다. 또한, 처음 두 곱셈에서 계산된 기수-''1000'' 올림수를 고려하여 뺄셈을 계산해야 한다.
3. 3. 재귀적 활용
''n''이 4 이상이면, 카라추바 알고리즘 기본 단계를 통해 ''n''보다 작은 자리의 수에 대한 곱셈 3번을 하게 된다. 그러므로 재귀 호출을 통해 그 곱을 계산할 수 있다. 재귀 호출은 곱하는 수가 단번에 계산될 정도로 작아질 때까지 적용할 수 있다.[4]
예를 들어 32비트끼리 곱하는 곱셈기에서 ''B'' = 231 = 2147483648 또는 ''B'' = 109 = 를 선택하고 각 자리를 독립된 32비트 단위로 저장할 수 있다. 그러면 ''x''1 + ''x''0와 ''y''1 + ''y''0에 여분의 자리올림 비트가 필요없고, 카라추바 재귀는 숫자가 한 자리가 될 때까지 반복 가능하다.
4. 효율성 분석
카라추바 알고리즘의 기본 단계는 모든 B와 m에 대해 작동하지만, m이 n/2일 때 가장 효율적이다. 특히 양의 정수 k에 대해 n이 2k이고, 재귀가 n이 1일 때 끝난다면, 한 자리 곱셈의 횟수는 3k이 된다(''n''''c''에서 ''c'' = log23이므로).[7]
카라추바 알고리즘 기본 단계의 덧셈, 뺄셈, 시프트 연산(B의 거듭제곱으로 곱하는 것)은 n에 비례하는 시간이 걸리므로, 그 비용의 비중은 n이 증가함에 따라 무시할 정도로 줄어든다. 더 정확하게 t(n)이 두 n자리수의 곱셈에 필요한 기초 연산의 총횟수라고 할 때 다음과 같다.
:t(n) = 3t(n/2) + cn + d
(c와 d는 적당한 상수)
이런 재귀적 관계를 마스터 정리를 통해 풀면, 점근 표기법으로 t(n) = (nlog(3)/log(2))이라는 것을 알 수 있다.[6]
충분히 큰 n에 대해, 카라추바 알고리즘은 고전적인 곱셈법보다 적은 횟수의 시프트 연산과 한 자리 곱셈을 행한다. 하지만 작은 n에 대하여는 추가적인 덧셈과 시프트 연산 때문에 고전적인 곱셈법보다 속도가 느려진다. 그 경계는 컴퓨터 플랫폼에 따라 달라진다. 대략적으로 곱하는 수가 2320 (약 96자리) 이상일 때 카라추바 알고리즘이 더 빠르다.[7]
5. 구현
다음은 십진법으로 표현된 숫자를 사용하는 이 알고리즘의 의사 코드이다. 정수의 이진 표현의 경우, 10을 2로 바꾸면 된다.[5]
`split_at` 함수의 두 번째 인수는 ''오른쪽''에서 추출할 자릿수를 지정한다. 예를 들어, `split_at("12345", 3)`은 마지막 3자리를 추출하여 high="12", low="345"를 반환한다.
```c
function karatsuba(num1, num2)
if (num1 < 10 or num2 < 10)
return num1 × num2 /* 기존 곱셈으로 돌아감 */
/* 숫자의 크기를 계산합니다. */
m = max(size_base10(num1), size_base10(num2))
m2 = floor(m / 2)
/* m2 = ceil (m / 2)도 작동합니다. */
/* 중간에서 숫자 시퀀스를 분할합니다. */
high1, low1 = split_at(num1, m2)
high2, low2 = split_at(num2, m2)
/* 크기가 대략 절반인 숫자에 대해 3번의 재귀 호출을 합니다. */
z0 = karatsuba(low1, low2)
z1 = karatsuba(low1 + high1, low2 + high2)
z2 = karatsuba(high1, high2)
return (z2 × 10 ^ (m2 × 2)) + ((z1 - z2 - z0) × 10 ^ m2) + z0
```
구현 시 발생하는 문제는 z1에 대한 (x1 + x0)과 (y1 + y0)의 위 계산에서 오버플로가 발생할 수 있다는 것이다(Bm ≤ result < 2 Bm 범위의 결과가 생성됨). 이는 한 비트가 더 많은 승수를 필요로 한다. 이는 다음을 통해 피할 수 있다.
:z1 = (x0 - x1)(y1 - y0) + z2 + z0.
(x0 - x1)과 (y1 - y0)의 이 계산은 -Bm < result < Bm 범위의 결과를 생성한다. 이 방법은 음수를 생성할 수 있으며, 이는 부호를 인코딩하기 위해 한 비트가 더 필요하며, 승수를 위해 여전히 한 비트가 더 필요하다. 그러나 이를 피하는 한 가지 방법은 부호를 기록한 다음 (x0 - x1) 및 (y1 - y0)의 절댓값을 사용하여 부호 없는 곱셈을 수행하는 것이다. 그런 다음 원래 두 부호가 다를 때 결과를 음수로 만들 수 있다. 또 다른 장점은 (x0 - x1)(y1 - y0)이 음수일 수 있지만, z1의 최종 계산에는 덧셈만 포함된다는 것이다.
참조
[1]
논문
Multiplication of Many-Digital Numbers by Automatic Computers
https://www.mathnet.[...]
[2]
논문
The Complexity of Computations
http://www.ccas.ru/p[...]
[3]
서적
The Art of Computer Programming
Addison-Wesley Publ.Co.
[4]
문서
Of the Analytical Engine, Larger Numbers Treated
https://archive.org/[...]
Longman Green, London
1864
[5]
서적
Data Structures and Algorithm Analysis in C++
Addison-Wesley
2005
[6]
저널
자동식 컴퓨터에 의핸 큰 수의 곱셈(Multiplication of Many-Digital Numbers by Automatic Computers)
[7]
저널
계산 복잡도(The Complexity of Computations)
http://www.ccas.ru/p[...]
[8]
서적
컴퓨터 프로그래밍의 예술. 제 2권.
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com