티스토리 뷰
728x90
반응형
순열이란 영어로는 Permutation으로
n개의 물체를 순서를 고려해서 m개를 뽑는 경우의수를 의미합니다.
중고등학교 시간에 배웠던 nPm입니다.
경우의 수가 몇개인지 구하는 것은 간단합니다.
n!/m!을 해주면 갯수는 구할 수가 있습니다.
하지만 컴퓨터과학에서 모든 경우의수를 탐색하는 완전탐색을 위해서는
경우의 수의 갯수가 아니라, 모든 경우의 수를 구해야 하는 일이 있습니다.
1. Python의 내장라이브러리인 itertools의 permutations 매쏘드를 사용할 수 있습니다.
2. 직접 산출하는 함수를 지정하는 방법에 대해서 살펴봅시다.
일단 우리는 nPm의 경우의수 개수를 알고 있습니다.
해당 방법을 활용해서 경우의수를 모두 구하게 됩니다.
첫번째 Pick의 가능한 경우의 수는 nPm입니다.
이때 모든 Element가 동일한 개수를 가지므로
각 원소는 nPm/n의 => (n-1)P(m-1)개의 자기자신을 선두Element로 갖는 경우의수를 갖습니다.
이제, 경우의 수의 첫번째 Element의 배열이 모두 완료되었습니다.
이제는 각 선두Element값에 따라 부분배열을 분할하여 동일한 알고리즘을 반복해줍니다.
이렇게되면 각 부분배열 별로 정해진 경우의 수의 부분배열을 반환하고
Merge Sort의 개념과 비슷하게,
부분배열을 Merge하면서 최종적으로 모든 경우의수를 구하게 됩니다.
Python으로 구현해본 permutation 소스코드입니다 :)
#순열함수 구현을 위해서 Factorial 을 구하는 함수를 정의합니다.
def fact(n):
result = 1
#0! = 1로 정의되어있으므로, 예외처리를 합니다.
if n == 0:
return result
#n의값을 1씩 줄이면서 곱하여 Factorial값을 구합니다.
while True:
result = n*result
n = n-1
if n<=0:
break
return result
def permut(data, n, result = 999):
#함수 처음에는 모든 경우의수 개수만큼의 List를 만들어 줍니다.
if result == 999:
result = [[]for i in range(int(fact(len(data))/fact(len(data)-n)))]
n = n-1
#n+1번째 자리의경우의수를 구하기 위한 경우의수를 계산합니다.
loop_count = int(fact(len(data)-1)/fact(len(data)-n-1))
#loop_count를 이용해서 n+1번째 자리에 가능한 경우의수를 채워넣습니다.
for i in range(len(data)):
for j in range(loop_count):
result[j+i*loop_count].append(data[i])
for i in range(len(data)):
#만약 n=0이라면, 더이상 경우의수가 없으므로 재귀함수를 종료시킵니다.
if n == 0:
break
#아닐 경우에는 이제 n번째 값이 같고, n+1번째 자리에서 값이 같은부분배열을 만들어
#permutation함수를 순환호출 시킵니다.
else:
result[(i)*loop_count:(i+1)*loop_count] = permut(data[:i]+data[i+1:], n,result[(i)*loop_count:(i+1)*loop_count])
#순환호출이 모두 끝난 후 Merge된 모든 경우의수를 반환
return result
permut(data = [7,9,6,1,2],n = 3)
Out[133]:
[[7, 9, 6],
[7, 9, 1],
[7, 9, 2],
[7, 6, 9],
[7, 6, 1],
[7, 6, 2],
[7, 1, 9],
[7, 1, 6],
[7, 1, 2],
[7, 2, 9],
[7, 2, 6],
[7, 2, 1],
[9, 7, 6],
[9, 7, 1],
[9, 7, 2],
[9, 6, 7],
[9, 6, 1],
[9, 6, 2],
[9, 1, 7],
[9, 1, 6],
[9, 1, 2],
[9, 2, 7],
[9, 2, 6],
[9, 2, 1],
[6, 7, 9],
[6, 7, 1],
[6, 7, 2],
[6, 9, 7],
[6, 9, 1],
[6, 9, 2],
[6, 1, 7],
[6, 1, 9],
[6, 1, 2],
[6, 2, 7],
[6, 2, 9],
[6, 2, 1],
[1, 7, 9],
[1, 7, 6],
[1, 7, 2],
[1, 9, 7],
[1, 9, 6],
[1, 9, 2],
[1, 6, 7],
[1, 6, 9],
[1, 6, 2],
[1, 2, 7],
[1, 2, 9],
[1, 2, 6],
[2, 7, 9],
[2, 7, 6],
[2, 7, 1],
[2, 9, 7],
[2, 9, 6],
[2, 9, 1],
[2, 6, 7],
[2, 6, 9],
[2, 6, 1],
[2, 1, 7],
[2, 1, 9],
[2, 1, 6]]
728x90
반응형
'Python 알고리즘 > ETC' 카테고리의 다른 글
최대공약수, 최소공배수 구하기 (0) | 2021.03.05 |
---|---|
Prime Number 여부 확인(단순탐색) (0) | 2021.02.28 |
사칙연산의 표현 (0) | 2021.02.24 |
HourGlass 만들기 (0) | 2021.02.20 |
Genetic Algorithm (0) | 2021.02.08 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Greedy알고리즘
- 동적계획법
- 사칙연산
- SIMD
- hash
- Python
- heap
- 자료구조
- GDC
- 완전탐색 알고리즘
- 컴퓨터그래픽스
- 프로그래머스
- AVX
- 코딩테스트
- 알고리즘
- 이분탐색
- 병렬처리
- C++
- stack
- 분할정복
- Sort알고리즘
- prime number
- git
- Search알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함