NumberSmallGroups算法

D:\MathTool\gaptool>NumberSmallGroups
第1種:GAP[3,1]:
1 2 3
2 3 1
3 1 2
第1種:GAP[4,2]:
1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1
第2種:GAP[4,1]:
1 2 3 4
2 1 4 3
3 4 2 1
4 3 1 2
第3種:GAP[4,1]:
1 2 3 4
2 3 4 1
3 4 1 2
4 1 2 3
第4種:GAP[4,1]:
1 2 3 4
2 4 1 3
3 1 4 2
4 3 2 1

#include "stdafx.h"
#include "FiniteGroup.h"
#include <iostream>
#include <vector>
using namespace std;

// Aut(C_3)=C_2
int g_C3[3][3]={
    {1,2,3},
    {2,3,1},
    {3,1,2},
};

//Aut(K_4)=S_3
int g_K4[4][4]={
    {1,2,3,4},
    {2,1,4,3},
    {3,4,1,2},
    {4,3,2,1},
};

// Aut(C_4)=C_2
int g_C4[4][4]={
    {1,2,3,4},
    {2,3,4,1},
    {3,4,1,2},
    {4,1,2,3},
};

int g_C4a[4][4]={
    {1,2,3,4},
    {2,1,4,3},
    {3,4,2,1},
    {4,3,1,2},
};

int g_C4b[4][4]={
    {1,2,3,4},
    {2,4,1,3},
    {3,1,4,2},
    {4,3,2,1},
};

typedef unsigned int TElem; // unsigned char
typedef vector<vector<TElem> > MATRIXi8;

bool nextV1(int m,vector<TElem>& v){
    int n=v.size();
    for(int i=n-1;i>=0;i--){
        if(v[i]<m-1){
            v[i]+=1;
            return true;
        }
        else if(v[i]==m-1 && i>0){
            if(v[i-1]<m-1){
                v[i-1]+=1;
                for(int j=i;j<n;j++)
                    v[j]=0;
                return true;
            }
        }
    }
    return false;
}

bool isValidRow(MATRIXi8& M,int i){
    int n=M.size();
    vector<TElem> I;
    for(int k=0;k<n;k++){
        I.push_back(M[i][k]);
    }
    sort(I.begin(),I.end());
    for(int k=0;k<n;k++){
        if(I[k]!=k)
            return false;
    }
    return true;
}

bool isValidCol(MATRIXi8& M,int i){
    int n=M.size();
    vector<TElem> I;
    for(int k=0;k<n;k++){
        I.push_back(M[k][i]);
    }
    sort(I.begin(),I.end());
    for(int k=0;k<n;k++){
        if(I[k]!=k)
            return false;
    }
    return true;
}

// 調用IsGroup之前先調用check進行檢測:第一行和第一列是恆等置換,每行每列不同
bool check(MATRIXi8& M){
    int n=M.size();
    for(int k=0;k<n;k++){
        if(M[0][k]!=k||M[k][0]!=k)
            return false;
    }
    for(int k=0;k<n;k++){
        if(!isValidRow(M,k))
            return false;
        if(!isValidCol(M,k))
            return false;
    }
    return true;
}

vector<TElem> M2V(MATRIXi8& M){
    int n=M.size();
    vector<TElem> v(n*n);
    for(int k=0;k<n*n;k++)
        v[k]=M[k/n][k%n];
    return v;
}

// 調用n^(n^2)次visit,僅對n<=3有效
vector<vector<TElem> > visitMnRn(int n){
    vector<vector<TElem> > Set;
    vector<TElem> v(n*n,0);
    int cnt=0;
    do {
        ++cnt;
        MATRIXi8 M(n,vector<TElem>(n,0));
        for(int k=0;k<n*n;k++){
            int i=k/n;
            int j=k%n;
            M[i][j]=v[k];
        }
        bool b=check(M);
        if(b){
            Set.push_back(v);
        }
    }while(nextV1(n,v));
    return Set;
}

// 做了一點優化,但僅對n<=4有效
vector<vector<TElem> > visitMn(int n){
    vector<vector<TElem> > Set;
    vector<TElem> v((n-1)*(n-1),0);
    int cnt=0;
    do {
        ++cnt;
        MATRIXi8 M(n,vector<TElem>(n,0));
        for(int k=0;k<n;k++){
            M[0][k]=k;
            M[k][0]=k;
        }
        for(int k=0;k<(n-1)*(n-1);k++){
            int i=k/(n-1);
            int j=k%(n-1);
            M[i+1][j+1]=v[k];
        }
        bool b=check(M);
        if(b){
            Set.push_back(M2V(M));
        }
    }while(nextV1(n,v));
    return Set;
}

int main()
{
    for(int N=3;N<=4;N++){
        vector<vector<TElem> > vG3=visitMn(N);
        int nG3=vG3.size();
        for(int i=0;i<nG3;i++){
            vector<int> vArr(vG3[i].size());
            //int N=sqrtf(vG3[i].size());
            for(int j=0;j<vArr.size();j++){
                vArr[j]=vG3[i][j];
            }
            FiniteGroup g3(N,&vArr[0],0);
            bool bG=IsGroup(&g3);
            if(!bG){
                cout<<"不是羣:"<<endl;
                printGroup(&g3);
                continue;
            }
            int ID=IdGroup(&g3);
            char sz[100]={0};
            sprintf(sz,"GAP[%d,%d]:",g3.size(),ID); 
            cout<<"第"<<i+1<<"種:"<<sz<<endl;
            printGroup(&g3);    
        }
    }
    //system("pause");
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章