Search code examples
pythonarraysnumpysortinggroup-by

Python program to divide one group to sub-groups with exceptions


I want to write a python code to divide a group consist of several rows to sub-groups depending on specific criteria to the effect that every row can join a group contain certain rows, but not permitted to join groups contain other rows. for example:

Group_A =[
[[2, 3, 5, 6, 8], [1, 4, 7, 9], 0],
[[3, 4, 7, 8, 9], [0, 2, 5, 6], 1],
[[0, 3, 7, 8, 9], [1, 4, 5, 6], 2],
[[0, 1, 4, 7, 9], [2, 5, 6, 8], 3],
[[1, 5, 6, 8, 9], [0, 2, 3, 7], 4],
[[0, 2, 4, 7, 9], [1, 3, 6, 8], 5],
[[0, 4, 7, 8, 9], [1, 2, 3, 5], 6],
[[2, 3, 5, 6, 8], [0, 1, 4, 9], 7],
[[0, 2, 4, 7, 9], [1, 3, 5, 6], 8],
[[2, 3, 4, 6, 8], [0, 1, 5, 7], 9]] 

Output:

Group_1 = [
[[2, 3, 5, 6, 8], [1, 4, 7, 9], 0]
[[1, 5, 6, 8, 9], [0, 2, 3, 7], 4]
[[2, 3, 5, 6, 8], [0, 1, 4, 9], 7]]

Group_2 = [
[[3, 4, 7, 8, 9], [0, 2, 5, 6], 1]
[[0, 3, 7, 8, 9], [1, 4, 5, 6], 2]
[[0, 4, 7, 8, 9], [1, 2, 3, 5], 6]]

Group_3 = [
[[0, 1, 4, 7, 9], [2, 5, 6, 8], 3]
[[0, 2, 4, 7, 9], [1, 3, 6, 8], 5]
[[0, 2, 4, 7, 9], [1, 3, 5, 6], 8]]

Group_4 = [[[2, 3, 4, 6, 8], [0, 1, 5, 7], 9]]

For more illustration: For the first row [[2, 3, 5, 6, 8], [1, 4, 7, 9], 0], 0 is the number of the row, [2, 3, 5, 6, 8] the group contains rows 2,3,5,6 and 8 that row number 0 not permitted to join, but can join a group contain most of these rows[1, 4, 7, 9].

Another example as follows:

Group_B = [
[[1, 3, 6, 7, 9], [2, 4, 5, 8], 0]
[[0, 2, 4, 5, 8], [3, 6, 7, 9], 1]
[[0, 1, 4, 7, 8], [3, 5, 6, 9], 2]
[[0, 1, 4, 5, 8], [2, 6, 7, 9], 3]
[[2, 3, 7, 8, 9], [0, 1, 5, 6], 4]
[[1, 3, 6, 7, 9], [0, 2, 4, 8], 5]
[[0, 1, 5, 7, 8], [2, 3, 4, 9], 6]
[[0, 4, 5, 6, 8], [1, 2, 3, 9], 7]
[[1, 4, 6, 7, 9], [0, 2, 3, 5], 8]
[[0, 4, 5, 7, 8], [1, 2, 3, 6], 9]]

Output:

Group_1 = [
[[0, 1, 4, 7, 8], [3, 5, 6, 9], 2]
[[0, 1, 4, 5, 8], [2, 6, 7, 9], 3]
[[0, 1, 5, 7, 8], [2, 3, 4, 9], 6]
[[0, 4, 5, 7, 8], [1, 2, 3, 6], 9]]

Group_2 = [
[[1, 3, 6, 7, 9], [2, 4, 5, 8], 0]
[[1, 3, 6, 7, 9], [0, 2, 4, 8], 5]
[[1, 4, 6, 7, 9], [0, 2, 3, 5], 8]]

Group_3 = [
[[0, 2, 4, 5, 8], [3, 6, 7, 9], 1]
[[0, 4, 5, 6, 8], [1, 2, 3, 9], 7]]

Group_4 = [[[2, 3, 7, 8, 9], [0, 1, 5, 6], 4]]

Regards,


