Python Practice: Greedy Algorithms – Activity Selection, Fractional Knapsack Problem

Table of Contents

  1. Introduction
  2. Activity Selection Problem
    1. Overview
    2. Algorithm
    3. Implementation
    4. Example
  3. Fractional Knapsack Problem
    1. Overview
    2. Algorithm
    3. Implementation
    4. Example
  4. Conclusion

Introduction

In this tutorial, we will explore two classic problems that can be solved using greedy algorithms: the Activity Selection Problem and the Fractional Knapsack Problem. Greedy algorithms make locally optimal choices at each step with the hope of finding a global optimum solution. By the end of this tutorial, you will understand the concepts behind these two problems and be able to implement the corresponding algorithms in Python.

Before we proceed, make sure you have the following prerequisites:

  • Basic understanding of Python programming language.
  • Familiarity with lists and sorting.
  • Python installed on your machine.

Activity Selection Problem

Overview

The Activity Selection Problem involves selecting a maximum-sized set of mutually compatible activities from a given set, assuming that the activities are sorted by their finish time. The goal is to find the largest set of non-overlapping activities that can be performed.

Algorithm

To solve the Activity Selection Problem, we can use a greedy algorithm that iteratively selects activities with the earliest finish time. Here’s the high-level algorithm:

  1. Sort the activities by their finish time in ascending order.
  2. Initialize an empty list selected_activities to store the selected activities.
  3. Select the first activity from the sorted list (since it has the earliest finish time) and add it to selected_activities.
  4. For each remaining activity, if the start time is greater than or equal to the finish time of the last selected activity, add it to selected_activities.
  5. Repeat step 4 until all activities are considered.
  6. Return selected_activities as the maximum-sized set of non-overlapping activities.

Implementation

Let’s implement the Activity Selection algorithm in Python: ```python def activity_selection(activities): activities.sort(key=lambda x: x[1]) # Sort by finish time selected_activities = [activities[0]] # Select the first activity

    for activity in activities[1:]:
        if activity[0] >= selected_activities[-1][1]:
            selected_activities.append(activity)

    return selected_activities
``` ### Example

Consider the following list of activities, where each activity is represented as a tuple (start_time, finish_time): python activities = [(1, 4), (5, 7), (2, 6), (8, 10), (9, 11), (3, 9)] By applying the Activity Selection algorithm, we can find the maximum-sized set of non-overlapping activities: python selected = activity_selection(activities) print(selected) # Output: [(1, 4), (5, 7), (8, 10)] In this example, the activities (1, 4), (5, 7), and (8, 10) can be performed without any overlap, providing the maximum-sized set.

Fractional Knapsack Problem

Overview

The Fractional Knapsack Problem involves selecting a combination of items (with fractional quantities) to maximize the total value within a given capacity constraint. Each item has both a weight and a value associated with it.

Algorithm

To solve the Fractional Knapsack Problem, we can use a greedy algorithm that selects items based on their value-to-weight ratio. Here’s the high-level algorithm:

  1. Compute the value-to-weight ratio for each item.
  2. Sort the items in descending order of their value-to-weight ratios.
  3. Initialize the result selected_items as an empty list.
  4. For each item, if the weight of the current item is less than or equal to the remaining capacity, add it to selected_items and subtract its weight from the remaining capacity.
  5. If the weight of the current item is greater than the remaining capacity, calculate the fraction of the item that can be added to selected_items based on the remaining capacity and add it.
  6. Repeat steps 4 and 5 until all items are considered or the remaining capacity becomes zero.
  7. Return selected_items as the selected combination of items.

Implementation

Let’s implement the Fractional Knapsack algorithm in Python: ```python def fractional_knapsack(items, capacity): items.sort(key=lambda x: x[1] / x[0], reverse=True) # Sort by value-to-weight ratio selected_items = []

    for item in items:
        if capacity >= item[0]:
            selected_items.append(item)
            capacity -= item[0]
        else:
            fraction = capacity / item[0]
            selected_items.append((item[0] * fraction, item[1] * fraction))
            break

    return selected_items
``` ### Example

Consider the following list of items, where each item is represented as a tuple (weight, value): python items = [(10, 60), (20, 100), (30, 120)] capacity = 50 By applying the Fractional Knapsack algorithm, we can find the selected combination of items: python selected = fractional_knapsack(items, capacity) print(selected) # Output: [(20, 100), (30, 120)] In this example, the total weight of the selected items (20, 100) and (30, 120) is equal to the remaining capacity of 50, providing the maximum total value.

Conclusion

In this tutorial, we explored two classic problems that can be solved using greedy algorithms: the Activity Selection Problem and the Fractional Knapsack Problem. We learned the concepts behind these problems and implemented the corresponding algorithms in Python. By applying these algorithms, we can efficiently find optimal solutions in various scenarios.

Remember, greedy algorithms make locally optimal choices, but they might not always lead to the globally optimal solution. It’s important to thoroughly understand the problem and analyze the given constraints before applying greedy algorithms.

Now that you have a deeper understanding of greedy algorithms and their applications, you can further explore other problems where greedy strategies can be employed. Keep practicing and experimenting with different algorithms to enhance your problem-solving skills.