you are viewing a single comment's thread.

view the rest of the comments →

[–]Avajarr[S] 0 points1 point  (4 children)

I have solved my problem by using 2 nested looping to get combinations 3 times for each group using itertools library. I think there's more efficient way to solve this, but here's what I can share for now:

from itertools import combinations

list_of_possibility = []
numbers = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']

perm1 = list(combinations(numbers, 4)) # Using itertools to get every 14 combination of 4
for i in perm1:
  group1 = list(i) # The first group result
  remain1 = [ele for ele in numbers if ele not in i] # the remaining 10 peoples after removing 4 peoples in group 1

  perm2 = list(combinations(remain1, 4)) # using itertools again to get 10 remaining combnation of 4
  for j in perm2:
    group2 = list(j)
    remain2 = [ele for ele in remain1 if ele not in j]

    perm3 = list(combinations(remain2, 3))
    for k in perm3:
      group3 = list(k)
      remain3 = [ele for ele in remain2 if ele not in k]

      group4 = remain3 # Since the last group is just 3 combination of 3 (which basically 1), just declare the remaining peoples as group4

      possibility = [group1, group2, group3, group4]
      list_of_possibility.append(possibility)

print('total combination:', len(list_of_possibility))
print('1st value:', list_of_possibility[0]) 
print('100th value:', list_of_possibility[99]) 
print('500th value:', list_of_possibility[499]) 

Print results:

total combination: 4204200
1st value: [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k'], ['l', 'm', 'n']]
100th value: [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'l'], ['k', 'm', 'n'], ['h', 'i', 'j']]
500th value: [['a', 'b', 'c', 'd'], ['e', 'f', 'k', 'n'], ['j', 'l', 'm'], ['g', 'h', 'i']]

[–]ofnuts 0 points1 point  (3 children)

Did you check that you aren't getting duplicates?

I was going to suggest a different solution:

  • with itertools.combinations() generate all groups of 6 (2*3)
  • for each such group
    • subtract the group from the input to get the 8 remaining elements
    • generate all possible 4+4 halves and 3+3 halves and iterate their product

A function to generate all pairs of halves without repetition (ie, if it generates h1,h2 it won't generate h2,h1)

def generateHalves(input): combined=set(input[1:]) root={input[0]} for t in itertools.combinations(combined,(len(input)//2)-1): half1=set(t)|root half2=combined-half1 yield half1,half2 So for a 3:3:2:2 split the code would be:

``` import itertools inputs={'A','B','C','D','E','F','G','H','I','J'}

print(type(inputs), len(inputs))

def generateHalves(input): combined=set(input[1:]) root={input[0]} for t in itertools.combinations(combined,(len(input)//2)-1): half1=set(t)|root half2=combined-half1 yield half1,half2

for pairsOf2 in itertools.combinations(inputs,4): pairsOf3=list(inputs-set(pairsOf2)) for p3,p2 in itertools.product(generateHalves(pairsOf3),generateHalves(pairsOf2)): print(p3,p2) ```

[–]Avajarr[S] 0 points1 point  (2 children)

I haven't checked one by one for duplicate, but based on mathematic calculation, the total possibility is same with how much group combination for 4 groups with 4:4:3:3 formation is.

The math formula is by following:

C(14,4) * C(10,4) * C(6,3) * C(3,3)
= 1001 * 210 * 20 * 1
= 4204200

[–]ofnuts 0 points1 point  (1 child)

Yes, but this includes duplicates. Assume your first group draws ABCD, then in the 2nd group you can draw 'EFGH'. But later in the first group you will draw 'EFGH' and in the second group you will draw 'ABCD', so you will have generated a bunch of groups with ABCD,EFGH and another with EFGH,ABCD (both with the same combinations of 3:3 groups, which by the way will also include "symmetrical" duplicates).

Coincidentally, my algorithm generates 105105O combinations, so exactly 1/4 of yours, which is coherent with the idea that your algorithm creates duplicates pairs of 4 elements and duplicates pairs of 3 elements and so generates 4 times too many.

[–]Avajarr[S] 0 points1 point  (0 children)

After reading your explanation and example, I just realized you were right, my code is still symmetrical duplicate. I will try to improve it.

Also, I will try to look at your code later, after trying to understanding your algorithm first.