# Greedy Algorithm Example

## An Introduction to Greedy Algorithm

A greedy algorithm is a fundamental approach in computer science and optimization. It is a simple and intuitive strategy used to solve various problems and to make a series of choices that lead to an optimal solution. Essentially, a greedy algorithm makes locally optimal choices at each step, hoping that those choices will lead to a globally optimal solution. In other words, it makes the best possible decision in the current situation without considering possible future consequences. Here's an overview of how the greedy algorithm works:

2. Selection: At each stage, select the best available option according to certain criteria. This choice is based on the current situation without considering the whole problem.
3. Feasibility: Check if the selected option is feasible. If so, add it to the solution; discard it.
4. Termination: Repeat steps 2 and 3 until the termination condition is met. This condition can be achieving the desired solution's quality or thoroughly evaluating all alternatives.
5. Solution: Finally, the options chosen to form the solution to the problem. It is important to note that although a greedy algorithm is easy to implement and may work well for some problems, it does not guarantee an optimal solution for all problems.

In some cases, the greedy approach may lead to a suboptimal result, but in others, it may find a globally optimal solution. The choice of selection criteria ("greedy selection") is critical to the algorithm's success. The criteria must be chosen to correspond to the problem's characteristics and ensure the positive effect of the choice chosen at each stage on the overall solution. Problem that can be solved using greedy algorithms include the Coin exchange problem (minimizing the number of coins per given amount). The broken backpack problem (maximizing the value of objects placed in a backpack of limited capacity). Huffman coding (efficient data compression). The Greedy algorithm is a powerful and versatile tool. However, understanding its limitations and carefully analyzing the problem is important to determine if a greedy approach is appropriate and likely to produce the desired result.

## History of Greedy algorithm

The concept of a greedy algorithm has a long history in various fields, going back in some form to ancient times. Although the term "greedy algorithm" may not have been used explicitly, the principles of making local optimal choices have been applied to problem-solving for centuries. Here is a brief historical overview:

1. Ancient Mathematics and Coin Tossing: The earliest known application of the greedy approach is the coin-tossing problem. Ancient civilizations needed to exchange goods and services, and their challenge was to make the change with as few coins as possible. This problem can be solved by a simple greedy strategy of always choosing the largest currency denomination that is not greater than the remaining convertible amount.
2. Huffman coding: One of the best-known applications of the greedy algorithm is data compression, specifically using Huffman coding, which was developed by David. Huffman in 1952. Huffman coding creates an optimal prefix binary tree for character coding in a way that minimizes. The total number of bits necessary for the representation. The algorithm builds the tree repeatedly by combining the two least frequent symbols at each step, a clear example of greedy selection.
3. Graph theory: The greedy algorithm has been applied to graph theory problems since the mid-20th century. One famous example is Prim's algorithm for finding the minimum spanning tree of a graph. The algorithm starts from a single vertex and iteratively adds the lowest weight edge associated with the existing tree. This greedy approach ensures that the end result is at least a configuration tree. Dijkstra's algorithm: Another important contribution is Dijkstra's algorithm for finding the shortest path in a graph, published by Edsger W. Dijkstra in 1959. The algorithm maintains a set of vertices with the shortest known distance from the source, expanding that set to minimize the currently known distance to each vertex, representing a greedy choice at each step.
4. Activity Selection Problem: This classic problem involves selecting the largest set of mutually compatible activities from a given set, each associated with a start and end time. The greedy algorithm for this problem involves ordering the activities according to their finish times and selecting them so they do not overlap.

During the development of computer science and various fields, the greedy algorithm has proven to be a valuable and often intuitive technique for solving optimization tasks. This paved the way for the development of efficient algorithms for many applications.

## Some Examples of a Greedy algorithm

### Problem 1:

You are given an array of coins (e.g., 1 cent, 5 cents, 10 cents, 25 cents) and a target in cents. Find the minimum number of coins needed to make the target amount.

