同態、同構判定算法

[C4toC4]isomorphism0:1
1 2 3 4
2 3 4 1
3 4 1 2
4 1 2 3
[C4toC4]homomorphism1:2
[C4toC4]isomorphism2:1
1 2 3 4
2 3 4 1
3 4 1 2
4 1 2 3
[C4toC4a]isomorphism3:1
1 2 3 4
2 1 4 3
3 4 2 1
4 3 1 2
[C4toC4b]isomorphism4:1
1 2 3 4
2 4 1 3
3 1 4 2
4 3 2 1
[C4atoC4b]isomorphism5:1
1 2 3 4
2 4 1 3
3 1 4 2
4 3 2 1

#include "stdafx.h"
//#include "FiniteGroup.h"
#include <functional>
#include <iostream>
#include <vector>
#include <map>
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},
};

/*
同態homomorphism:粗略地說,同態是一個保持合成法則的映射。
同構isomorphism:就是說這兩個代數結構的元素之間存在一個一一對應,並且這個對應保持代數運算。
全同構holohedral isomorphism
自同構automorphism
同胚homeomorphism
*/
#if 0
typedef int(*morphism)(int i);
#else
typedef function<int(int)> morphism;
#endif

function<int(int)> mul(function<int(int)> f1,function<int(int)> f2){
    function<int(int)> f=[=](int i){return f2(f1(i));};
    return f;
}

function<int(int)> inv(function<int(int)> f1,int n){
    function<int(int)> f=[=](int i){
        for(int j=0;j<n;j++){
            if(f1(j)==i)
                return j;
        }
        return -1;
    };
    return f;
}

bool isEqual(function<int(int)> f1,function<int(int)> f2,int n){
    for(int i=0;i<n;i++){
        if(f1(i)!=f2(i))
            return false;
    }
    return true;
}

bool isBijective(function<int(int)> f1,int n){
    map<int,int> M;
    for(int i=0;i<n;i++){
        M[f1(i)]=i;
    }
    return M.size()==n;
}

// 平凡同構
int isomorphism0(int i){
    return i;
}

int homomorphism1(int i){
    static map<int,int> M;
    if(M.size()==0){
        M[1]=1;
        M[2]=3;
        M[3]=1;
        M[4]=3;
    }
    if(i<0||i>=M.size())
        return 0;
    return M[i+1]-1;
}

int isomorphism2(int i){
    static map<int,int> M;
    if(M.size()==0){
        M[1]=1;
        M[2]=4;
        M[3]=3;
        M[4]=2;
    }
    if(i<0||i>=M.size())
        return 0;
    return M[i+1]-1;
}

int isomorphism3(int i){
    static map<int,int> M;
    if(M.size()==0){
        M[1]=1;
        M[2]=3;
        M[3]=2;
        M[4]=4;
    }
    if(i<0||i>=M.size())
        return 0;
    return M[i+1]-1;
}

int isomorphism4(int i){
    static map<int,int> M;
    if(M.size()==0){
        M[1]=1;
        M[2]=2;
        M[3]=4;
        M[4]=3;
    }
    if(i<0||i>=M.size())
        return 0;
    return M[i+1]-1;
}

// 是否是同態映射(0:不同態,1:同構,2:同態但不同構)
int isHomomorphism(int* arr2,int* arr2f,int n,morphism f){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            // f(i*j)=f(i)*f(j)
            int ij=(*(arr2+i*n+j)-1);
            int fij=f(ij);
            int fifj=*(arr2f+f(i)*n+f(j))-1;
            if(fij!=fifj)
                return 0;
        }
    }
    // 進一步判斷是否是同構映射
    bool bj=isBijective(f,n);
    return bj?1:2;
}

// 是否是自同態映射
int isHomomorphism(int* arr2,int n,morphism f){
    return isHomomorphism(arr2,arr2,n,f);
}

void printIm(int* arr2,int n,morphism f){
    vector<vector<int> > vv(n,vector<int>(n,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            int ij=(*(arr2+i*n+j)-1);
            int fij=f(ij);
            vv[i][j]=fij;
        }
    }
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            // 交換行
            if(vv[j][0]<vv[i][0]){
                vector<int> v(n);
                for(int k=0;k<n;k++){
                    v[k]=vv[j][k];
                    vv[j][k]=vv[i][k];
                    vv[i][k]=v[k];
                }
            }
            // 交換列
            if(vv[0][j]<vv[0][i]){
                vector<int> v(n);
                for(int k=0;k<n;k++){
                    v[k]=vv[k][j];
                    vv[k][j]=vv[k][i];
                    vv[k][i]=v[k];
                }
            }
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            printf("%d ",vv[i][j]+1);
        }
        printf("\n");
    }
}

int main(){
    {
        morphism fArr[]={isomorphism0,homomorphism1,isomorphism2};
        const char *szNameArr[]={"isomorphism0","homomorphism1","isomorphism2"};
        int cnt=sizeof(szNameArr)/sizeof(szNameArr[0]);
        for(int i=0;i<cnt;i++){
            int bH=isHomomorphism(&g_C4[0][0],4,fArr[i]);
            printf("[C4toC4]%s:%d\n",szNameArr[i],bH);
            if(bH==1){
                printIm(&g_C4[0][0],4,fArr[i]);
            }
        }
    }
    {
        morphism fArr[]={isomorphism3};
        const char *szNameArr[]={"isomorphism3"};
        int cnt=sizeof(szNameArr)/sizeof(szNameArr[0]);
        for(int i=0;i<cnt;i++){
            int bHa=isHomomorphism(&g_C4[0][0],&g_C4a[0][0],4,fArr[i]);
            printf("[C4toC4a]%s:%d\n",szNameArr[i],bHa);
            if(bHa==1){
                printIm(&g_C4[0][0],4,fArr[i]);
            }
        }
    }
    {
        morphism fArr[]={isomorphism4};
        const char *szNameArr[]={"isomorphism4"};
        int cnt=sizeof(szNameArr)/sizeof(szNameArr[0]);
        for(int i=0;i<cnt;i++){
            int bHa=isHomomorphism(&g_C4[0][0],&g_C4b[0][0],4,fArr[i]);
            printf("[C4toC4b]%s:%d\n",szNameArr[i],bHa);
            if(bHa==1){
                printIm(&g_C4[0][0],4,fArr[i]);
            }
        }
    }
    {
        morphism f3=isomorphism3;
        morphism f4=isomorphism4;
        morphism f5=mul(inv(f3,4),f4);
        morphism fArr[]={f5};
        const char *szNameArr[]={"isomorphism5"};
        int cnt=sizeof(szNameArr)/sizeof(szNameArr[0]);
        for(int i=0;i<cnt;i++){
            int bHa=isHomomorphism(&g_C4a[0][0],&g_C4b[0][0],4,fArr[i]);
            printf("[C4atoC4b]%s:%d\n",szNameArr[i],bHa);
            if(bHa==1){
                printIm(&g_C4a[0][0],4,fArr[i]);
            }
        }
    }
    system("pause");
    return 0;
}

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