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
kelements out ofn, there are two cases:#n#nSince 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.Choosing element
#nSince we have already chosen one element, we need only choose another
k-1elements. Also, since we have decided upon one element – as to whether it is included or not – already, we only need to consider the remainingn-1elements.Thus, the amount of combinations for choosing element
#nis given byNot choosing element
#nThere are still
kelements to choose, but since we have already made up our mind about element#n, there remain onlyn - 1elements to choose from. Thus:The base case
The recursion uses the fact, that we can usually differentiate between two situations, solutions where element
nis part of that solution, and those where it is not.However, such a distinction can not always be made:
n == kin code below)k == 0in code below)In these cases, there is only exactly one solution, hence
Ensuring it works
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 < kat some point. Since per our assumption,nwas originally greater or equal tok, there must have been some point wheren = k, becausenandkdecrease in unison or onlyndecreases by one, i.e. it followsThis implies, that there must have been a call to
subset(n - 1, k)for it to happen, thatndecreases belowk. However, this is not possible since we have a base case onn = kwhere we return a constant1.We conclude that either
ndecreases at some point such thatn = k, or decrease in unison exactlyktimes such thatk = 0.Thus, the base case works.