学习了polya计数,例如对正10边形的10个顶点进行着色,不想将所有的置换全部罗列出来,然后将它们一一转化为循环因子乘积的形式。有没有其它一些快捷的方法。
例如对于正4边形有,
在平面旋转产生的4个置换:
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
1 2 3 4 2 3 4 1 3 4 1 2 4 1 2 3
在空间翻转产生的4个置换
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
4 3 2 1 2 1 4 3 1 4 3 2 3 2 1 4
一共存在这样8个置换,然后对每个置换求解循环因子乘积。
[1]·[2]·[3]·[4]
[1 2 3 4]
[1 3]·[2 4]
[1 4 3 2]
[1 4]·[2 3]
[1 2]·[3 4]
[1]·[2 4]·[3]
[1 3]·[2]·[4]
然后根据生成函数求解。
对于4边形还可以,要是更多边形,就不容易做了。我们需要寻找简单方法。
对于正n边形,对于旋转的n个置换,设定函数g(n,k)为置换
1 2 3 4 5 ...
k k+1 k+2 k+3 k+4 ...
在生成函数中形式?
例如如果k = 1,
则g(n, 1) = z(1,n) 其中1为下标,n为上标,代表n次方。因为不容易表示,在这里使用一些方式。
例如k = n,这样的话,g(n, n) = z(n, 1),其中n为下标,1为上标,代表1次方。
现在给出g(n, k)的公式:
g(n, k) =
{
for (t = 1; t <=n; ++t) {
if ((t * k - (t - 1)) % n == 1) {
return z(t, n / t);
}
}
}
这样的话,只需要遍历k从1到n便可。
上面讨论了旋转的n个置换,再来考虑反射的n个置换。
如果n是奇数,例如5,7,
那么反射置换产生的总形式为:
n * (z(1, 1) * z(2, (n - 1) / 2))
如果n是偶数,例如4,6,则有n/2个对称轴,n/2个对角线。
对于一个对称轴,z(2, n/2);
对于一个对角线,z(1, 2)*z(2, (n - 2)/ 2)
综上,
如果n为奇数,
return n * (z(1, 1) * z(2, (n - 1) / 2))
如果n为偶数,
return n/2 * z(2, n/2) + n/2* z(1, 2)*z(2, (n-2)/2)
这样就可以直接求出生成函数,求解了。
下面是使用matlab编写的代码
function result = polya(n, MODE);
% polya 该函数计算一个正n边形的polya计数
% 输入:n 正n边形
% MODE: 1|2|3
% 1 只考虑旋转
% 2 只考虑反射
% 3 说明旋转和反射都计算
% 输出:polya的生成函数,在这里返回元胞,其中每个元素包含了z1z2...zn各自的指数
% Author : 李盼
% Timestamp : 2012/11/19 14:17
for i = 1:1:n
xuanzhuan_polya{1, i} = zeros(1, n);
end
% 这里同样需要是元胞数组
for k = 1:1:n
result{k, 1}{1} = 0;
result{k, 1}{2} = zeros(1, n);
end
if (3 == MODE || 1== MODE) % 模式是1或3
for k = 1:1:n
for t = 1:1:n
if (mod(t * k - (t - 1), n) == 1)
xuanzhuan_polya{1, k}(1, t) = n / t; %这个公式是作者推导出来的
break;
end
end
end
%计算出所有的置换的生成函数之后,进行整合
for k = 1:1:n
cell = xuanzhuan_polya{1, k};
t = sum(cell);
result{t, 1}{1} = result{t, 1}{1} + 1;
result{t, 1}{2} = cell;
end
end
if (3 == MODE || 2 == MODE) % 模式是2或3
%讨论反射
if (mod(n, 2) == 1) % n为奇数
result{(n + 1) / 2, 1}{1} = result{(n + 1) / 2, 1}{1} + n;
result{(n + 1) / 2, 1}{2} = [1, (n - 1) / 2, zeros(1, n - 2)];
else % n为偶数
result{(n + 2) / 2, 1}{1} = result{(n + 2) / 2, 1}{1} + n / 2;
result{(n + 2) / 2, 1}{2} = [2, (n - 2) / 2, zeros(1, n - 2)];
result{n / 2, 1}{1} = result{n / 2, 1}{1} + n / 2;
result{n / 2, 1}{2} = [0, n / 2, zeros(1, n - 2)];
end
end
% 对result中那些出现0次的置换过滤掉
count = 0;
for i = 1:1:n
if (result{i, 1}{1} ~= 0)
count = count + 1;
temp_result{count, 1}{1} = result{i, 1}{1};
temp_result{count, 1}{2} = result{i, 1}{2};
end
end
result = temp_result;
end
% Finished Time 2012/11/20 8:36
