맨위로가기

카라추바 알고리즘

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의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자리 수 곱셈의 복잡도가 \Omega(n^2)일 것이라는 추측을 제기했다. 당시 23세 학생이었던 아나톨리 카라추바는 이 추측을 반증하는 알고리즘을 일주일 만에 발견했다. 콜모고로프는 이 발견에 매우 놀랐으며, 다음 세미나에서 이를 발표하고 세미나를 종료했다[7].

이 알고리즘은 1962년 소비에트 연방 과학 학회(Доклады Академии наук СССР)에 발표되었다[6]. 논문은 콜모고로프가 유리 페트로비치 오프만과 협력하여 작성했지만, 저자는 "A. 카라추바와 Yu. 오프만"으로 등재되었다. 카라추바는 발표된 논문의 별쇄본을 받고 나서야 이 사실을 알게 되었다[7].

3. 알고리즘

카라추바 알고리즘은 분할 정복 방식을 사용하여 두 큰 수의 곱셈을 더 작은 수들의 곱셈으로 나누어 계산한다. 이 방법은 찰스 배비지가 알고 있던 공식[4]을 이용해 곱셈 횟수를 줄일 수 있다는 아이디어에서 출발했다.

일반적인 곱셈 방식에서는 두 수를 곱할 때 여러 번의 곱셈이 필요하지만, 카라추바 알고리즘은 이 횟수를 줄인다. 예를 들어, 피승수 X와 승수 Y를 곱하여 Z를 구하는 경우(Z = X \times Y), XY를 상위와 하위 부분으로 나누고, 분할 기준이 되는 기수 b(예: 3자리씩 분할하는 경우 b:=1000)를 정한다.

:X := x_1 \cdot b + x_0

:Y := y_1 \cdot b + y_0

:Z := z_2 \cdot b^2 + z_1 \cdot b + z_0

카라추바 알고리즘은 다음 공식을 사용하여 z_1을 계산하여 곱셈을 3번으로 줄인다.

:z_1 := z_2 + z_0 - (x_1 - x_0) \times (y_1 - y_0)

이 방식은 곱셈 횟수를 줄여 계산 효율성을 높인다.

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(\lceiln/2\rceil) + cn + d

(c와 d는 적당한 상수)

이런 재귀적 관계를 마스터 정리를 통해 풀면, 점근 표기법으로 t(n) = \Theta(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