同态、同构判定算法

[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},
};

/*

*/
#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;
}

10-07 7652

11-02 2万+
02-06 130
09-24 436
11-22 40
11-05 1万+
04-13 394
05-18 2130
07-21 23