최근 수정 시각 : 2022-06-02 22:41:33

계승(수학)

팩토리얼에서 넘어옴
1. 개요2. 하강 계승 / 상승 계승3. 정의역의 확장4. 알고리즘5. 기타6. 관련 문서

1. 개요

, factorial

기호로 간단하게 [math(n!)]로 나타내며 [math(1)]부터 [math(n)]까지의 자연수를 모두 곱하는 것을 의미한다. 팩토리얼이라고도 불린다.

문화어로는 차례곱이라고 하는데 [math(1)]부터 차례대로 곱한다는 의미[1]이다.

[math(\displaystyle n! = \prod_{k=1}^n k)]로 나타내기도 하는데, [math(k=1)]부터 [math(k=n)]까지 합 연산을 의미하는 [math(\displaystyle \sum_{k=1}^n k)]처럼 [math(\displaystyle \prod)]는 곱연산을 의미한다.

고등학교 교육과정에서는 중복 순열 기호로 [math(\Pi)]를 쓰는 것도 있고, 여러개의 항을 곱하는 것을 거의 다루지 않다 보니 곱의 기호 [math(\displaystyle \prod)]를 가르치지 않기 때문에 계승을 접하는 확률과 통계, 수학 과목에서는 [math(n!=1 \times 2 \times 3 \times \cdots \cdots \times (n-1) \times n)]으로 배운다.[2]
그러나 이중 계승([math(!!=!_2)])[3]이나 다중 계승([math(\overbrace{!!! \cdots\cdots !!}^k = !_k)])[4], 상승·하강 계승 등의 심화 개념을 이해하려면 식을 거꾸로 기억하는 것이 좋다. 이는 나중에 HAN 으로 넘어간다.

그러니까 [math(\displaystyle n! = \prod_{i=0}^{n-1} \left(n-i\right) = n \left( n-1 \right) \left( n-2 \right) \cdots\cdots 3 \cdot 2 \cdot 1)], 즉 [math(\boldsymbol n)]부터 [math(\boldsymbol 1)]씩 빼서 [math(\boldsymbol 1)]까지 곱하는 것으로 기억하자.

순열이나 조합 조합론의 여러 분야에서 빈번하게 쓰이는 기호이기 때문에 [math(n)]의 범위는 일반적으로 음이 아닌 정수로 확장, 즉 [math(n=0)]을 포함하는데, [math(0!)]은 특별히 [math(0!=1)]로 정의한다.0!=1은 true이기 때문이다 예를 들자면 서로 다른 [math(n)]개의 물건에서 [math(n)]개를 모두 뽑아 나열하는 경우의 수([math({}_n\mathrm P_n)])는 [math(n!)]인데, [math({}_n\mathrm P_r = \dfrac{n!}{\left( n-r \right)!})]이므로 [math({}_n\mathrm P_n = \dfrac{n!}{0!})]이며, 정의의 일관성을 유지하려면 [math(0!=1)]이어야 한다.
만약 [math(0! \ne 1)]이라면 순열 뿐만 아니라 조합론의 거의 모든 개념에서 일일이 경우를 나눠서 재정의 해야할 것이다. [math(n! = n \times \left( n-1 \right)!)] 등의 점화식 역시 [math(0!=1)]로 정의하면 자연수 범위에서 성립하는 걸로 만들 수 있다. 참고로 [math(1!=1)]이다.[5]

계승은 매우 빠른 속도로 증가한다. [math(n=12)]까지의 값은 다음과 같다.
[math(n)] [math(0)] [math(1)] [math(2)] [math(3)] [math(4)] [math(5)] [math(6)] [math(7)] [math(8)] [math(9)] [math(10)] [math(11)] [math(12)]
[math(n!)] [math(1)] [math(1)] [math(2)] [math(6)] [math(24)] [math(120)] [math(720)] [math(5{,}040)] [math(40{,}320)] [math(362{,}880)] [math(3{,}628{,}800)] [math(39{,}916{,}800)] [math(479{,}001{,}600)]

고작 10!까지만 해도 벌써 363만 정도이며 12!만 해도 4.8억 정도이다. 이 때문에 시간 복잡도에서 계승([math({\mathcal O}(n!))])이 튀어나오면 해당 알고리즘 폐급 취급을 받는다.[6]

2. 하강 계승 / 상승 계승

