0% found this document useful (0 votes)
35 views6 pages

Huffman Coding and Greedy Algorithms

The document discusses various algorithms related to graphs and strings: 1. The greedy method is an optimization technique that makes locally optimal choices at each step to find a global optimum. Huffman coding is an example of a greedy algorithm. 2. Kruskal's and Prim's algorithms are greedy approaches for finding minimum spanning trees in weighted graphs. 3. Dijkstra's and Bellman-Ford algorithms solve the single-source shortest path problem on graphs, with Bellman-Ford handling some negative edge weights. 4. The Rabin-Karp algorithm improves on the naive string matching approach by using hashing to avoid unnecessary character comparisons. The Knuth-Morris-Pratt algorithm

Uploaded by

Bhartiya Nagrik
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views6 pages

Huffman Coding and Greedy Algorithms

The document discusses various algorithms related to graphs and strings: 1. The greedy method is an optimization technique that makes locally optimal choices at each step to find a global optimum. Huffman coding is an example of a greedy algorithm. 2. Kruskal's and Prim's algorithms are greedy approaches for finding minimum spanning trees in weighted graphs. 3. Dijkstra's and Bellman-Ford algorithms solve the single-source shortest path problem on graphs, with Bellman-Ford handling some negative edge weights. 4. The Rabin-Karp algorithm improves on the naive string matching approach by using hashing to avoid unnecessary character comparisons. The Knuth-Morris-Pratt algorithm

Uploaded by

Bhartiya Nagrik
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

The greedy method is one of the strategies like Divide and conquer used to solve the problems.

This
method is used for solving optimization problems. An optimization problem is a problem that demands
either maximum or minimum results
The main function of this approach is that the decision is taken on the basis of the currently available
information. Whatever the current information is present, the decision is made without worrying about the
effect of the current decision in future.
This technique is basically used to determine the feasible solution that may or may not be optimal.

Huffman Codes
o (i) Data can be encoded efficiently using Huffman Codes.
o (ii) It is a widely used and beneficial technique for compressing data.
o (iii) Huffman's greedy algorithm uses a table of the frequencies of occurrences of each character to
build up an optimal way of representing each character as a binary string.
o Huffman (C)
o 1. n=|C|
o 2. Q ← C
o 3. for i=1 to n-1
o 4. do
o 5. z= allocate-Node ()
o 6. x= left[z]=Extract-Min(Q)
o 7. y= right[z] =Extract-Min(Q)
o 8. f [z]=f[x]+f[y]
o 9. Insert (Q, z)
o 10. return Extract-Min (Q)

A tree is a graph with the following properties:

1. The graph is connected (can go from anywhere to anywhere)


2. There are no cyclic (Acyclic)

Spanning Tree:
Given a connected undirected graph, a spanning tree of that graph is a subgraph that is a tree and
joined all vertices. A single graph can have many spanning trees.

Properties of Spanning Tree:

1. There may be several minimum spanning trees of the same weight having the minimum
number of edges.
2. If all the edge weights of a given graph are the same, then every spanning tree of that
graph is minimum.
3. If each edge has a distinct weight, then there will be only one, unique minimum spanning
tree.
4. A connected graph G can have more than one spanning trees.
5. A disconnected graph can't have to span the tree, or it can't span all the vertices.
6. Spanning Tree doesn't contain cycles.
7. Spanning Tree has (n-1) edges where n is the number of vertices.

Addition of even one single edge results in the spanning tree losing its property of Acyclicity and
elimination of one single edge results in its losing the property of connectivity.

Minimum Spanning Tree:


Minimum Spanning Tree is a Spanning Tree which has minimum total cost. If we have a
linked undirected graph with a weight (or cost) combine with each edge. Then the cost of
spanning tree would be the sum of the cost of its edges.

Kruskal's Algorithm:
An algorithm to construct a Minimum Spanning Tree for a connected weighted graph. It is a
Greedy Algorithm.

If the graph is not linked, then it finds a Minimum Spanning Tree.

