我需要枚举大小为N的所有排列,但具有特定的循环大小——长度为1(即静止点)、2和K(一个参数)的循环。我需要检查具有此类循环的所有排列——如果N足够大,每个大小可以有多个循环。
我试图在文献中寻找这样的算法,但没有成功。我将感谢任何指向此类算法的指针。
我认为这个问题解决起来既不困难也不优雅。没关系。有一种递归策略,它接受多个循环大小,循环大小,包括一个固定元素和适当数量的其他元素,并在剩余元素上递归。
轻度测试,未经优化的Python3:
import itertools
def enumerate_perms(cycle_sizes, elements):
assert isinstance(cycle_sizes, list)
assert all(isinstance(cycle_size, int) for cycle_size in cycle_sizes)
assert all(cycle_size >= 1 for cycle_size in cycle_sizes)
assert isinstance(elements, list)
assert len(elements) == sum(cycle_sizes)
if not elements:
yield {}
return
for cycle_size in set(cycle_sizes):
remaining_cycle_sizes = cycle_sizes[:]
remaining_cycle_sizes.remove(cycle_size)
for others_tuple in itertools.permutations(elements[1:], cycle_size - 1):
remaining_elements = elements[1:]
for other in others_tuple:
remaining_elements.remove(other)
others = list(others_tuple)
others.append(elements[0])
for subperm in enumerate_perms(remaining_cycle_sizes, remaining_elements):
for i in range(cycle_size):
subperm[others[i - 1]] = others[i]
yield subperm
print(list(enumerate_perms([2, 2, 1], [1, 2, 3, 4, 5])))