하강 계승(falling factorial) [math(n^{\underline k})][7]은 계승의 정의 [math(\displaystyle n! = \prod_{i=0}^{n-1}(n-i) )]에서 [math(i=n-1)]까지가 아닌 [math(i=k-1)]까지의 곱으로 정의된다.
[math(\displaystyle n^{\underline k} = \prod_{i=0}^{k-1} (n-i) = n(n-1)(n-2)\cdots(n-k+2)(n-k+1) = \frac{n!}{(n-k)!})]
[math(k=0)]일 때는 [math(n^{\underline 0}=1)]로 정의된다. 쉽게 말하면, [math(n)]부터 [math(1)]씩 빼가면서 총 [math(k)]개를 곱하는 것이다. 예를 들어서 [math(23^{\underline{4}}=23\cdot22\cdot21\cdot20)]이다. 즉, [math(23)], [math(22)], [math(21)], [math(20)] 이렇게 [math(4)]개를 곱하는 것이다. 한편, [math(\dfrac{n!}{(n-k)!} = {}_n\mathrm P_k)]이므로 하강 계승은 곧 순열 [math({}_n\mathrm P_k)]와 동치임을 알 수 있다. 조합 기호 [math(\dbinom nk = \dfrac{{}_n\mathrm P_k}{k!})]를 이용하면 [math(n^{\underline k} = k!\dbinom nk)]로도 나타낼 수 있다.

이와 비슷하게 상승 계승(rising factorial) [math(n^{\overline k})][8]은 하강 계승의 부분곱 식에서 [math((n-i))]를 [math((n+i))]로 바꾼 식으로 정의된다.
[math(\displaystyle n^{\overline k} = \prod_{i=0}^{k-1} (n+i) = n(n+1)(n+2)\cdots(n+k-2)(n+k-1) = \frac{(n+k-1)!}{(n-1)!})]
[math(k=0)]일 때는 [math(n^{\overline 0}=1)]로 정의된다. 쉽게 말하면, [math(n)]부터 [math(1)]씩 더해가면서 총 [math(k)]개를 곱하는 것이다. 예를 들어서 [math(23^{\overline{3}}=23\cdot24\cdot25)]이다. 즉, [math(23)], [math(24)], [math(25)] 이렇게 [math(3)]개를 곱하는 것이다. 한편, 조합과 비슷하게 위 식은 중복 조합 [math({}_n\mathrm H_k =\left(\!\!\dbinom nk \!\!\right) = \dfrac{(n+k-1)!}{(n-1)!\cdot k!})]에서 등장하므로 [math(n^{\overline k} = k! \left(\!\!\dbinom nk \!\!\right))]로도 나타낼 수 있다.

하강 계승의 정의에서 [math(n)]에 [math(-n)]을 대입하면 다음과 같이 식이 바뀌면서 상승 계승에 대한 식으로 변한다.
[math(\displaystyle (-n)^{\underline k} = \prod_{i=0}^{k-1} (-n-i) = (-1)^k \prod_{i=0}^{k-1} (n+i) = (-1)^k n^{\overline k})]
즉, [math(n^{\overline k} = (-1)^k(-n)^{\underline k})]임을 알 수 있고, 반대로 [math(n^{\underline k} = (-1)^k(-n)^{\overline k})]도 성립한다. 상술한 바와 같이 하강 계승은 조합의 정의에서, 상승 계승은 중복 조합의 정의에서 등장하므로 위와 같은 관계는 조합과 중복 조합이 사실상 하나의 식으로 표현될 수 있음을 의미한다. 즉, [math(\left(\!\!\dbinom nk \!\!\right) = (-1)^k \dbinom{-n}k)]의 관계에 있다.

[math((n)_k)], [math(n^{(k)})]는 레오 아우구스트 포흐하머가 고안한 기호이며, [math(n^{\underline{k}})], [math(n^{\overline{k}})]은 커누스 윗화살표 표기법로 유명한 도널드 커누스가 고안했다.

제1종 스털링 수, 제2종 스털링 수, 라흐 수, 베타 함수, 초기하함수를 정의할 때 쓰인다.

3. 정의역의 확장

계승은 자연수에서만 정의되지만 [math(\Gamma)]로 표기하는 감마 함수를 이용하면 정의역을 복소수로 확장할 수 있다.[9] 자세한 내용은 감마 함수 문서로. 그러니까 감마 함수를 이용하면 [math(1.5!)] 같은 것도 계산할 수 있다는 것. 예를 들어 [math(\left(-\dfrac{1}{2}\right)!=\Gamma\left(\dfrac{1}{2}\right)=\sqrt\pi)]이다. 그래서 이를 통해 순열이나 조합 같은 것도 실수, 복소수로 일반화가 가능하다!

일반 공학용 계산기에 [math(1.5!)] 따위를 넣으면 못 구해주지만, 어째서인지 구글 계산기나 일부 계산기에선 잘 구해준다.[10][math(n! = \Gamma\left(n+1\right))]를 이용해, 정수가 아닌 수를 넣으면 감마 함수로 구하도록 프로그래밍했을 것으로 추정된다.

4. 알고리즘

계승 알고리즘은 컴퓨터에서 두 가지 형태로 구현할 수 있다.

#!syntax cpp
unsigned int fact_iter (unsigned int n) { // 계승은 음이 아닌 정수에 대해서만 정의된다.

	if (n <= 1) return 1; // 1! = 0! = 1이므로 1을 반환한다.

	int result = n;
	for (int i = n - 1; i > 1; i--) result *= i; // n부터 하나씩 값을 줄여가며 그 값을 결과값에 곱한다.

	return result;
	
}

