Here is the code to a subset problem with arguments n and k. n represents the total number of students and k represents the amount of the students I want to get out of n. The code attempts to give the number of possible combinations of pulling k number of students out of n number of students.
def subset(n, k):
if k == 0:
return 1
if n == k:
return 1
else:
return subset(n-1, k-1) + subset(n-1, k)
I understand the first part of the recursive call, but I'm having trouble understanding the + subset(n-1, k) part. Can anyone explain this to me?
The recursion is based on a simple observation, for which I will give a combinatorial argument, as to why it is true, rather than a mathematical proof through formulae.
Whenever you choose k
elements out of n
, there are two cases:
#n
#n
Since these events are mutually exclusive, the total amount of combinations is given by the amount of combinations when choosing #n
, and those when you don't choose #n
.
#n
Since we have already chosen one element, we need only choose another k-1
elements. Also, since we have decided upon one element – as to whether it is included or not – already, we only need to consider the remaining n-1
elements.
Thus, the amount of combinations for choosing element #n
is given by
subset(n - 1, k - 1)
#n
There are still k
elements to choose, but since we have already made up our mind about element #n
, there remain only n - 1
elements to choose from. Thus:
subset(n - 1, k)
The recursion uses the fact, that we can usually differentiate between two situations, solutions where element n
is part of that solution, and those where it is not.
However, such a distinction can not always be made:
n == k
in code below)k == 0
in code below)In these cases, there is only exactly one solution, hence
if k == 0:
return 1
if n == k:
return 1
To do that, we need to convince ourselves (or prove) that the base case is always hit at some point.
Let us assume, that n < k
at some point. Since per our assumption, n
was originally greater or equal to k
, there must have been some point where n = k
, because n
and k
decrease in unison or only n
decreases by one, i.e. it follows
This implies, that there must have been a call to subset(n - 1, k)
for it to happen, that n
decreases below k
. However, this is not possible since we have a base case on n = k
where we return a constant 1
.
We conclude that either n
decreases at some point such that n = k
, or decrease in unison exactly k
times such that k = 0
.
Thus, the base case works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With