Greedy access:

1. Start with the largest value less than or equal to the target amount.
2. Continue subtracting the largest possible multiple of that denomination from the target amount if the target amount is greater than 0.
3. Move to the next smaller denomination and repeat the process until the target amount is 0.

Example:

Let's say we have nominal coins: 1 cent, 5 cents, 10 cents, and 25 cents, and we want to change 63 cents.

Greedy solution:

1. Start with the largest value, 25 cents. We can use two of the 25 cents, which leaves us with 13 cents in change.
2. The next largest value, 10 cents, can be used once, leaving us with 3 cents.
3. The remaining amount is less than the smallest value, 5 cents, so we use three 1 cents to complete the exchange.

Result:

The minimum amount to make 63 cents is 6 coins (two 25 cents, one 10 cents, and three 1 cents). It is important to note that the greedy algorithm only sometimes works for all optimization problems and may not find the globally optimal solution in all cases.

For certain problems, such as the coin toss problem, where the greedy choice property holds (i.e., making a locally optimal choice at each step leads to a globally optimal solution), the greedy approach works well and provides an efficient solution.

### Problem 2:

You are given a series of tasks, each with a start and end time. The goal is to select the maximum number of non-overlapping tasks that can be completed.

Greedy access:

1. Sort tasks by their due dates in ascending order.
2. Scroll through the sorted task list and select the task with the earliest due date that does not overlap with previously selected tasks.

Example:

Let's have the following tasks with start and end times.

Task 1: (start time: 1, end time: 4)

Task 2: (start time: 3, end time: 5)

Task 3: (start time: 0, end time: 6)

Task 4: (start time: 5, end time: 7)

Task 5: (start time: 3, end time: 9)

Task 6: (start time: 5, end time: 9)

Task 7: (start time: 6, end time: 10)

Greedy solution:

3. Go to task 7 (earliest finish time after task 5: 10) because tasks 3 and 4 overlap with tasks 1 and 5.

Result:

A maximum of 3 non-overlapping missions can be completed, and the selected missions are Mission 1, Mission 5, and Mission 7. The greedy algorithm for the interval scheduling problem works because choosing the tasks with the earliest finish times ensures more time for other tasks. By repeatedly selecting the task with the earliest completion time that does not coincide with the previously selected tasks, we can find an optimal solution to this problem.

### Problem 3:

You get a set of items, each with weight and value, and a backpack with the largest carrying capacity. The goal is to fill the backpack with items to maximize the total value. Unlike the classic 0/1 backpack problem, you can still pick up some items.

Greedy access:

1. Calculate the value-to-weight ratio (value divided by weight) of each product.
2. Sort products by their value-to-weight ratio in descending order.
3. Add items to the backpack in the order of the ranked list until the backpack is full.

If an item doesn't quite fit, take part of it to fill the remaining capacity.

Example:

Suppose you have the following items with weights and values:

Item 1. (Weight: 10, Value: 60)

Item 2: (Weight: 20, Value: 100)

Item 3: (Weight: 30, Value: 120)

And the maximum carrying capacity of the backpack is 50.

Greedy solution:

1. Calculate the value and weight ratios.
2. Sort the products in descending order by the value-to-weight ratio: item 1, item 2, item 3.
4. Take Full Item 1 (Weight: 10, Value: 60).
5. Remaining capacity: 50 - 10 = 40.
6. Take 40% of item 2 (weight: 20, value: 100) that fits in the remaining capacity. Remaining capacity: 40 - 40% * 20 = 32.
7. No point 3 fits in the remaining capacity (30 > 32), so we stop here.

Result:

The maximum total value obtained by filling the backpack with partial goods is 60 (from 1) 40% * 100 (from 2) = 60 40 = 100.

The greedy algorithm of the fractional knapsack problem works because it focuses on selecting items with the highest value-to-weight ratio, ensuring that the most valuable items are included as much as possible, even in fractions, if necessary.

Next Topic#