반복문(iteration, loop) 형태의 알고리즘

#!syntax cpp
unsigned int fact_rcsv (unsigned int n) {

	if (n <= 1) return 1; // 1! = 0! = 1이므로 1을 반환한다.

	return n * fact_rcsv(n - 1); // n! = n * (n - 1)!이므로, n - 1에 대한 함수를 한 번 더 호출한다.
	
}

재귀(recursion) 형태의 알고리즘

두 알고리즘은 모두 시간복잡도가 [math(O(n))]이지만, 재귀 함수는 반복하여 호출할수록 메모리 공간을 더 차지하므로, 숫자가 커지면 반복문 알고리즘이 상대적으로 효율적이다.
그냥 노가다 해서 배열을 미리 만들어 두는 것이 좋다. 농담이 아닌 것이, 13!부터 어차피 int의 범위를 넘는다![11]

5. 기타

이것을 기반으로 한 공대개그가 존재한다. 예를 들어 [math(3!)]를 '삼!'이라고 강하게 읽으면 일반인, '삼 팩토리얼'이라고 읽으면 공대생, 이라고 읽으면 이론언어학 전공자라는 식. 3이라고 읽으면 수학 귀신 애독자라고 한다. 다른 개그로 수학 문제를 잘못 계산한 척 해놓고 느낌표를 팩토리얼 기호로 해석하면 정답이 되는 식의 낚시()가 있고,[12] 가수 룰라의 노래인 3!4!를 3!×4!로 해석해서 3!=(3×2×1)=6, 4!=(4×3×2×1)=24이니까 (3×2×1)×(4×3×2×1)=6×24=144라는 식으로 해석하는 식이다. 또는 이러한 유머도 있다.
문과생, 이과생: 230-220÷2가 몇인지 알아?
초등학생: 5!
문과생: 아직 잘 모르네.
이과생: 역시 잘 아네.[13]

오랫동안 수학자들을 괴롭힌 P-NP 문제의 단골 소재 중 하나다.

숫자 뒤가 아닌 숫자 앞에 느낌표를 붙이거나, 뒤집어서 붙이게 되면([math(!n)] 또는 [math(n¡)]의 꼴, [math(n)]은 자연수) [math(n)]개의 원소에 대한 완전순열(derangement)의 수를 의미하게 되며, 이 때는 준계승(subfactorial)이라 부르게 된다. 완전순열은 섞인 모자들 속에서 사람들이 아무도 자기 모자를 집어가지 않는 경우의 수 등을 셀 때 쓰이며, [math(!n)]의 공식은 [math(n!)]보다 복잡하다. 자세한 내용은 완전순열 항목으로.

6. 관련 문서



[1] 후술하겠지만 [math(1)]씩 빼서 [math(1)]까지 차례로 곱한다는 뜻으로 외우는 것이 좋다. [2] 곱의 기호 [math(\prod)]와, 중복 순열의 기호 [math(\Pi)]는 같은 문자를 써서 헷갈릴 수 있다. [3] [math(2)]씩 빼서 [math(2)]나 [math(1)]까지 차례로 곱하라는 기호. [4] [math(k)]씩 빼서 차례로 곱하라는 기호. [5] 1부터 1까지 차례대로 곱하는 것은 결국 곱하나 마나이기 때문이다. [6] 대개 전수조사의 시간 복잡도가 계승꼴이다. 즉 어떠한 알고리즘을 만들든 전수조사보다는 효율적이어야 한다는 의무를 함의한다. [7] [math((n)_k)]로도 표기된다. [8] [math(n^{(k)})]로도 표기된다. [9] 다만 이 경우에도 허수부가 [math(0)]이라면 실수부는 [math(0)] 이하의 정수가 될 수 없다. [10] 특히, PC 윈도우스 계산기. [11] [math(12! \fallingdotseq 479 \rm M)], [math(13! \fallingdotseq 6.23 \rm G)]로, unsigned int의 범위인 42.95억을 넘어간다. [12] 이를테면 6×4=24인데 4!라고 하면 4×3×2×1=24이므로, 느낌표를 문장 부호로 보면 틀리고, 팩토리얼로 보면 정답이 되는 방식이다. [13] 문과생은 숫자 5를 말한 것으로 알아듣고 복잡한 수식에서는 곱셈과 나눗셈을 먼저 해야 하는데 그냥 순서대로 계산한 것으로 이해했고, 이과생은 [math(5!)], 즉 5팩토리얼이라고 말한 것으로 알아듣고 원래 정답인 120을 같은 값인 [math(5!)]로 바꿔 표현한 것으로 이해한 것이다.




파일:CC-white.svg 이 문서의 내용 중 전체 또는 일부는 문서의 r82에서 가져왔습니다. 이전 역사 보러 가기
파일:CC-white.svg 이 문서의 내용 중 전체 또는 일부는 다른 문서에서 가져왔습니다.
[ 펼치기 · 접기 ]
문서의 r82 ( 이전 역사)
문서의 r ( 이전 역사)


분류