Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
2 views

Python_M4

The document outlines various algorithmic approaches to problem-solving using Python, including Brute Force, Divide and Conquer, Dynamic Programming, Greedy algorithms, and Randomized approaches. It provides detailed explanations, examples, advantages, and disadvantages of the Brute Force and Divide and Conquer methods, highlighting their characteristics and applications. The content is structured for a semester course at the College of Engineering Trikaripur, emphasizing computational strategies for effective problem-solving.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Python_M4

The document outlines various algorithmic approaches to problem-solving using Python, including Brute Force, Divide and Conquer, Dynamic Programming, Greedy algorithms, and Randomized approaches. It provides detailed explanations, examples, advantages, and disadvantages of the Brute Force and Divide and Conquer methods, highlighting their characteristics and applications. The content is structured for a semester course at the College of Engineering Trikaripur, emphasizing computational strategies for effective problem-solving.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

Algorithmic Thinking with Python

SEMESTER S1(Common to All Branches)

Huda Noor Dean


College of Engineering Trikaripur
Computational Approaches to Problem Solving
Brute Force Approach

Divide and Conquer Approach

Dynamic Programming Approach

Greedy algorithm Approach

Randomized Approach

Huda Noor Dean College of Engineering Trikaripur 1 / 79


Outline
Brute Force Approach

Divide and Conquer Approach

Dynamic Programming Approach

Greedy algorithm Approach

Randomized Approach

Huda Noor Dean College of Engineering Trikaripur 2 / 79


Brute Force Approach

A brute force algorithm is a simple, comprehensive search strategy that


systematically explores every option until a problem’s answer is discovered.
The brute force approach is a guaranteed way to find the correct solution
by listing all the possible candidate solutions for the problem.
It is a generic method and not limited to any specific domain of problems.
The brute force method is ideal for solving small and simpler problems.

Huda Noor Dean College of Engineering Trikaripur 3 / 79


Padlock example

Imagine you have a small padlock with 4 digits, each


from 0-9. You forgot your combination, but you don’t want
to buy another padlock. Since you can’t remember any of the
digits, you have to use a brute force method to open the lock.
The brute-force approach would involve sequentially trying
every possible combination from ”0000” to ”9999” until the
correct code unlocks the padlock. So you set all the numbers
back to 0 and try them one by one: 0001, 0002, 0003, and so
on until it opens. In the worst case scenario, it would take 104 ,
or 10,000 tries to find your combination.
Huda Noor Dean College of Engineering Trikaripur 4 / 79
Password guessing
A brute force attack is a hacking technique that employs trial and error to
breach passwords. This technique systematically tries every possible
combination of characters until the correct password is found. Brute force
attacks can be automated using software that can attempt millions of
combinations per second, making them effective against weak passwords.
The name ‘brute force’ is a way of achieving something by strength — not
always with the best strategy or technology.
For instance, attacking a six-character password consisting of letters and
digits would involve testing all 2.18 billion (366 ) possible combinations until
the correct one is identified.

Huda Noor Dean College of Engineering Trikaripur 5 / 79


Characteristics of Brute-Force Solutions

1. Exhaustive Search: Every possible solution is examined without any


optimization.
2. Simplicity: Easy to understand and implement.
3. Inefficiency: Often slow and resource-intensive due to the large number
of possibilities.
4. Guaranteed Solution: If a solution exists, the brute-force method will
eventually find it.

Huda Noor Dean College of Engineering Trikaripur 6 / 79


Problem-1 (String Matching)
String matching algorithm is a simple method for finding all occurrences of
a pattern within a text. Slide the pattern over the text one character at a
time and check if the pattern matches the substring of the text starting at
the current position.
1. Start at the beginning of the text: Begin by aligning the pattern with the
first character of the text.
2. Check for a match: Compare the pattern with the substring of the text
starting at the current position. If the substring matches the pattern, record
the position.
3. Move to the next position: Shift the pattern one character to the right and
repeat the comparison until you reach the end of the text.
4. Finish: Continue until all possible positions in the text have been
checked.
Huda Noor Dean College of Engineering Trikaripur 7 / 79
example

Huda Noor Dean College of Engineering Trikaripur 8 / 79


