Algorithm to determine possible groups of items

后端 未结 6 1733
遥遥无期
遥遥无期 2021-02-03 11:51

I am scratching my head trying to do this and it\'s eating me up. I know it is not THAT complex. I have a number of items, this number can be equal or greater than three. Then I

6条回答
  •  鱼传尺愫
    2021-02-03 12:35

    this would be the number of partitions of n which contain only integers from the set [3,7]

    similar to the regular partition problem (where the elements can be any positive integer):

    http://www.research.att.com/~njas/sequences/A000041

    i don't see an existing number sequence that matches this constraint exactly, but you can count the groups like so (in python). this can take an arbitrary range ([3,7] in this case) and count all the a,b,c,d,e (3*a + 4*b + 5*c + 6*d + 7*e) sequences that sum to n.

    import sys
    
    # All partitions for a particular n:
    
    def groups(n, base, minBase, sum, sets, group = []):
      c = 0; i = (n - sum) / base
      while i >= 0:
        s = sum + base * i
        if s == n:
          sets.append(group + [i]);
          c = c + 1
        elif s < n and base > minBase:
          c = c + groups(n, base - 1, minBase, s, sets, (group + [i]))
        i = i - 1
      return c
    
    # Partitions for each n in [1,maxNum]
    
    def run(maxNum):
      for i in xrange(1, maxNum + 1):
        sets = []; maxBase = 7; minBase = 3
        n = groups(i, maxBase, minBase, 0, sets)
        print '    %d has %d groups:\n' % (i, n)
        for g in sets:
          x = len(g) - 1
          sys.stdout.write('      ')
          while x >= 0:
            if g[x] > 0:
              if x < len(g) - 1: sys.stdout.write(' + ')
              sys.stdout.write('(%d * %d)' % (maxBase - x, g[x]))
            x = x - 1
          print ''
        if len(sets): print ''
    
    run(40)
    

    you'd have:

    1 has 0 groups:
    
    2 has 0 groups:
    
    3 has 1 groups:
    
      (3 * 1)
    
    4 has 1 groups:
    
      (4 * 1)
    
    5 has 1 groups:
    
      (5 * 1)
    
    6 has 2 groups:
    
      (6 * 1)
      (3 * 2)
    
    7 has 2 groups:
    
      (7 * 1)
      (3 * 1) + (4 * 1)
    
    8 has 2 groups:
    
      (3 * 1) + (5 * 1)
      (4 * 2)
    
    9 has 3 groups:
    
      (3 * 1) + (6 * 1)
      (4 * 1) + (5 * 1)
      (3 * 3)
    
    10 has 4 groups:
    
      (3 * 1) + (7 * 1)
      (4 * 1) + (6 * 1)
      (5 * 2)
      (3 * 2) + (4 * 1)
    
    11 has 4 groups:
    
      (4 * 1) + (7 * 1)
      (5 * 1) + (6 * 1)
      (3 * 2) + (5 * 1)
      (3 * 1) + (4 * 2)
    
    12 has 6 groups:
    
      (5 * 1) + (7 * 1)
      (6 * 2)
      (3 * 2) + (6 * 1)
      (3 * 1) + (4 * 1) + (5 * 1)
      (4 * 3)
      (3 * 4)
    
    13 has 6 groups:
    
      (6 * 1) + (7 * 1)
      (3 * 2) + (7 * 1)
      (3 * 1) + (4 * 1) + (6 * 1)
      (3 * 1) + (5 * 2)
      (4 * 2) + (5 * 1)
      (3 * 3) + (4 * 1)
    
    14 has 7 groups:
    
      (7 * 2)
      (3 * 1) + (4 * 1) + (7 * 1)
      (3 * 1) + (5 * 1) + (6 * 1)
      (4 * 2) + (6 * 1)
      (4 * 1) + (5 * 2)
      (3 * 3) + (5 * 1)
      (3 * 2) + (4 * 2)
    
    15 has 9 groups:
    
      (3 * 1) + (5 * 1) + (7 * 1)
      (4 * 2) + (7 * 1)
      (3 * 1) + (6 * 2)
      (4 * 1) + (5 * 1) + (6 * 1)
      (3 * 3) + (6 * 1)
      (5 * 3)
      (3 * 2) + (4 * 1) + (5 * 1)
      (3 * 1) + (4 * 3)
      (3 * 5)
    

    or @Cletus's excellent solution

提交回复
热议问题