1. Arrange the edge of G in order of increasing weight.


2. Starting only with the vertices of G and proceeding sequentially add each edge which does
not result in a cycle, until (n - 1) edges are used.
3. EXIT.

Analysis: Where E is the number of edges in the graph and V is the number of vertices, Kruskal's
Algorithm can be shown to run in O (E log E) time, or simply, O (E log V) time, all with simple data
structures. These running times are equivalent because:

Prim's Algorithm
It is a greedy algorithm. It starts with an empty spanning tree. The idea is to maintain two sets of
vertices:

o Contain vertices already included in MST.


o Contain vertices not yet included.

At every step, it considers all the edges and picks the minimum weight edge. After picking the
edge, it moves the other endpoint of edge to set containing MST.

Steps for finding MST using Prim's Algorithm:


1. Create MST set that keeps track of vertices already included in MST.
2. Assign key values to all vertices in the input graph. Initialize all key values as INFINITE (∞). Assign
key values like 0 for the first vertex so that it is picked first.
3. While MST set doesn't include all vertices.

1. Pick vertex u which is not is MST set and has minimum key value. Include 'u'to MST set.
2. Update the key value of all adjacent vertices of u. To update, iterate through all adjacent
vertices. For every adjacent vertex v, if the weight of edge u.v less than the previous key
value of v, update key value as a weight of u.v.

SINGLE SOURCE SHORTEST PATH


The breadth-first- search algorithm is the shortest path algorithm that works on unweighted
graphs, that is, graphs in which each edge can be considered to have unit weight.

Dijkstra Algorithm
Dijkstra algorithm is a single-source shortest path algorithm. Here, single-source means that only
one source is given, and we have to find the shortest path from the source to all the nodes.

Dijkstra's Algorithm works on the basis that any subpath  B -> D  of the shortest path  A ->

D  between vertices A and D is also the shortest path between vertices B and D.
we overestimate the distance of each vertex from the starting vertex. Then we visit
each node and its neighbors to find the shortest subpath to those neighbors.

The algorithm uses a greedy approach in the sense that we find the next best solution
hoping that the end result is the best solution for the whole problem.

Dijkstra's Algorithm Complexity


Time Complexity:  O(E Log V)

where, E is the number of edges and V is the number of vertices.

Space Complexity:  O(V)

Bellman-Ford Algorithm
Solves single shortest path problem in which edge weight may be negative but no negative cycle
exists.

This algorithm works correctly when some of the edges of the directed graph G may have negative
weight. When there are no cycles of negative weight, then we can find out the shortest path
between source and destination.
It is slower than Dijkstra's Algorithm but more versatile, as it capable of handling some of the
negative weight edges.

This algorithm detects the negative cycle in a graph and reports their existence.

NAIVE-STRING-MATCHER (T, P)
1. n ← length [T]
2. m ← length [P]
3. for s ← 0 to n -m
4. do if P [1.....m] = T [s + 1....s + m]
5. then print "Pattern occurs with shift" s
The Rabin-Karp string matching algorithm calculates a hash value for the pattern, as well as for each M-
character subsequences of text to be compared. If the hash values are unequal, the algorithm will determine
the hash value for next M-character sequence. If the hash values are equal, the algorithm will analyze the
pattern and the M-character sequence. In this way, there is only one comparison per text subsequence, and
character matching is only required when the hash values match.

RABIN-KARP-MATCHER (T, P, d, q)
1. n ← length [T]
2. m ← length [P]
3. h ← dm-1 mod q
4. p ← 0
5. t0 ← 0
6. for i ← 1 to m
7. do p ← (dp + P[i]) mod q
8. t0 ← (dt0+T [i]) mod q
9. for s ← 0 to n-m
10. do if p = ts
11. then if P [1.....m] = T [s+1.....s + m]
12. then "Pattern occurs with shift" s
13. If s < n-m
14. then ts+1 ← (d (ts-T [s+1]h)+T [s+m+1])mod q

