Polya计数的快捷计算

学习了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
吐舌头


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值