티스토리 뷰
728x90
반응형
Huffman Coding은 글자의 빈도수를 기반으로 text를 2진수의 조합으로 변환하는 알고리즘입니다.
글자의 출현 빈도수가 높을수록 작은 2진수를, 글자수의 빈도가 낮을수록 높은 2진수를 부여합니다.
그렇게되면 기존의 Text를 2진수로 무손실 압축을 할 수가 있습니다(정보의 손실X)
과거 Huffman이 고안하여 Huffman Coding이라고 하며,
원본을 알기 위해선 Coding 된 Text와 함께 Huffman Tree가 필요합니다.
Huffman Tree의 생성 알고리즘은
1. 문자의 총 출현 빈도를 가지고, 가장 높은 빈도수의 문자부터 Top Node의 Left Node에 추가해줍니다.
2. Right Node로 이동하여 1번을 반복합니다.
3. Unique Text의 개수만큼 Node가 할당되었으면 알고리즘 종료
이제 왼편으로 가면 0, 오르편으로 가면 1이 추가된다고 하면
빈도가 높으면 0 그 다음은 10, 그다음은 110 과 같은 2진수로 Encoding을 할 수 있는 Huffman Tree가 구축됩니다.
(10진수로 생각하면 처음은 0, 두번째는 0+2, 다음은 0+2+4... 0+2+...2^(n+1)의 값을 갖게됩니다)
최근 Python과 같은 언어에서는 Dictonary나 Json을 사용하면 쉽게 구현이 가능할 수 있지만,
Huffman Tree를 구축하고, 구축된 Tree를 이용하여 Huffman Coding을 하는 Python Code입니다.
import random
#Huffman Tree의 기본 Node.
#left,right node와 해당 Node의 count, char, coding_num 정보를 가지고있습니다.
class binary_node:
def __init__(self, left, count, char, coding_num, right):
self.left = left
self.count = count
self.char = char
self.coding_num = coding_num
self.right = right
class huffman_tree:
def __init__(self, text):
self.ori_text = text
self.node_list = []
self.node_list_copy = []
self.text_array = list(set(text))
self.text_count = [0]*len(self.text_array)
for i in range(len(self.text_array)):
for j in range(len(text)):
if self.text_array[i]==text[j]:
self.text_count[i] = self.text_count[i] +1
self.text_count_copy = self.text_count.copy()
self.top_node = binary_node(None, sum(self.text_count), None, None, None)
#leaf Node를 입력된 Text를 기반으로 생성합니다.
def make_leaf_tree(self, char_array = None, char_count = None):
if (char_array is None) or (char_count is None):
char_array = self.text_array
char_count = self.text_count
for i in range(len(char_array)):
self.node_list = self.node_list + [binary_node(None,char_count[i],char_array[i],None,None)]
self.node_list_copy = self.node_list.copy()
return self.node_list.copy()
#huffman Tree의 규칙에 따라 가장 큰 빈도수의 문자를 가진 Node를 left Node로
#그 다음 right Node로 이동 후 동일한 과정을 반복합니다.
def make_hf_tree(self,start_node = None,tot_count = None,char_count = None,coding_num = 1):
if char_count is None:
char_count = max(self.text_count_copy)
if start_node is None:
start_node = self.top_node
if tot_count is None:
tot_count = sum(self.text_count_copy)
for i in range(len(self.node_list_copy)):
if self.node_list_copy[i].count == char_count:
self.node_list_copy[i].coding_num = coding_num
coding_num = coding_num +1
start_node.left = self.node_list_copy[i]
del(self.node_list_copy[i])
del(self.text_count_copy[i])
tot_count = tot_count - char_count
if tot_count <=0:
return True
char_count = max(self.text_count_copy)
start_node.right = binary_node(None, tot_count, None, None, None)
self.make_hf_tree(start_node.right,start_node.right.count,char_count,coding_num)
break
#huffman Tree를 출력
def show_tree(self, test = 999):
if test == 999:
test = self.top_node
print(test.count, test.char, bin(test.coding_num) if test.coding_num is not None else test.coding_num)
self.show_tree(test.left) if test.left != None else None
self.show_tree(test.right) if test.right != None else None
#huffman Tree를 기반으로 입력된 알파벳 or 문자의 coding num를 반환합니다.
def coding_num(self, text, node = 999):
result = 0
if node == 999:
node = self.top_node
if node != None:
if text == node.char:
result = pow(2,node.coding_num+1)-2
return result
if node.left != None:
result = self.coding_num(text, node.left) + result
if node.right != None:
result = self.coding_num(text, node.right) + result
return result
#입력된 text를 huffman tree를 기반으로 Encoding 하여 반환
def coding_text(self, text = 999):
if text == 999:
text = self.ori_text
coding_text = ""
for i in range(len(text)):
coding_text = coding_text + str(bin(self.coding_num(text[i])))[2:]
return coding_text
text = "eeemdaaksdaaa"
test = huffman_tree(text)
test.make_leaf_tree()
test.make_hf_tree()
test.show_tree()
test.coding_text()
Out[1]: '110110110111110111010101111011111101110101010'
728x90
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Python
- SIMD
- 컴퓨터그래픽스
- GDC
- Search알고리즘
- 이분탐색
- 코딩테스트
- Greedy알고리즘
- hash
- stack
- git
- AVX
- 알고리즘
- 완전탐색 알고리즘
- 분할정복
- heap
- 자료구조
- prime number
- C++
- 프로그래머스
- 병렬처리
- 동적계획법
- Sort알고리즘
- 사칙연산
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함