Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.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_Arrays_Algorithm_Circular Permutations - Fatal编程技术网

Python算法:项链生成/循环置换

Python算法:项链生成/循环置换,python,arrays,algorithm,circular-permutations,Python,Arrays,Algorithm,Circular Permutations,我正在努力生成循环排列,或者用Python解决“项链问题”。我基本上希望尽可能高效地生成列表的所有循环排列 基本上,假设我们有一个列表[1,2,3,4],我想以循环的方式生成所有唯一的排列。因此: [1,2,3,4],[1,3,2,4] 将被视为不同,而: [1,2,3,4],[4,1,2,3]被认为是相同的,因为我只寻找循环列表的唯一排列 我曾尝试使用itertools生成所有排列,但在使用更大长度的列表时效率非常低 作为另一个例子,考虑运行循环歌曲,其特征在于[1,2,3,4,5]播放重复。

我正在努力生成循环排列,或者用Python解决“项链问题”。我基本上希望尽可能高效地生成列表的所有循环排列

基本上,假设我们有一个列表[1,2,3,4],我想以循环的方式生成所有唯一的排列。因此:

[1,2,3,4],[1,3,2,4]

将被视为不同,而:

[1,2,3,4],[4,1,2,3]被认为是相同的,因为我只寻找循环列表的唯一排列

我曾尝试使用
itertools
生成所有排列,但在使用更大长度的列表时效率非常低

作为另一个例子,考虑运行循环歌曲,其特征在于[1,2,3,4,5]播放重复。我试图想出一个算法,只生成唯一的订单。显然[1,2,3,4,5]和[4,5,1,2,3]的顺序相同


正在苦苦挣扎,希望您能为解决此问题提供帮助

当您有一个N个元素的列表时,列表的一个循环排列由其第一个元素唯一给出。Than意味着您将有N个循环置换(包括原始列表),您可以通过移除第一个元素并将其添加到列表末尾,从一个元素传递到另一个元素

您可以轻松地为列表的所有循环排列构建生成器:

def circ_perm(lst):
    cpy = lst[:]                 # take a copy because a list is a mutable object
    yield cpy
    for i in range(len(lst) - 1):
        cpy = cpy[1:] + [cpy[0]]
        yield cpy
演示:


如果你想要的是唯一的排列,当两个排列是另一个的循环排列时,你仍然可以使用一个循环排列是由它的第一个元素给出的事实,并修复第一个元素,然后找到剩下的所有排列:

def uniq_perm(lst):
    gen = itertools.permutations(lst[1:])
    for end in gen:
        yield [lst[0]] + list(end)
演示:


进行排列的复杂度约为O(n*n!),因此对于大量或列表,生成所有可能的排列将是低效的,您可以使用回溯来生成列表排列,我将共享一个链接,这可能会有所帮助。


def置换(a、l、r):
如果l==r:
印刷品(a)
其他:
对于范围内的i(l,r+1):
a[l],a[i]=a[i],a[l]
排列(a,l+1,r)
a[l],a[i]=a[i],a[l]
数据=[1,2,3,4,5]
n=len(数据)
a=列表(数据)

排列(a,0,n-1)
下面的代码生成最后一个
n-1
数字的所有排列,在每个排列前加上原始列表的第一个元素

from itertools import permutations
circular_perms = [my_list[:1]+list(perm) for perm in permutations(my_list[1:])]
其中
my_list
是生成所有循环排列的初始值列表

  • 想想项链上的“固定点”
  • 安排将编号最低的胎圈1旋转到此点
  • 那么珠子的唯一顺序是所有以1开头的项目排列
  • 由于Python中的itertool.permutations生成器的输入列表中的第一项在连续输出中变化最小,因此以下代码仅输出所有解决方案,如旋转到上面的固定点时所示

    
    从itertools导入排列,islice
    从数学导入阶乘
    项目=[1,2,3,4]
    i长度=长度(项目)
    基本项链顺序=列表(islice(排列(项目),阶乘(ilength)//ilength))
    打印(基本订单)
    
    #[(1,2,3,4),(1,2,4,3),(1,3,2,4),(1,3,4,2),(1,4,2,3),(1,4,3,2)]
    有两个Python库(据我所知)将生成组合项链。它们是和。

    您可以向我们展示您使用
    itertools
    编写的代码吗?您可以分享您在itertools中尝试过的内容吗?在你的案例中,我们讨论的元素长度是多少?Itertools通常可以被视为对大多数事物已经相当有效的实现……问题是我并不希望生成所有置换,因此使用类似于
    perms=Itertools.permutations(我的列表)
    的东西是低效的。我只想在循环数组中生成唯一的排列,实际上我想在循环列表中生成唯一的排列。你的方法的输出会产生我需要排除的结果,所以我要从[1,2,3,4]的输入中寻找像[1,3,2,4]这样的输出,基本上就是“项链”问题。假设你的项链上有5颗独特的珠子,那么不管项链是否旋转,你可以拥有多少不同的珠子顺序?@joe:4!。生成以
    1
    开头的所有置换(即生成最后的
    n-1
    元素的所有置换)。其中没有两个是相互旋转的,因为它们在同一个位置都有
    1
    。我怀疑你的真正目标是不同的。谢谢,这似乎计算了所有的排列,因此生成了[1,2,3,4,5],但[5,4,3,2,1]也是如此。我只寻找围绕圆形阵列的唯一订单。因此,两个元素不应该相邻出现两次。我可以使用
    int(阶乘(ilength-1))
    而不是
    /
    除法子表达式。
    >>> list(uniq_perm([1,2,3,4]))
    [[1, 2, 3, 4], [1, 2, 4, 3], [1, 3, 2, 4], [1, 3, 4, 2], [1, 4, 2, 3], [1, 4, 3, 2]]
    
    from itertools import permutations
    circular_perms = [my_list[:1]+list(perm) for perm in permutations(my_list[1:])]