worst case scenario O ((n-m+1) m

If the expected number of strong shifts is small O (1) and prime q is chosen to be quite large, then the
Rabin-Karp algorithm can be expected to run in time O (n+m) plus the time to require to process spurious
hits.

Knuth-Morris and Pratt introduce a linear time algorithm for the string matching problem. A matching
time of O (n) is achieved by avoiding comparison with an element of 'S' that have previously been involved
in comparison with some element of the pattern 'p' to be matched.
Components of KMP Algorithm:
1. The Prefix Function (Π): The Prefix Function, Π for a pattern encapsulates knowledge about
how the pattern matches against the shift of itself. This information can be used to avoid a useless
shift of the pattern 'p.' In other words, this enables avoiding backtracking of the string 'S.'

2. The KMP Matcher: With string 'S,' pattern 'p' and prefix function 'Π' as inputs, find the
occurrence of 'p' in 'S' and returns the number of shifts of 'p' after which occurrences are found.

Definition of NP class Problem: - The set of all decision-based problems came into the division of NP
Problems who can't be solved or produced an output within polynomial time but verified in the polynomial
time. NP class contains P class as a subset. NP problems being hard to solve.

Definition of P class Problem: - The set of decision-based problems come into the division of P
Problems who can be solved or produced an output within polynomial time. P problems being
easy to solve

Definition of Polynomial time: - If we produce an output according to the given input within a
specific amount of time such as within a minute, hours. This is known as Polynomial time.

Definition of Non-Polynomial time: - If we produce an output according to the given input but
there are no time constraints is known as Non-Polynomial time. But yes output will produce but
time is not fixed yet.

Definition of NP-hard class: - Here you to satisfy the following points to come into the division
of NP-hard

1. If we can solve this problem in polynomial time, then we can solve all NP problems in
polynomial time
2. If you convert the issue into one form to another form within the polynomial time

Definition of NP-complete class: - A problem is in NP-complete, if

1. It is in NP
2. It is NP-hard

NP: is the set of decision problems that can be verified in polynomial time.

NP-Hard: L is NP-hard if for all L' ϵ NP, L' ≤p L. Thus if we can solve L in polynomial time, we can
solve all NP problems in polynomial time.

NP-Complete L is NP-complete if

1. L ϵ NP and
2. L is NP-hard

Common questions

Powered by AI

A disconnected graph cannot yield a spanning tree by definition, as a spanning tree must include all vertices of the graph with minimum connections (n-1 edges for n vertices), without cycles . Spanning tree algorithms, such as those using Kruskal's or Prim's method, assume an initially connected graph to function correctly, adding edges to form a subgraph that is both acyclic and fully connected . If a graph is disconnected, these algorithms cannot cover all vertices without violating their required properties, thus rendering the algorithms for Minimum Spanning Tree construction inapplicable . Moreover, a connected minimum spanning forest, which comprises a collection of spanning trees for each component, may be considered instead where disconnection is inherent .

The Rabin-Karp algorithm is particularly efficient in scenarios where multiple patterns need to be searched simultaneously within a large text body, or where patterns have a fixed length, due to its rolling hash function which can handle simultaneous checks efficiently . It computes a hash for the pattern and text substrings, enabling fast identification of potential matches before verifying the characters, reducing unnecessary comparisons. Thus, for applications requiring multi-pattern matching, like plagiarism detection or DNA sequencing, its ability to handle large patterns with linear average complexity, O(n+m), plus processing time for spurious hits, makes it superior . However, it relies on a good hash function to minimize collisions and ensure performance .

The primary advantage of the Knuth-Morris-Pratt (KMP) algorithm lies in its efficiency through preprocessing of a pattern to create a partial match table (prefix function), which allows the algorithm to skip unnecessary comparisons once mismatches occur, achieving an overall time complexity of O(n). This makes KMP very efficient for scenarios where the text and pattern sizes are large, as it minimizes redundant checks. The drawback is the additional preprocessing step to create the prefix table, which adds upfront computational overhead and complexity compared to simpler algorithms like the naive string matcher, making it less ideal for small text sizes or patterns where preprocessing time outweighs match time benefits .

A decision problem is classified as NP-complete if it meets two primary criteria: it must be in NP, meaning its solution can be verified in polynomial time, and it must also be NP-hard . This means that any problem in NP can be transformed into this problem in polynomial time . The duality of these criteria implies that NP-complete problems are both as challenging as the hardest problems in NP (due to the NP-hard designation) and have solutions that are verifiable in polynomial time, thus representing the most complex problems that are still tractable in the sense of validation if not immediate resolution .

A Minimum Spanning Tree (MST) is unique if all the edge weights in the graph are distinct. This uniqueness occurs because any choice of alternative edges would have a greater weight and thus would not be viable in minimizing the overall cost . When all edges have unique weights, there's only one optimal way to connect all vertices without forming a cycle and using minimal weight edges . If edge weights are not distinct, multiple spanning trees of the same minimal total weight can exist, thereby losing uniqueness unless further specified criteria (like lexicographical order) are applied .

Kruskal's Algorithm is particularly efficient for constructing a Minimum Spanning Tree (MST) in a connected, weighted graph when the graph has a large number of edges. It arranges edges in order of increasing weight and adds them sequentially, avoiding cycles, until the MST is complete . The algorithm runs efficiently in O(E log E) with simple data structures, making it suitable for dense graphs where the number of edges E greatly exceeds the number of vertices V . However, its limitations include inefficiency when the graph is sparse, requiring more sophisticated data structures for optimal performance. Additionally, it might not perform well in parallelized computing environments due to its reliance on sorting edges .

Huffman Coding employs a greedy strategy by building a binary tree where each character from the data is represented as a leaf node. It constructs this tree using a priority queue of characters, sorted by frequency, ensuring the least frequent characters (nodes) are merged first into new nodes, iteratively reducing the queue size . The factors it considers for efficient encoding include the frequency of occurrences; more frequent characters are given shorter binary codes, which minimizes the overall storage required for the data . By always combining the least frequent nodes, it ensures that the resulting codes provide the optimal compression of the input dataset .

Prim's Algorithm and Kruskal's Algorithm both find a Minimum Spanning Tree (MST) using a greedy approach but differ in execution. Prim's Algorithm starts with an empty tree and grows the MST by repeatedly adding the cheapest edge from the tree to a vertex not in the tree, focusing on a 'vertex-centric' approach . It is more efficient for dense graphs due to its complexity of O(V^2) or O(E + V log V) with priority queue optimizations . Kruskal's Algorithm, in contrast, is 'edge-centric,' sorting all edges upfront, then sequentially adding the shortest edge unless it creates a cycle, until (n-1) edges are included . Its complexity, O(E log E), makes it efficient for graphs with fewer edges than vertices, i.e., sparse graphs. Prim's is advantageous for an adjacency matrix representation, while Kruskal's better suits edge lists .

The greedy method differs from other techniques, like Divide and Conquer, by making decisions based on the current available information without considering the future consequences of those decisions . This characteristic means it provides a feasible solution that may not always be optimal because it only focuses on immediate gains rather than overall efficiency . Unlike other strategies that might find global optima, the greedy method could end up stuck in a local optimum, hence failing to provide the globally best solution. Moreover, its simplistic decision rule might not properly account for complex problem constraints, leading to suboptimal solutions in certain contexts .

Negative edges impact Dijkstra's Algorithm because it assumes all edge weights are nonnegative in ensuring the shortest path condition holds correctly; thus it can fail or give incorrect results if negative edges are present . In contrast, Bellman-Ford Algorithm handles graphs with negative weight edges effectively, as it iteratively relaxes all edges and can identify negative weight cycles if present . Although slower, running in O(VE) time, Bellman-Ford's capability to correctly determine shortest paths even in graphs with negative weights demonstrates its versatility over Dijkstra's Algorithm, making it preferable in such scenarios .

You might also like