我有一个数字 1 到 n 的排列。在每一轮中,一个排列函数用于将当前排列映射到一个新排列。
该函数由 F(i) = p[i]
定义,它将当前排列的每个元素映射到新排列中的一个位置。由于这个函数是单射和满射的,所以可以证明我们总是再次得到第一个排列。 (其实就是排列图中的一个循环)
例如[2,3,1] -> [3,1,2] -> [1,2,3] -> [2,3,1]
所以循环长度是 3,因为第一个和最后一个排列相同,我们陷入了一个循环。
作为输入,我有一种像这样的特殊排列:
[2,1,
4,5,3,
7,8,9,10,6,
17,11,12,13,14,15,16,
18,19,20,
29,21,22,23,24,25,26,27,28,
40,30,31,32,33,34,35,36,37,38,39,
53,41,42,43,44,45,46,47,48,49,50,51,52]
它由一些子排列组成(每一行都有一组数字,这些数字属于它们的索引集)
我的问题是再次到达第一个排列所需的最少步数是多少。
作为序言中的练习题,我想计算每个子排列的移动次数并获得它们的 lcm 但我不确定如何实现这个(如何计算每个子排列的移动次数)
任何帮助将不胜感激
最佳答案
置换 p
可以看作是集合 {1,2,...,n}
到自身的双射函数。现在您似乎要求的是此排列与其自身的最小串联数 p o p o ... o p
(其中 o
是与 (f o g )(i) := f(g(i))
) s.t.你得到恒等排列 p0
和 p0(i) = i
。
您有一个可以轻松分解为循环的排列 1->2->1
, 3->4->5->3
, 6->7->8->9->10->6
, ...
每个循环都需要与其自身进行尽可能多的连接,因为它有成员才能获得身份。由于您有长度为 2、3、5、7、3、9、11、13 的循环,因此需要 2*9*5*7*11*13(最小公倍数)串联,直到所有循环同时运行第一次。
关于algorithm - 计算一个循环中的排列数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50552304/