def brute_force_string_match(text, pattern):
n = len(text) # Length of the text
m = len(pattern) # Length of the pattern
for i in range(n - m + 1):
substring = text[i:i + m]
if substring == pattern: # Compare substring with pattern
print("Pattern found at index",i")
""" Loop over each possible starting index in the text, Extracting
the substring of the text from the current position """
# Example usage
text = "ABABDABACDABABCABAB"
pattern = "ABABCABAB"
brute_force_string_match(text, pattern)
Huda Noor Dean College of Engineering Trikaripur 9 / 79
Problem-2 (Subset Sum Problem)

The Subset Sum Problem involves determining if there exists a subset of a


given set of numbers that sums up to a specified target value. The brute
force approach to solve this problem involves generating all possible
subsets of the set and checking if the sum of any subset equals the target
value.

Brute Force guarantees finding a solution if one exists but can be inefficient
for large sets due to its exponential time complexity.

Huda Noor Dean College of Engineering Trikaripur 10 / 79


Steps

1. Generate subsets: Iterate over all possible subsets of the given set of
numbers.
2. Calculate sums: For each subset, calculate the sum of its elements.
3. Check target: Compare the sum of each subset with the target value.
4. Return result: If a subset’s sum matches the target, return that subset.
Otherwise, conclude that no such subset exists.

Huda Noor Dean College of Engineering Trikaripur 11 / 79


example

Huda Noor Dean College of Engineering Trikaripur 12 / 79


Example :

Use brute force approach and demonstrate how to find the subsets that
sums up to 9 in the list [3, 34, 4, 12, 5, 2].

Huda Noor Dean College of Engineering Trikaripur 13 / 79


Advantages of Brute Force Approach
1. Guaranteed Solution: Brute-force methods ensure finding a solution if
one exists within the predefined constraints.

2. Simplicity: The approach is straightforward to implement and


understand, requiring minimal algorithmic complexity.

3. Versatility: Applicable across various domains where an exhaustive


search is feasible, such as puzzle solving, cryptography, and optimization
problems.

Huda Noor Dean College of Engineering Trikaripur 14 / 79


Disadvantages of Brute Force Approach

▶ The brute force approach is inefficient. For real-time problems,time


taken is O(N!) order of growth.
▶ This method relies more on compromising the power of a computer
system for solving a problem than on a good algorithm design.
▶ Brute force algorithms are slow.
▶ Brute force algorithms are not constructive or creative compared to
other algorithmic approaches.

Huda Noor Dean College of Engineering Trikaripur 15 / 79


Outline
Brute Force Approach

Divide and Conquer Approach

Dynamic Programming Approach

Greedy algorithm Approach

Randomized Approach

Huda Noor Dean College of Engineering Trikaripur 16 / 79


Divide and Conquer Approach

Divide and Conquer Algorithm is a problem-solving technique used to solve


problems by dividing the main problem into subproblems, solving them
individually and then merging them to find solution to the original problem.
The basic idea is to recursively divide the problem into smaller
subproblems until they become simple enough to be solved directly. Once
the solutions to the subproblems are obtained, they are then combined to
produce the overall solution.

Huda Noor Dean College of Engineering Trikaripur 17 / 79


Divide and Conquer Approach

Huda Noor Dean College of Engineering Trikaripur 18 / 79


Working of Divide and Conquer Algorithm:
1. Divide: Break down the original problem into smaller subproblemsuntil
no further division is possible. Each subproblem should represent a part of
the overall problem.
2. Conquer: Solve each of the smaller subproblems individually. If a
subproblem is small enough (often referred to as the “base case”), we
solve it directly without further recursion.
3. Merge: Once the smaller subproblems are solved, we recursively
combine their solutions to get the solution of larger problem. The goal is to
formulate a solution for the original problem by merging the results from the
subproblems.

Huda Noor Dean College of Engineering Trikaripur 19 / 79


Divide and Conquer Merge Sort
Merge Sort is a classic example of the divide-and-conquer strategy used
for sorting an array of elements.
▶ It operates by recursively breaking down the array into progressively
smaller sections.
▶ The core idea is to split the array into two halves, sort each half, and
then merge them back together.
▶ 1. Divide: Split the array into two halves.
2. Conquer: Recursively sort both halves.
3. Combine: Merge the two sorted halves to produce the sorted array.

Huda Noor Dean College of Engineering Trikaripur 20 / 79


Divide and Conquer Approach

Huda Noor Dean College of Engineering Trikaripur 21 / 79


Visualization or demonstrate to sort [38, 27, 43, 3, 9, 82, 10].
Step 1: Divide the Array 1. Initial Array: [38, 27, 43, 3, 9, 82, 10]
2. Divide into Halves:

Left Half: [38, 27, 43,3]


Right Half: [ 9, 82, 10]

3. Further Divide: Left Half: [38, 27, 43, 3] becomes:


Left Half:[38, 27] and Right Half: [ 43,3]

4. Further [38, 27] becomes: [38] and [27]


5. Further [43,3] becomes: [43] and [3]

Huda Noor Dean College of Engineering Trikaripur 22 / 79


Steps :
Step 2: Merge the Arrays
1. Merge Smaller Arrays:
– [38] and [27] are merged to form [27,38]
– [43] and [3] are merged to form [3, 43]
– [9] and [82] are merged to form [9, 82]

2. Merge Larger Arrays:


– [27,38] and [3, 43] are merged to form [3,27, 38, 43]
- [9,82] and [10] are merged to form [9,10,82]

3. Merge to get final Array:


- [3,27, 38, 43] and [9,10,82] to form [3,9,10,27,38,43,82]
Huda Noor Dean College of Engineering Trikaripur 23 / 79
Finding the Maximum Element in an Array
Given an array of integers, find the maximum value in the array.

Step-by-Step Solution :

1. Initial Setup:
Begin with the entire array and determine the range to process. Initially, this
range includes the entire array from the first element to the last element.

2. Divide
If the array contains more than one element, split it into two approximately
equal halves. This splitting continues recursively until each subarray has
only one element.
Huda Noor Dean College of Engineering Trikaripur 24 / 79
Finding the Maximum Element in an Array
3. Conquer:
-For subarrays with only one element, that element is trivially the maximum
for that subarray.
- For larger subarrays, recursively apply the same process to each half of
the subarray.

4.Combine:
- After finding the maximum element in each of the smaller subarrays,
combine the results by comparing the maximum values from each half.
Return the largest of these values as the maximum for the original array.

Huda Noor Dean College of Engineering Trikaripur 25 / 79


Step by step explanation
For the array [3, 6, 2, 8, 7, 5, 1] find max element.

1. Initial Setup:
Array starts with indices 0 and len(array) - 1.
i.e 0 and 6

2. Divide:
- Calculate the middle index mid of the current array segment.
mid would be (0 + 6) // 2 = 3.

Split the array into two halves based on this mid index
– Left half: [3, 6, 2, 8] and Right half: [7, 5, 1]
Huda Noor Dean College of Engineering Trikaripur 26 / 79
Step by step explanation
Split into [3, 6] and [2, 8]
– Further split [3, 6] into [3] and [6]

Similarly Split into [7, 5, 1] to [7,5] and [1]


– Further split [7, 5] into [7] and [5]

3. Conquer
For subarrays with only one element, that element is trivially the maximum
for that subarray.

Huda Noor Dean College of Engineering Trikaripur 27 / 79


Step by step explanation

4. Combine
After finding the maximum element in each of the smaller subarrays,
combine the results by comparing the maximum values from each half.
- from [3, 6] , max is 6 and from [2, 8] , max is 8.
- from [7,5] , max is 7 and [1] is 1 itself.

- from [3,6] and [2, 8] , max is 8. - from [7,5] and [1] , max is 7
- from [3, 6, 2, 8] and [7, 5, 1] , max is 8

Huda Noor Dean College of Engineering Trikaripur 28 / 79


Advantages of Divide and Conquer Approach
▶ Simplicity in Problem Solving: By breaking a problem into smaller
subproblems, each subproblem is simpler to understand and solve and
complexity reduced.
▶ Efficiency: Often have lower time complexities compared to iterative
approaches.
▶ Modularity: Divide-and-conquer promotes a modular approach to
problem solving, where each subproblem can be handled by a
separate function or module.
▶ Parallelism: The divide-and-conquer approach can easily be
parallelized because the subproblems can be solved independently
and simultaneously
Huda Noor Dean College of Engineering Trikaripur 29 / 79
Disadvantages of Divide and Conquer Approach
▶ Overhead of Recursive Calls: The recursive nature can lead to
significant overhead due to function calls and maintaining the call stack
and may cause stack overflow.
▶ Increased Memory Usage: Divide-and-conquer algorithms often
require additional memory for storing intermediate results.
▶ Complexity of Merging Results: The merging step can be complex and
may not always be straightforward.
▶ Difficulty in Implementation: Implementing divide-and-conquer
algorithms can be more challenging/

Huda Noor Dean College of Engineering Trikaripur 30 / 79


Outline
Brute Force Approach

Divide and Conquer Approach

Dynamic Programming Approach

Greedy algorithm Approach

Randomized Approach

Huda Noor Dean College of Engineering Trikaripur 31 / 79


Dynamic Programming Approach

overlapping subproblems to avoid redundant calculations Dynamic


programming is a method for solving a complex problem by breaking it up
into smaller subproblems, and store the results of the subproblems for later
use .It is a way of combining solutions to overlapping subproblems to avoid
redundant calculations

Wherever we see a recursive solution that has repeated calls for same
inputs, we can optimize it using Dynamic Programming.

Huda Noor Dean College of Engineering Trikaripur 32 / 79


Nth fibnocci term using recursion
The sequence Fn of Fibonacci numbers is defined by the recurrence
relation Fn = Fn-1 + Fn-2, with initial values F0 = 0 and F1 = 1.
def Fibonacci(n):

if n == 1:
return 0

elif n == 2:
return 1
else:
return (Fibonacci(n-1)+Fibonacci(n-2))

x=int(input(’enter
Huda Noor Dean number’)) College of Engineering Trikaripur 33 / 79
Nth fibnocci term using Recursion

Huda Noor Dean College of Engineering Trikaripur 34 / 79


Nth fibnocci term using Dynamic Programming
Using the color-coded image above, we can see just how many overlapping
subproblems there are. To solve for fib(5), we need to calculate fib(3) twice,
fib(2) three times etc. This is duplication that we would like to eliminate.
Optimal substructure means an optimal solution can be constructed from
optimal solutions of its subproblems.
Fibonacci of n is defined as follows:

fib(n) = fib(n − 1) + fib(n − 2)

Huda Noor Dean College of Engineering Trikaripur 35 / 79


Dynamic Programming Approach
There are two ways to solve the Fibonacci problem using dynamic
programming.
1. Memoization
Memoization stores the result of expensive function calls (in arrays) and
returns the stored results whenever the same inputs occur again. Already
calculated values can be accessed instead of repeating the same
calculation.(Top- Down Approach-similar to recursive procedure).
2. Tabulation Tabulation is an iterative method ( loop). Starting from the
smallest subproblem, and store the results in a table (an array).

This is a bottom-up approach. We start from the bottom, finding fib(0) and
fib(1), add them together to get fib(2) and so on until we reach fib(5).
Huda Noor Dean College of Engineering Trikaripur 36 / 79
Nth fibnocci term program
def Fibonacci(n):

if (n == 1 or n == 2):
return 1

else:
fibNums = [0, 1,1];
print(fibNums)
for i in range(3,n):
fibNums.append (fibNums[i-1] + fibNums[i-2])
print(fibNums)
return fibNums[n-1]
x=int(input(’enter
Huda Noor Dean number’)) College of Engineering Trikaripur 37 / 79
Recursion vs Dynamic Programming
Dynamic programming is mostly applied to recursive algorithms. This is not
a coincidence, most optimization problems require recursion and dynamic
programming is used for optimization. But not all problems that use
recursion can use Dynamic Programming. Unless there is a presence
of overlapping sub-problems like in the Fibonacci sequence problem, a
recursion can only reach the solution using a divide and conquer approach.
This is the reason why a recursive algorithm like Merge Sort cannot use
Dynamic Programming, because the subproblems are not overlapping in
any way.

Huda Noor Dean College of Engineering Trikaripur 38 / 79


Outline
Brute Force Approach

Divide and Conquer Approach

Dynamic Programming Approach

Greedy algorithm Approach

Randomized Approach

Huda Noor Dean College of Engineering Trikaripur 39 / 79


Greedy algorithm Approach
A greedy algorithm is an approach for solving a problem by selecting the
best option available at the moment. It doesn’t worry whether the current
best result will bring the overall optimal result.
The algorithm never reverses the earlier decision even if the choice is
wrong. The most appealing aspect of greedy algorithm is that they are
simple and efficient.
This algorithm may not produce the best result for all the problems. It’s
because it always goes for the local best choice to produce the global best
result.

Huda Noor Dean College of Engineering Trikaripur 40 / 79


Greedy algorithm Approach

1. To begin with, the solution set (containing answers) is empty.


2. At each step, an item is added to the solution set until a solution is
reached.
3. If the solution set is feasible, the current item is kept.
4. Else, the item is rejected and never considered again.

Huda Noor Dean College of Engineering Trikaripur 41 / 79


Example 1: Task Completion Problem

Being a very busy person, you have exactly T time to do some interesting
things and you want to do maximum such things.
You are given an array A of integers, where each element indicates the
time a thing takes for completion. You want to calculate the maximum
number of things that you can do in the limited time that you have.

Huda Noor Dean College of Engineering Trikaripur 42 / 79


Greedy algorithm Solution
Using a simple Greedy-algorithm problem, we greedily select the things
which will take the minimum amount of time to complete.Two variables
currentTime and numberOfThings are maintained.
1. Sort the array A in increasing order.
2. Select each to-do item one-by-one.
3. Add the time that it will take to complete that task into currentTime.
4. Add one to numberOfThings.
5. Repeat this as long as the currentTime is less than or equal to T.

Huda Noor Dean College of Engineering Trikaripur 43 / 79


Example
Consider the example usage with completionTimes = [2, 3, 1, 4, 6] and
available time = 8:
- After sorting: [1, 2, 3, 4, 6]
Iterating:
- Add task with time 1: totaltime = 1, taskcount = 1
- Add task with time 2: totaltime = 3, taskcount = 2
- Add task with time 3: totaltime = 6, taskcount = 3
- Next task with time 4 would exceed availabletime, so the loop breaks.
The maximum number of tasks that can be completed in 8 units of time is 3.

Huda Noor Dean College of Engineering Trikaripur 44 / 79


numberOfTask = 0 currentTime = 0
N=int(input('Enter the number of Tasks: '))
T=int(input('Time Available: '))
A=[]
for i in range(0,N):
A.append(int(input(f'Enter the time required for Task {i+1} :')))
A.sort()
for i in range(0,N):
if currentTime+A[i]<=T :
currentTime += A[i];
numberOfTask+=1
print(numberOfTask)
Huda Noor Dean College of Engineering Trikaripur 45 / 79
Example 2:

Huda Noor Dean College of Engineering Trikaripur 46 / 79


capacity given is 2.5 litres = 6 cups

1. Sort the recipe list in descending order of nutritional value.


2. Select each item one-by-one.
3. Add the quantity of the item into total quantity.
4. Add nutritional value to Totalnutritionalvalue.
5. Repeat this as long as the total quantity is less than or equal to 6 cups.

Huda Noor Dean College of Engineering Trikaripur 47 / 79


Selected food items are Cooked rice,Payasam, fish fry,butter milk.
Sambar is not selected as it exceeds 6 cups.
Total nutritional value =1398.
Huda Noor Dean College of Engineering Trikaripur 48 / 79
Example 3: Coin Changing Problem

Given a set of coin denominations, the task is to determine the minimum


number of coins needed to make up a specified amount of money. One
approach to solving this problem is to use a greedy algorithm, which works
by repeatedly selecting the largest denomination that does not exceed the
remaining amount of money. This process continues until the entire amount
is covered.

Huda Noor Dean College of Engineering Trikaripur 49 / 79


Suppose you have coin denominations of 1, 5, 10, and 25 Rupees, and you
need to make change for 63 Rupees.
1. Take two 25-Rupee coins (63 - 50 = 13 Rupees left).
2. Take one 10-Rupee coin (13 - 10 = 3 Rupees left).
3. Take three 1-Rupee coins (3 - 3 = 0 Rupee left).
Thus, the minimum number of coins needed is six (two 25-Rupee coins,
one 10-Rupee coin, and three 1-Rupee coins).

Huda Noor Dean College of Engineering Trikaripur 50 / 79


1. Sort the coin denominations in descending order.
2. Start with the highest denomination and take as many coins of that
denomination as possible without exceeding the amount.
3. Repeat the process with the next highest denomination until the amount
is made up.

Huda Noor Dean College of Engineering Trikaripur 51 / 79


Advantages :

1. Simplicity: Greedy algorithms are generally easy to understand and


implement.
2. Speed: These algorithms typically run quickly, making them suitable
for large input sizes.
3. Optimal for Certain Problems: For some problems, like the Coin
Change Problem with certain denominations, greedy algorithms
provide an optimal solution.

Huda Noor Dean College of Engineering Trikaripur 52 / 79


Disadvantages :

1. Suboptimal Solutions: Greedy algorithms do not always produce the


optimal solution for every problem. They are most effective when the
problem has the greedy-choice property, meaning a global optimum
can be reached by making local optimal choices.
2. Irrevocable Decisions: Once a choice is made, it cannot be changed,
which may lead to a suboptimal solution in some cases.
3. Lack of Backtracking: Greedy algorithms do not explore all possible
solutions or backtracks, which means they can miss better solutions.

Huda Noor Dean College of Engineering Trikaripur 53 / 79


Greedy Algorithms vs. Dynamic Programming
Greedy Algorithms:
▶ Approach: Make the best possible choice at each step based on local
information, without reconsidering previous decisions.
▶ Decision Process: Makes decisions sequentially and irrevocably.
▶ Optimality: Guaranteed to produce optimal solutions only for certain
problems with the greedy-choice property and optimal substructure.
▶ Efficiency: Typically faster and uses less memory due to the lack of
extensive bookkeeping.
▶ Example Problems: Coin Change Problem (specific denominations),
Kruskal’s Algorithm for Minimum Spanning Tree, Huffman Coding.
Huda Noor Dean College of Engineering Trikaripur 54 / 79
Greedy Algorithms vs. Dynamic Programming
Dynamic Programming:
▶ Approach: Breaks down a problem into overlapping sub-problems and
solves each sub-problem only once, storing the results to avoid
redundant computations.
▶ Decision Process: Considers all possible decisions and combines
them to form an optimal solution.
▶ Optimality: Always produces an optimal solution by considering all
possible ways of solving sub-problems and combining them.
▶ Efficiency: Can be slower and use more memory due to storing results
of all sub-problems.
▶ Example Problems: Fibonacci Sequence, Longest Common
Subsequence, Knapsack Problem.
Huda Noor Dean College of Engineering Trikaripur 55 / 79
Outline
Brute Force Approach

Divide and Conquer Approach

Dynamic Programming Approach

Greedy algorithm Approach

Randomized Approach

Huda Noor Dean College of Engineering Trikaripur 56 / 79


Randomized Approach

▶ Randomized algorithms use randomness as part of their logic.


▶ Provide a means of dealing with uncertainty or to optimize
problem-solving.
▶ These algorithms can offer better average-case performance or
simpler implementation.

Huda Noor Dean College of Engineering Trikaripur 57 / 79


Why Use Randomized Algorithms?

▶ Simplicity in implementation.
▶ Robust performance for many cases.
▶ Lower time complexity in expected scenarios.
▶ Widely used in algorithms such as quicksort, Monte Carlo methods,
and others.

Huda Noor Dean College of Engineering Trikaripur 58 / 79


Classic Problem 1: Birthday problem

Imagine a group of students in a classroom, and you want to determine the


probability that at least two students share the same birthday. The exact
calculation involves combinatorial mathematics, but a simulation offers a
more intuitive way to understand the problem. By randomly assigning
birthdays to students across many simulated classrooms and recording the
number of times at least two students share a birthday, we can empirically
estimate the probability.

Huda Noor Dean College of Engineering Trikaripur 59 / 79


Classic Problem 2:Random walk on a grid

A person starts at a fixed point on a grid and takes steps in random


directions. The goal is to determine the expected time it takes for the
person to return to the starting point. Simulating this random walk multiple
times allows us to estimate the average return time, offering insights into
the behavior of random processes.

Huda Noor Dean College of Engineering Trikaripur 60 / 79


Classic Problem 3: Random coin flips problem

Here we want to determine the probability of getting a certain number of


heads in a series of coin flips. For instance, simulating 100 coin flips
repeatedly and counting the number of heads in each simulation allows us
to estimate the probability distribution of getting a specific number of heads.

Huda Noor Dean College of Engineering Trikaripur 61 / 79


Coupon collector’s problem
A company selling jeans gives a coupon for each pair of jeans. There are n
different coupons. Collecting n different coupons would give you free jeans.
How many jeans do you expect to buy before getting a free one?

Each purchase comes with one random coupon.


Every coupon is equally likely to appear.
How many purchases needed to collect all coupons?

Huda Noor Dean College of Engineering Trikaripur 62 / 79


Coupon collector’s problem

No definite answer
The answer is random:
If lucky, then n purchases are enough.
If unlucky, then no purchases will be enough.
More suitable question:
How many purchases needed on average to collect all coupons?

Huda Noor Dean College of Engineering Trikaripur 63 / 79


Algorithmic Solution:

1. Initialize Variables:
- Total Jeans Bought: Start with a counter set to zero to track how many
pairs of jeans you have bought.
- Coupons Collected: Use a set to keep track of the different types of
coupons you have received.(to avoid duplicates use set)
- Number of Coupons: The total number of different coupon types is n.

Huda Noor Dean College of Engineering Trikaripur 64 / 79


Algorithmic Solution:
2. Buying Process:
- Loop Until All Coupons Are Collected: Continue buying jeans until you
have one of each type of coupon in your set.
- Each time you buy a pair of jeans, increase the counter for the total jeans
bought by one.
- When you buy a pair of jeans, you get a coupon. Add this coupon to your
set of collected coupons.
- Check if you have collected all n different types of coupons by comparing
the size of your set to n.

Huda Noor Dean College of Engineering Trikaripur 65 / 79


Algorithmic Solution:

3. Repeat for Accuracy:


- To get a reliable estimate, repeat the entire buying process many times
(e.g., 100,000 times).
- Keep a running total of the number of jeans bought across all these
repetitions.

Huda Noor Dean College of Engineering Trikaripur 66 / 79


Algorithmic Solution:

4. Calculate the Average:


- After completing all repetitions, calculate the average number of jeans
bought by dividing the total number of jeans bought by the number of
repetitions.
5. Output the Result:
-The average number of jeans bought from the repeated simulations gives
you a good estimate of how many pairs of jeans you would typically need to
buy before collecting all n coupons and getting a free pair.

Huda Noor Dean College of Engineering Trikaripur 67 / 79


Walk through an example
1. Setup and Initialization Step:
- Imagine there are 10 different types of coupons.
- Start with totaljeans = 0 and an empty set couponscollected.
2. Buying Jeans:
- You buy a pair of jeans and get a coupon. Add the coupon to your set.
- Increase totaljeans by 1.
- Repeat the buying process, each time adding the coupon to your set and
increasing the total jeans count.
- Check if your set now contains all 10 different coupons else repeat till
complete.

Huda Noor Dean College of Engineering Trikaripur 68 / 79


Walk through an example
3. Repeat Many Times:
- Once you have all 10 types in your set, note the total number of jeans
bought for this repetition. Let it be TJ1
- To ensure accuracy, repeat this entire process (buying jeans, collecting
coupons) 1000 times.
- Sum the total number of jeans bought over all repetitions.
-
sum = TJ1 + TJ2 + TJ3 + .....TJ1000

Huda Noor Dean College of Engineering Trikaripur 69 / 79


Walk through an example
4. Calculate Average:
- Divide the sum of all jeans bought by 1000 to get the average number of
jeans you need to buy to collect all coupons.
-
Average = sum/1000
5. Output the Result:
Now Avearge would represent the average number of jeans bought from
the repeated simulations, and gives you a good estimate of how many pairs
of jeans you would typically need to buy before collecting all 10 coupons
and getting a free pair.

Huda Noor Dean College of Engineering Trikaripur 70 / 79


pseudocode
import random
def expected_jeans(n, num_simulations=100000):
total_jeans = 0
for _ in range(num_simulations):
coupons_collected = set()
jeans_bought = 0
while len(coupons_collected) < n:
jeans_bought += 1
coupon = random.randint(1, n) # simulate getting a random
coupons_collected.add(coupon) # add the coupon to the set
total_jeans += jeans_bought

Huda Noor Dean College of Engineering Trikaripur 71 / 79


pseudocode

expected_jeans = total_jeans / num_simulations


return expected_jeans

# Example usage:
n = 10 # number of different coupons
expected_num_jeans = expected_jeans(n)
print(f"Expected number of jeans before getting a free one with {n} co

Huda Noor Dean College of Engineering Trikaripur 72 / 79


Problem-2 :Hat Problem
’n’ people go to a party and drop off their hats to a hat-check person. When
the party is over, a different hat-check person is on duty and returns the n
hats randomly back to each person. What is the expected number of
people who get back their hats?

To solve this problem, we can simulate the process of randomly distributing


hats and count how many people get their own hats back. By running the
simulation many times, we can calculate the expected number of people
who receive their own hats.

Huda Noor Dean College of Engineering Trikaripur 73 / 79


Algorithmic Solution:
1. Initialization:
- Set up variables to count the total number of correct matches across all
simulations.
- Define the number of simulations to ensure statistical reliability.
- Define the number of people n.
2. Simulate the Process:
- For each simulation:

▶ Create a list of hats representing each person.


▶ Shuffle the list to simulate random distribution.
▶ Count how many people receive their own hat.
▶ Add this count to the total number of correct matches.
Huda Noor Dean College of Engineering Trikaripur 74 / 79
Algorithmic Solution:

3. Calculate the Expected Value:


- Divide the total number of correct matches by the number of simulations
to get the average.

4. Output the Result:


- Print the expected number of people who get their own hats back.

Huda Noor Dean College of Engineering Trikaripur 75 / 79


walk through an example

1. Setup and Initialization Step:


- Suppose there are 5 people at the party.
- Initialize total _ correct to 0,
which will keep track of the total number of people who receive their own
hat across multiple simulations and num_simulations to 100,000.

Huda Noor Dean College of Engineering Trikaripur 76 / 79


walk through an example
2. Simulate the Process:
• For each simulation:
– Create a list of hats [1, 2, 3, 4, 5].
– Shuffle the list, e.g., [3, 1, 5, 2, 4].
– Initialize correct to 0.
– Check each person:
Person 1 (hat 3) - not correct.
Person 2 (hat 1) - not correct.
Person 3 (hat 5) - not correct.
Person 4 (hat 2) - not correct.
Person 5 (hat 4) - not correct.
– Add correct (which is 0 for this run) to total_correct.
Huda Noor Dean College of Engineering Trikaripur 77 / 79
walk through an example
3. Repeat Many Times:
- Repeat the simulation 100,000 times, each time shuffling the hats and
counting how many people get their own hats back.
-Sum the number of correct matches across all simulations.

4. Calculate Average:
- Divide total_correct by 100,000 to get the average number of people who
receive their own hat.

Huda Noor Dean College of Engineering Trikaripur 78 / 79


pseudocode
import random
def simulate_hat_problem(n, num_simulations):
total_correct = 0
for _ in range(num_simulations):
hats = list(range(n))
random.shuffle(hats)
correct = sum(1 for i in range(n) if hats[i] == i)
total_correct += correct
expected_value = total_correct / num_simulations
return expected_value
# Example usage
n = 10 # Number of people at the party
num_simulations
Huda Noor Dean = 100000 #College
Number ofTrikaripur
of Engineering simulations to run 79 / 79

You might also like