行和列中唯一条目的组合

时间:2015-09-22 20:51:18

标签: python python-3.x unique combinations

使用Python 3,我需要返回矩阵项的可能组合列表,其中组合中没有项与组合中的任何其他矩阵项共享行或列。

例如,     [A,B,C],      [d,E,F],      [G,H,I]]

返回:
A,E,I
A,F,H
B,d,我
B,F,G
C,E,G
C,D,H

我似乎无法找到一种有效的方法。

我希望这可以在没有说出来的情况下实现,生成所有组合,然后测试每个组合中的项目是否满足唯一的行和列规则。

如果有人有任何指示,那就太棒了。

2 个答案:

答案 0 :(得分:2)

我会用递归程序攻击它。

If only one element in matrix, return it.
Else
  for each element in first row
    choose the element (call it E)
    call self with that row & column deleted from matrix (list comprehension)
    for each sequence in returned list:
      prepend E to the sequence.

return the list of sequences

Python实现:

def traverse(mat):
    # Identify matrix traversals: one element from each row & col.
    # Input:
    #   mat -- square matrix (list of lists)
    # Return:
    #   list of all element combinations that satisfy the requirement

    if len(mat) <= 1:
        return mat

    result = []
    for elim, head in enumerate(mat[0]):
        submat = [row[:elim] + row[elim+1:] for row in mat[1:]]
        print(submat)
        subcombo = traverse(submat)
        for row in subcombo:
            result.append([head] + row)

        print(result)

    return result


mat = [['A', 'B', 'C'],  ['D', 'E', 'F'],  ['G', 'H', 'I']]
print(traverse(mat))

输出:

[['A', 'E', 'I'], ['A', 'F', 'H'], ['B', 'D', 'I'], ['B', 'F', 'G'], ['C', 'D', 'H'], ['C', 'E', 'G']]

使用内联操作和列表推导可以大大减少这种情况,但我希望让解决方案更适用于其他语言。

答案 1 :(得分:1)

def combMatrix(m):

        # index each letter with row and colum
        ll = [[ (y, x.index(y),l.index(x)) for y in x] for x in m]

        # flatten list
        flattened = [val for sublist in ll  for val in sublist]

        # no need for deepcopy, it just me first time using it
        from copy import deepcopy
        lst2 = deepcopy(flattened)

        lall = []
        temp = []
        srowt = set()
        scolt = set()
        pospath = []

        # loop from one copy of the list over the other indexed list of tuples
        for el in lst2:

            row = el[1]
            col = el[2]
            for t in flattened:
                rowt = t[1]
                colt = t[2]

                # if row index and column index are different
                if row != rowt and col != colt:
                    # and if for this tuple row index and column index is not in the visisited
                    # append that tuple, it is a good candidate
                    if rowt not in srowt and  colt not in scolt:
                        temp.append(t[0])
                        srowt.add(rowt)
                        scolt.add(colt)
                    else:
                        # here we append onother candidate to a list of possible path
                        pospath.append(t[0])


            temp.append(el[0])
            temp = sorted(temp)
            pospath.append(el[0])
            pospath = sorted(pospath)

            if temp not in lall:
                lall.append(temp)
            if pospath not in lall:
                lall.append(pospath)

            temp = []
            srowt = set()
            scolt = set()
            pospath = []



        for c, el in enumerate(lall):
            print(" {} {}".format(c, el))


l = [['A','B','C'],
     ['D','E','F'],
     ['G','H','I']]

combMatrix(l)

<强>输出

0 [&#39; A&#39;,&#39; E&#39;,&#39;我&#39;]

1 [&#39; A&#39;,&#39; F&#39;,&#39; H&#39;]

2 [&#39; B&#39;,&#39; D&#39;,&#39;我&#39;]

3 [&#39; B&#39;,&#39; F&#39;&#39; G&#39;]

4 [&#39; C&#39;,&#39; D&#39;,&#39; H&#39;]

5 [&#39; C&#39;,&#39; E&#39;&#39; G&#39;]