Information theory and coding (EC454) Assignment 2 Name: Tanmay Tripathi Roll No.: 2101102EC Branch: ECE Q1: Write a Huffman Algorithm. User input will be 1) Number of Symbols 2) Associated Probabilities 3) Symbols e.g. {0,1} , {0,1,2} Code: import heapq # Class for the node in the Huffman tree class Node: def __init__(self, char, freq): self.char = char # Character or symbol self.freq = freq # Frequency or probability self.children = [] # Children of the node def __lt__(self, other): return self.freq < other.freq # Function to build the Huffman Tree and generate Huffman codes def build_huffman_tree(symbols, probabilities, base): # Create a priority queue (min-heap) heap = [Node(symbols[i], probabilities[i]) for i in range(len(symbols))] heapq.heapify(heap) # Merge nodes until we have only one node in the heap (Huffman Tree root) while len(heap) > 1: # Pop the nodes with the lowest frequencies nodes_to_merge = [heapq.heappop(heap) for _ in range(base)] # Create a new internal node with the sum of frequencies merged = Node(None, sum(node.freq for node in nodes_to_merge)) merged.children = nodes_to_merge # Push the internal node back into the priority queue heapq.heappush(heap, merged) # The final node is the root of the Huffman tree return heap[0] # Function to generate Huffman codes from the tree using custom alphabet def generate_huffman_codes(node, prefix="", codes={}, alphabet=None): if node is not None: # If it's a leaf node, add the character and its corresponding Huffman code if node.char is not None: codes[node.char] = prefix # Traverse all children (instead of just left and right), using the custom alphabet if alphabet is None: alphabet = ["0", "1"] # Default binary alphabet (for compatibility) if hasattr(node, "children"): for i, child in enumerate(node.children): generate_huffman_codes(child, prefix + alphabet[i], codes, alphabet) return codes # Function to perform Huffman encoding def huffman_encoding(symbols, probabilities, alphabet): base = len(alphabet) # Base of the alphabet # Step 1: Build Huffman Tree root = build_huffman_tree(symbols, probabilities, base) # Step 2: Generate Huffman Codes codes = generate_huffman_codes(root, alphabet=alphabet) return codes # Input n = int(input("Enter the number of symbols: ")) symbols = [] probabilities = [] # Input symbols and their probabilities for _ in range(n): symbol = input("Enter the symbol: ") prob = float(input(f"Enter the probability for {symbol}: ")) symbols.append(symbol) probabilities.append(prob) # Input array of distinct "alphabet" representations (numeric or other symbols) alphabet = input( "Enter the array of alphabet representations (separated by space): " ).split() # Check if the alphabet is non-empty if len(alphabet) < 2: print("Error: The alphabet should contain at least 2 elements!") else: # Step 3: Generate Huffman Codes codes = huffman_encoding(symbols, probabilities, alphabet) # Output the Huffman codes print("\nHuffman Codes:") for symbol, code in codes.items(): print(f"{symbol}: {code}") Outputs: