问题
Distinguishable objects into distinguishable boxes
It is very similar to this question posted. I'm trying to get python code for this question. Note although it is similar there is a key difference. i.e. A bucket can be empty, while the other buckets contain all the items. Even this case will be considered as a separate case.
for example:
Consider I have 3 items A,B,C and 3 buckets B1, B2, B3
The table below will show the expected result:
B1 B2 B3 (A,B,C) () () () (A,B,C) () () () (A,B,C) (A) (B) (C) (A) (C) (B) (B) (A) (C) (B) (C) (A) (C) (B) (A) (C) (A) (B) (A,B) (C) () (A,B) () (C) (B,C) (A) () (B,C) () (A) (A,C) (B) () (A,C) () (B) () (A,B) (C) (C) (A,B) () () (B,C) (A) (A) (B,C) () () (A,C) (B) (B) (A,C) () () (C) (A,B) (C) () (A,B) () (A) (B,C) (A) () (B,C) () (B) (A,C) (B) () (A,C) Length is 27.
>>def make_sets(items, num_of_baskets=3):
pass
>>make_sets(('A', 'B', 'C', 'D', 'E'), 3)
I'm expecting the output of a function to give me these combinations in a form of list of lists of tuples. I'm saying this again the number of items is variable and the number of buckets is variable too.
** Please provide python code for the make_sets function.
If someone can explain the math combinatorics. I'd greatly appreciate that too. I spent more than 2 days on this problem without reaching a definite solution.
回答1:
Think about bringing in the items one by one, and each of them having to select a box to land on.
Start with the first item, it has n
possible choices. Now the second item comes in, it also has n
possible box choices. Since items and boxes are all distinguishable, we do not need to worry about discounting permutations (as one usually needs to do for indistinguishable items). The total number of different possibilities up to this point is n x n
.
Bring in the third item, it also has n
choices, and so the total number of possibilities is now n x n x n
.
You may have noticed by now that the answer is n^k
when you have k
items.
In the example mentioned, n=3
and k=3
, so we have 3^3 = 27
possible ways of placing the items.
The code to get a list with all of the actual combinations is shown below:
import itertools
def make_sets(items, num_of_boxes=3):
allpossible = []
for tup in itertools.product(range(num_of_boxes), repeat=len(items)):
boxes = [list() for _ in range(num_of_boxes)]
for item, box in zip(items, tup):
boxes[box].append(item)
allpossible.append(boxes)
return allpossible
for p in make_sets(('A', 'B', 'C')):
for box in p:
print str(box).ljust(20),
print
Running the above prints out:
['A', 'B', 'C'] [] []
['A', 'B'] ['C'] []
['A', 'B'] [] ['C']
['A', 'C'] ['B'] []
['A'] ['B', 'C'] []
['A'] ['B'] ['C']
['A', 'C'] [] ['B']
['A'] ['C'] ['B']
['A'] [] ['B', 'C']
['B', 'C'] ['A'] []
['B'] ['A', 'C'] []
['B'] ['A'] ['C']
['C'] ['A', 'B'] []
[] ['A', 'B', 'C'] []
[] ['A', 'B'] ['C']
['C'] ['A'] ['B']
[] ['A', 'C'] ['B']
[] ['A'] ['B', 'C']
['B', 'C'] [] ['A']
['B'] ['C'] ['A']
['B'] [] ['A', 'C']
['C'] ['B'] ['A']
[] ['B', 'C'] ['A']
[] ['B'] ['A', 'C']
['C'] [] ['A', 'B']
[] ['C'] ['A', 'B']
[] [] ['A', 'B', 'C']
回答2:
Notice that this corresponds to base-n numbers (I hope you can beautify the output). This solution is independent of n and k:
n = 3
k = 4
a = [0] * k
def to_base_n(x):
num = 0
while x is not 0:
num *= 10
num += x % n
x //= n
return num
for i in range(0, n ** k):
s = ('%0' + str(k) + 'd') % (to_base_n(i))
x = [list() for _ in range(n)]
for i in range(k):
x[int(s[i])].append(str(i))
print(x)
来源:https://stackoverflow.com/questions/38217594/no-of-ways-of-placing-k-distinguishable-items-into-n-distinguishable-boxes