2024. 2. 3. 20:17ใCS - Roadmap.sh/3. Common Algorithms
CS - 3. Common Algorithms - 3.6 Greedy Algorithms - 3.6.1 Huffman Coding
Huffman Coding
๐กHuffman coding is a lossless data compression algorithm. The idea is to assign variable-length codes to input characters, lengths of the assigned codes are based on the frequencies of corresponding characters. The most frequent character gets the smallest code and the least frequent character gets the largest code.
ํํ๋ง ์ฝ๋ฉ์ ๋ฌด์์ค ๋ฐ์ดํฐ ์์ถ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ์ ๋ ฅ ๋ฌธ์์ ๊ฐ๋ณ ๊ธธ์ด์ ์ฝ๋๋ฅผ ํ ๋นํ๊ณ , ํ ๋น๋ ์ฝ๋์ ๊ธธ์ด๋ ํด๋น ๋ฌธ์์ ๋น๋์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ๊ฐ์ฅ ๋น๋๊ฐ ๋์ ๋ฌธ์๋ ๊ฐ์ฅ ์์ ์ฝ๋๋ฅผ, ๊ฐ์ฅ ๋น๋๊ฐ ๋ฎ์ ๋ฌธ์๋ ๊ฐ์ฅ ํฐ ์ฝ๋๋ฅผ ํ ๋น๋ฐ์ต๋๋ค.
ํํ๋ง ์ฝ๋ฉ(Huffman Coding)์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์์ถํ๋ ์๊ณ ๋ฆฌ์ฆ ์ค ํ๋์ ๋๋ค.
์ด ๋ฐฉ๋ฒ์ ๋ฌธ์ ๋๋ ์ฌ๋ณผ์ด ์ผ๋ง๋ ์์ฃผ ๋ฑ์ฅํ๋์ง์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ธธ์ด์ ๋นํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๊ฐ์ฅ ์์ฃผ ๋ฑ์ฅํ๋ ๋ฌธ์๋ ๊ฐ์ฅ ์งง์ ๋นํธ๋ฅผ, ๊ฐ์ฅ ์ ๊ฒ ๋ฑ์ฅํ๋ ๋ฌธ์๋ ๊ฐ์ฅ ๊ธด ๋นํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ํํํ๋ ๋ฐ ํ์ํ ์ ์ฒด ๋นํธ ์๋ฅผ ์ต์ํ ํ ์ ์์ต๋๋ค.
import heapq
import collections
import sys
def huffman_encoding(data):
# ๋ฌธ์์ ๋น๋์๋ฅผ ์ธ์ด์ ์ฌ์ ์ ์ ์ฅํฉ๋๋ค.
freq_dict = collections.defaultdict(int)
for char in data:
freq_dict[char] += 1
# ๋น๋์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ต์ ํ์ ๋ง๋ญ๋๋ค.
# ํ์ ๊ฐ ์์๋ [๋ฌธ์ ๋น๋์, [๋ฌธ์, ๋ฌธ์์ ํํ๋ง ์ฝ๋]] ํํ์
๋๋ค.
heap = [[weight, [char, ""]] for char, weight in freq_dict.items()]
heapq.heapify(heap)
# ํ์ ์์๊ฐ ํ๋๋ง ๋จ์ ๋๊น์ง ์๋์ ๊ณผ์ ์ ๋ฐ๋ณตํฉ๋๋ค.
while len(heap) > 1:
# ํ์์ ๊ฐ์ฅ ๋น๋์๊ฐ ์ ์ ๋ ์์๋ฅผ ๊บผ๋
๋๋ค.
lo = heapq.heappop(heap)
hi = heapq.heappop(heap)
# ๋น๋์๊ฐ ๊ฐ์ฅ ์ ์ ์์์ ํํ๋ง ์ฝ๋ ์์ '0'์ ์ถ๊ฐํฉ๋๋ค.
for pair in lo[1:]:
pair[1] = '0' + pair[1]
# ๋ ๋ฒ์งธ๋ก ๋น๋์๊ฐ ์ ์ ์์์ ํํ๋ง ์ฝ๋ ์์ '1'์ ์ถ๊ฐํฉ๋๋ค.
for pair in hi[1:]:
pair[1] = '1' + pair[1]
# ๋ ์์๋ฅผ ํฉ์น ์ ์์๋ฅผ ํ์ ์ถ๊ฐํฉ๋๋ค.
# ์ด ์์์ ๋น๋์๋ ๋ ์์์ ๋น๋์ ํฉ์ด๋ฉฐ, ํํ๋ง ์ฝ๋๋ ๋ ์์์ ํํ๋ง ์ฝ๋๋ฅผ ํฉ์น ๊ฒ์
๋๋ค.
heapq.heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[1:])
# ํ์ ๋จ์ ๋ง์ง๋ง ์์๊ฐ ์ ์ฒด ๋ฌธ์์ ํํ๋ง ํธ๋ฆฌ์
๋๋ค.
# ์ด๋ฅผ ํํ๋ง ์ฌ์ ์ผ๋ก ๋ณํํ์ฌ ์ถ๋ ฅํฉ๋๋ค.
huff_dict = sorted(heapq.heappop(heap)[1:], key=lambda p: (len(p[-1]), p))
print("Huffman Coding: ")
for char, huff_code in huff_dict:
print(f"{char} : {huff_code}")
์ ์ฝ๋๋ ์ฌ์ฉ์๋ก๋ถํฐ ๋ฌธ์์ด์ ์ ๋ ฅ๋ฐ์ ๊ฐ ๋ฌธ์์ ๋น๋์๋ฅผ ๊ณ์ฐํ๊ณ ,
์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํํ๋ง ์ฝ๋ฉ ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํด ๊ฐ ๋ฌธ์์ ๋์ํ๋ ํํ๋ง ์ฝ๋๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
์ด๋ฐ์์ผ๋ก ๋ฌธ์์ด์์ ๊ฐ ๋ฌธ์์ ๋น๋์๋ฅผ ์นด์ดํธํ๊ณ , ๋น๋์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํํ๋ง ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
ํธ๋ฆฌ๋ฅผ ํตํด ๊ฐ ๋ฌธ์์ ๋์ํ๋ ํํ๋ง ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ถ๋ ฅํฉ๋๋ค. ์ด๋ ๊ฒ ์์ฑ๋ ํํ๋ง ์ฝ๋๋ ๊ทธ ๋ฌธ์์ ๋น๋์์ ๋ฐ๋น๋กํ๋ ๊ธธ์ด๋ฅผ ๊ฐ์ง๋ฏ๋ก, ๋น๋์๊ฐ ๋์ ๋ฌธ์๋ ์งง์ ์ฝ๋๋ฅผ, ๋น๋์๊ฐ ๋ฎ์ ๋ฌธ์๋ ๊ธด ์ฝ๋๋ฅผ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค.
ํ์ฉ
์ ์์ ๋ฐ๋ผ์ '์์ถ'์ ๊ฐ์ ์ ์ง๋๊ธฐ์ ์์ถ๊ณผ ์ ์ก์ ์์ด ํฐ ํจ์จ์ฑ์ ์ง๋๋๋ค.
1. ํ์ผ ์์ถ
ํํ๋ง ์ฝ๋ฉ์ ํ์ผ ์์ถ์ ๋ง์ด ์ฌ์ฉ๋ฉ๋๋ค.
ZIPํ์ผ ์์ถ์ ํํ๋ง ์ฝ๋ฉ์ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์์ถํฉ๋๋ค.
JPEG ์ด๋ฏธ์ง ์์ถ์์๋ ํํ๋ง ์ฝ๋ฉ์ด ์ฌ์ฉ๋ฉ๋๋ค.
์ด๋ฏธ์ง ์์ ์ ๋ณด๋ฅผ ์์ถํ๋ ๊ณผ์ ์์ ํํ๋ง ์ฝ๋ฉ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์์ถํฉ๋๋ค.
2. ํต์
ํํ๋ง ์ฝ๋ฉ์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ ์กํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉ๋ฉ๋๋ค.
๋ฐ์ดํฐ ์ ์ก์ ํ์ํ ๋นํธ์๋ฅผ ์ค์ฌ ์ต์ํํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
3. ์น ๋ก๋ฉ
ํ ์คํธ ๋ฐ์ดํฐ๋ ํํ๋ง ์ฝ๋ฉ์ ํตํด ์์ถ์ ํ ์ ์์ผ๋ฉฐ, ์น ํ์ด์ง ๋ก๋ฉ ์๋๋ฅผ ๋์ด๋๋ฐ ๋์์ด ๋ฉ๋๋ค.
'CS - Roadmap.sh > 3. Common Algorithms' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
3.6.3 Ford Fulkerson algorithm(ํด๋ํ์ปค์จ ์๊ณ ๋ฆฌ์ฆ) (1) | 2024.02.06 |
---|---|
3.6.2 Kruskalโs algorithm (ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ) (1) | 2024.02.05 |
3.6 Greedy Algorithms (0) | 2024.02.02 |
3.5 Graph - 3.5.5 A* Algorithm (0) | 2024.01.31 |
3.5 Graph - 3.5.4 Dijkstraโs Algorithm (2) | 2024.01.30 |