置换 置换群 应用
置换的概念是什么?一个有限集合的一一变换叫做置换,一对对置换组成了置换群。对于一个集合a(a[1],a[2],a[3]…a[n]) 通过置换可以变成 (b[a[1]],b[a[2]],b[a[3]]…b[a[n]]) b的作用就是置换(可以理解为某种函数的作用),将原来的集合映射成具有相应次序的集合a’,a’可以看做是a的相同元素集合,不同的排列组合的一个集合。 每个n元的置换都可以表示成若干个互不相交的循环置换的乘积,设每个子循环置换的循环节为ci,则总的置换的循环节显然为lcm(c1,c2..cn)。其实看了这么多概念,我自己也还是云里雾里的,我们需要几个数学模型来加深对其理解和认识。
模型1:给定n头牛,初始站位无序,给定每头牛的权重w[i],最终要将n头牛从小到大有序排好,交换两头牛的代价为两头牛的权重之和,问如何安排交换,使得代价最小?我们可以理解为从一个初始集(a1,a2,…an)置换到(b1,b2..bn)的最小代价。好吧,问题的过程理解清楚了,现在我们要开始分析了,从一个贪心的角度,我们肯定希望权重最大的那个牛参与的次数尽量的少,依次类推,交换这一行为映射了置换,最终我们会获得若干个循环,从而得到一个置换群。对于群内的每个环,有一个很贪心的办法就是每次都让权值最小的那个元素去和其他的元素交换,这样交换的代价为sum-min+(len-1)*min,其中sum为环内所有元素的权重之和,min为环内最小的元素,len为这个环的循环节,经过len-1次交换,我们让这个环变的有序了,不过这里还有一个策略,引进外援,就是从全局中找一个最小的small,将其引入到这个环中,参与置换,举例(1) (8 6 9 7) 我们可以先把1和6交换,让1去参与环的置换,结束后再将6交换进来,如此的代价为sum+min+(len+1)*small 取这两种策略里代价小的那种即可。对于这个问题我们通过第二属性偏序关系和目标关系,等价成将某个(1,2,3…n)的某个排列组合,通过交换变成(1,2,3…n) (http://poj.org/problem?id=3270)
模型2:有n张牌,一台洗牌机,洗牌机的功能如下:如果i位置的牌为j,j位置的牌为k,那么洗牌机将i位置的牌变为k(洗牌机的作用就是置换),现在给定一个初始排列(数字为1到n),洗牌S次后的牌为(a1,a2..an) 求初始的牌的排列。分析:我们逆着来看,本质就是问你从一个初始状态已知的局面经过S次置换后的状态。我们可以求得置换群的循环节m,然后k=S%m ,把剩余的次数通过暴力模拟置换来获得初始状态。这个模型是帮助理解这整个个置换过程是如何进行的http://poj.org/problem?id=1721
模型3:给定一个值m,拆成若干个>=1的整数集合,使得他们的最小公倍数最大,这个数字代表了某个置换群的循环节,我们最终还要求得这个字典序最小的置换群。分析:先看这样一个数学模型将m分成若干数,使得其lcm最大,一个贪心的策略是两两的最大公约数越小越好,最好就是1了,那么最好的局面就是两两互素为什么呢,假定一个最优的情况中,有两个元素a,b d=gcd(a,b) 那么其lcm=ab/d,对于整体的贡献等价于a/d于b/d 但是明显多出来了 a+b-a/d-b/d,我们可以做新德分配,虽然“可能”内部的因子会被整体完全或部分覆盖,但是有一定的“概率”产生出和其他等效得来的lcm不产生公共因子的数字,于是这两种看似等效的方案,显然互素的那种方案至少不会比部互素的方案差,于是推到至两两满足互素。(证明的不是很严谨,望有兴趣同学给出严谨证明)。那么这部分我们可以预处理出若干素数,用dp[i][j]表示前i个素数 组成的和为j时最大的lcm,同时pre[i][j]记录第j个素数用了几个(可以理解成幂指数),通过这个我们可以得到一组分配的解,现在主要的精力就是放在如何得到这个置换群上了。 通过刚才的pre[i][j]来分解,构造出一组解,有剩余的都用1来补足。循环群类似(2,3,4,1)这样的构造就可以保证字典序最小。http://poj.org/problem?id=3590
这些题都是POJ上面的。
先说下循环的概念。
记(a1 a2 ^ an)= 为一个循环。循环亦称做轮换。可以认为是a1到an组成了一个环。而一个置换可以写成多个循环的乘积。比如
=(a1a3a6)(a2a4)(a5)。而循环节的长度就是轮换的个数。这里循环节长度为3。
对于循环有一些操作。比如乘上一个[对换]。
定义(a1,b1)为将a循环中的a1元素和b循环中的b1元素交换。则这是一个两元素在不同轮换中的对换。给循环乘上这个对换。即相当于将原来的两个“环”分别在a1和b1处拆开,再连接成一个新的“环”。也就是说,就是这种对换将两个轮换合并成了一个。
反之,如果对换发生在某轮换内部,那么相当于在(a1,ai)处将此环拆开,然后分别合并为了两个新“环”。也就是说,这种对换将轮换分拆为了两个新的轮换。
如果我们记置换群中元素个数为n,循环节长度为a,可以发生的内部对换数为b。则有下列式子成立:
b = n-a。
想到了神马?对了,最小路径覆盖。
实际上,二分图就是一个置换群。上面一排元素为X集,下面一排元素为Y集。在利用二分图求解最小路径覆盖问题的时候,每次增加一个匹配,路径数就会减少一条。也就是说,匹配数+路径条数==顶点个数。如果想要尽量减小路径条数,大家都看得出来要求最大匹配。
类比一下,匹配数即为轮换内对换数,路径条数即为循环节长度,而顶点个数也就是置换群内的元素个数。所以说,此题其实是求置换群中循环节的长度。
还有一个记忆犹新的例子。那就是某个神奇的DP题。
题目大意大概就是一些钥匙分别对应一些门,但是这些钥匙分别放在不同的门里,并且锁起来了(多么悲催~~)。现在你有两条途径得到这些钥匙。要么破坏门,拿出里面的钥匙。要么用之前得到的钥匙去开现在面对的门。求最少破坏的门的数目。
看出来了,对不对?门看做大括号上面一排元素,钥匙看做下面一排。如果出现“钥匙转圈”的现象,那么即形成一个轮换。此题即变为求循环节的长度。
而用dp求解的时候,我们写方程如下:
f[i][j] = min{f[i-1][j-1],(i-1)*f[i-1][j]}。这样,第一个式子是设前面i-1个元素组成一个循环,而后一个式子则是通过给前i-1个元素组成的循环乘上一个两元素分属于不同轮换的对换将它和第i个元素的轮换合并为了一个。
这样,不论是DP还是图论,我们都可以统一地用离散数学的群论来总结和解释。
其实,之前在学习群论的过程中,就隐约体会到了其对于其他领域问题的一些本质解释。比如拓扑排序,比如线性代数。
所以说,虽然有一些抽象而看上去没神马用处的数学理论,其实往往蕴藏着一些更本质的问题。如果深入理解,也一定会有所获益。