我有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]
它由一些子排列组成(每行都有一组属于其索引集的数字)
我的问题是,再次进入第一个排列所需的最小移动次数是多少。
作为prolog中的练习题,我想计算每个子置换的移动次数并得到它们的lcm,但我不知道如何实现这个(如何计算每个子移动的移动次数)排列)
任何帮助将不胜感激
答案 0 :(得分:1)
排列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(最不常见的多个)级联,直到所有循环都在同一个循环中运行这是第一次。