Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python:查找集合的所有拉丁方(或列数较少的部分方)_Python_Algorithm_Permutation_Combinatorics - Fatal编程技术网

python:查找集合的所有拉丁方(或列数较少的部分方)

python:查找集合的所有拉丁方(或列数较少的部分方),python,algorithm,permutation,combinatorics,Python,Algorithm,Permutation,Combinatorics,编辑: 多亏了评论员道格拉斯·扎尔,我用更合适的术语重新命名了这篇文章的标题,以供其他可能正在寻找类似内容的人使用。下面来自David Eisenstat的代码非常有用 原始帖子: 我很抱歉没有合适的集合论术语。。。但我在这里有点不知所措(尽管我怀疑这是一个容易的问题)。我正在尝试开发一种算法,该算法将接受一个集合和一个数字K,并返回所有可能的具有K大小子集且集合覆盖率=K的“完整”分区,这样: 任何给定子集都不会有重复项 在所有子集上组合第n个项将给出集合的完整分区 所有子集的第n项在其余子

编辑:
多亏了评论员道格拉斯·扎尔,我用更合适的术语重新命名了这篇文章的标题,以供其他可能正在寻找类似内容的人使用。下面来自David Eisenstat的代码非常有用


原始帖子:
我很抱歉没有合适的集合论术语。。。但我在这里有点不知所措(尽管我怀疑这是一个容易的问题)。我正在尝试开发一种算法,该算法将接受一个集合和一个数字K,并返回所有可能的具有K大小子集且集合覆盖率=K的“完整”分区,这样:

  • 任何给定子集都不会有重复项

  • 在所有子集上组合第n个项将给出集合的完整分区
  • 所有子集的第n项在其余子集中是唯一的
  • 例如:

    function({A, B, C, D}, 2)
    
    应该像这样返回所有可能的集合:

    [AB, BC, CD, DA]
    [AB, BD, CA, DC]
    [AC, BD, CA, DB]
    [AD, DA, CB, BC]
    [BC, CA, DB, AD]
    ...
    
    还有,为了它的价值

  • 单个子集中元素的顺序无关紧要(只要遵守其他三条规则即可)
  • 因此,以下是等效的:

    [AB, BA, CD, DC] = [BA, AB, DC, CD] = [AB, BA, DC, CD] = [BA, AB, CD, DC]
    

  • 不同子集的顺序很重要:
  • 因此,以下是不同的:

    [BC, CA, DB, AD] ≠ [CA, BC, AD, DB]
    
    换句话说,在矩阵术语中:我要查找所有具有
    rows=len(set)
    columns=K
    的矩阵,这样每一列都有确切的覆盖范围,并且任何一行中没有项目出现一次以上

    function({A, B, C, D}, 3)
    
    将返回所有矩阵,如下所示

    ABC      ADB    
    BCD      DCA    
    CDA      CBD    
    DAB      BAC 
    

    我希望能在python中找到答案,使用numpy之类的库也不错……但也希望能有一个通用的算法策略。我认为类似的东西可能会派上用场……但我无法从这一点跨越到这里概述的问题……

    回溯搜索是可行的。python 3:

    import itertools
    import operator
    
    
    def valid(cols_so_far):
        for i, col1 in enumerate(cols_so_far):
            for col2 in cols_so_far[i + 1:]:
                if any(map(operator.eq, col1, col2)):
                    return False
        return True
    
    
    def enum(letters, k, cols_so_far=None):
        if cols_so_far is None:
            cols_so_far = (tuple(letters),)
        if not valid(cols_so_far):
            pass
        elif len(cols_so_far) == k:
            yield tuple(zip(*cols_so_far))  # transpose
        else:
            for perm in itertools.permutations(letters):
                yield from enum(letters, k, cols_so_far + (perm,))
    

    将所有子集中的第n个项组合起来,就可以对“和”进行完整的划分,单个子集中元素的顺序无关紧要(只要遵守其他三条规则)相互矛盾。如果子集元素的顺序无关紧要,那么谈论子集的第n项意味着什么?对不起……也许我的措辞很奇怪。任何给定子集中元素的顺序只与其他子集相关。因此
    [AB,BA,CD,DC]=[BA,AB,DC,CD]
    (因为每个列表的第n个元素有相同的两个项目)但是
    [AB,BA,CD,DC]≠ [DC、AB、BA、CD]
    (即使相同的四个组合出现,只是顺序不同)……这有意义吗?也许最后的矩阵示例可以最好地解释一下……“设置”、“设置分区”和“分区”已经有了意义。你应该试着说出你的意思,不要以不寻常的方式使用这些术语。你有一个二维数组,或者一个矩阵,它对行和列有一些条件。我想你有的是部分拉丁方的一些行数。谢谢道格拉斯!我知道我没有完全使用适当的术语a我说。拉丁方这个词正是我想要的……如果我能创建一组中所有可能的拉丁方,我想我可以根据我在这里列出的需要将它们裁剪成部分拉丁方。(值得一提的是,我永远不会有一组大于8项的东西……通常小于6项)我将开始沿着这些路线搜索。如果有人有算法可以建议,请随意…谢谢你,大卫!这太棒了。今晚我需要一些时间来深入研究这一点,但我真的很欣赏作为起点的代码。