Solution

  • My approach uses itertools to iterate over possible combinations

    import itertools
    
    Group_A =[
    [[2, 3, 5, 6, 8], [1, 4, 7, 9], 0],
    [[3, 4, 7, 8, 9], [0, 2, 5, 6], 1],
    [[0, 3, 7, 8, 9], [1, 4, 5, 6], 2],
    [[0, 1, 4, 7, 9], [2, 5, 6, 8], 3],
    [[1, 5, 6, 8, 9], [0, 2, 3, 7], 4],
    [[0, 2, 4, 7, 9], [1, 3, 6, 8], 5],
    [[0, 4, 7, 8, 9], [1, 2, 3, 5], 6],
    [[2, 3, 5, 6, 8], [0, 1, 4, 9], 7],
    [[0, 2, 4, 7, 9], [1, 3, 5, 6], 8],
    [[2, 3, 4, 6, 8], [0, 1, 5, 7], 9]]
    
    
    Group_B = [
    [[1, 3, 6, 7, 9], [2, 4, 5, 8], 0],
    [[0, 2, 4, 5, 8], [3, 6, 7, 9], 1],
    [[0, 1, 4, 7, 8], [3, 5, 6, 9], 2],
    [[0, 1, 4, 5, 8], [2, 6, 7, 9], 3],
    [[2, 3, 7, 8, 9], [0, 1, 5, 6], 4],
    [[1, 3, 6, 7, 9], [0, 2, 4, 8], 5],
    [[0, 1, 5, 7, 8], [2, 3, 4, 9], 6],
    [[0, 4, 5, 6, 8], [1, 2, 3, 9], 7],
    [[1, 4, 6, 7, 9], [0, 2, 3, 5], 8],
    [[0, 4, 5, 7, 8], [1, 2, 3, 6], 9]]
    
    
    def getGroups(groups):
        used = []
        c = 3
        group_c = 0
        print()
        while len(used) < 10:
            for x in range(0,10):
                for combo in itertools.combinations(groups[x][1], c):
                    result = []
                    for group in groups:
                            if group[2] not in used and group[2] in combo and x not in group[0]:
                                if (all(elem not in group[0] for elem in combo)):
                                    result.append(group)
                    
                    if len(result) == c:
                        group_c += 1
                        print("GROUP", group_c)
                        
                        if x not in used:
                            print(groups[x])
                        for treffer in result:
                            print(treffer)
                            used.append(treffer[2])
                        used.append(x)
            c = c-1
    
    getGroups(Group_A)
    
    getGroups(Group_B)
    

    The output looks as hopefully expected:

    GROUP 1
    [[2, 3, 5, 6, 8], [1, 4, 7, 9], 0]
    [[1, 5, 6, 8, 9], [0, 2, 3, 7], 4]
    [[2, 3, 5, 6, 8], [0, 1, 4, 9], 7]
    GROUP 2
    [[3, 4, 7, 8, 9], [0, 2, 5, 6], 1]
    [[0, 3, 7, 8, 9], [1, 4, 5, 6], 2]
    [[0, 4, 7, 8, 9], [1, 2, 3, 5], 6]
    GROUP 3
    [[0, 1, 4, 7, 9], [2, 5, 6, 8], 3]
    [[0, 2, 4, 7, 9], [1, 3, 6, 8], 5]
    [[0, 2, 4, 7, 9], [1, 3, 5, 6], 8]
    GROUP 4
    [[2, 3, 4, 6, 8], [0, 1, 5, 7], 9]
    
    GROUP 1
    [[0, 1, 4, 7, 8], [3, 5, 6, 9], 2]
    [[0, 1, 4, 5, 8], [2, 6, 7, 9], 3]
    [[0, 1, 5, 7, 8], [2, 3, 4, 9], 6]
    [[0, 4, 5, 7, 8], [1, 2, 3, 6], 9]
    GROUP 2
    [[1, 3, 6, 7, 9], [2, 4, 5, 8], 0]
    [[2, 3, 7, 8, 9], [0, 1, 5, 6], 4]
    [[1, 3, 6, 7, 9], [0, 2, 4, 8], 5]
    GROUP 3
    [[1, 4, 6, 7, 9], [0, 2, 3, 5], 8]
    GROUP 4
    [[0, 2, 4, 5, 8], [3, 6, 7, 9], 1]
    [[0, 4, 5, 6, 8], [1, 2, 3, 9], 7]