我正在努力生成圆形排列,或者使用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]的顺序相同。
苦苦挣扎,希望能为解决该问题提供帮助!
答案 0 :(得分:0)
当您有N个元素的列表时,列表的一个循环排列由其第一个元素唯一地给出。 Than表示您将拥有正好N个循环排列(包括原始列表),并且可以通过删除fist元素并将其添加到列表的末尾来从一个传递到另一个。
您可以轻松地为列表的所有圆形排列构建生成器:
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
演示:
>>> list(circ_perm([1,2,3,4]))
[[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]
如果当两个排列是另一个排列的ciruclar排列时,如果您想要的是唯一排列,您仍然可以使用以下事实:循环排列由第一个元素给出,并修复第一个元素并找到所有排列剩下的东西:
def uniq_perm(lst):
gen = itertools.permutations(lst[1:])
for end in gen:
yield [lst[0]] + list(end)
演示:
>>> 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]]
答案 1 :(得分:0)
进行排列的复杂度约为O(n * n!),因此对于较大的数或列表,生成所有可能的排列的效率很低,您可以使用回溯来生成列表排列,我将分享一个链接这会有所帮助。 The solution is based on the backtracking
sum
答案 2 :(得分:0)
以下代码生成最后n-1
个数字的所有排列,并在每个排列之前加上原始列表的第一个元素。
from itertools import permutations
circular_perms = [my_list[:1]+list(perm) for perm in permutations(my_list[1:])]
my_list
是要生成其所有循环排列的初始值列表。
答案 3 :(得分:0)
由于Python中的itertool.permutations生成器使输入列表中的第一项在连续输出中变化最小,因此以下代码仅输出旋转到上方固定点时看到的所有解。
from itertools import permutations, islice
from math import factorial
items = [1, 2, 3 ,4]
ilength = len(items)
base_necklace_orders = list(islice(permutations(items), factorial(ilength) // ilength))
print(base_necklace_orders)
# [(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2)]
答案 4 :(得分:0)