Refactoring recognition for c++ graphs

1. Isomorphic meaning of graph

Simply understand, the essence of the graph is the same, but the way of expression is different.
For example, the following graph:
insert image description here

Its isomorphic graphs are:
insert image description here

insert image description here
Wait, it can be found that the isomorphism of the graph is actually caused by the different numbering of the points. It can also be deduced that if one graph can be replaced with another graph through the numbering, then the two graphs are isomorphic, otherwise isomorphic

Two, the representation method of the graph

There are many ways to represent graphs, such as adjacency list, adjacency matrix and so on. Obviously, the isomorphism of graphs is conveniently represented by an adjacency matrix.

We use two pictures as examples to explain the problem

figure 1:
insert image description here

figure 2:
insert image description here

The adjacency matrix in Figure 1 is expressed as:
0 1 0 0 0 1
0 1 1 0 0 1 0
0 0 0 1
0 0 1 0
0 0 1 0

The adjacency matrix in Figure 2 is expressed as:
0 1 1 0 0 1
0 0 1 1 1
0 0 0 0 0 1
0 0 0
0 1 0 0 0

Three, the transformation of the picture

Let's think about it, how to convert Figure 2 into Figure 1?

Obviously, changing the number 5 to 1, changing the number 4 to 3, changing the number 1 to 4, and changing the number 3 to 5, is exactly the same as Figure 1!

For example, the adjacency matrix of Figure 2:

1 2 3 4 5
1 0 1 1 0 0
2 1 0 0 1 1
3 1 0 0 0 0
4 0 1 0 0 0
5 0 1 0 0 0

Note that the first row represents the column number, and the second row represents the row number.
After we replace the number, the adjacency matrix is ​​as follows:

4 2 5 3 1
4 0 1 1 0 0
2 1 0 0 1 1
5 1 0 0 0 0
3 0 1 0 0 0
1 0 1 0 0 0

We want to reconvert the columns into 1, 2, 3, 4, 5, how to convert?
Just sort each column according to the column number. For example, 4 will roll back to the 4th column, and 5 will roll back to the 5th column.

After column transformation, the figure is as follows:

1 2 3 4 5
4 0 1 0 0 1
2 1 0 1 1 0
5 0 0 0 1 0
3 0 1 0 0 0
1 0 1 0 0 0

Then row conversion is also the same

The figure after row conversion is as follows:

1 2 3 4 5
1 0 1 0 0 0
2 1 0 1 1 0
3 0 1 0 0 0
4 0 1 0 0 1
5 0 0 0 1 0

It is exactly the same as the adjacency matrix in Figure 1, then the two graphs can be considered to be isomorphic
0 1 0 0 0 1
0 1 1 0 0
1 0 0 0
0 1 0 0 1 0
0 0 1 0

Fourth, the implementation of the algorithm

To convert from Figure 2 to Figure 1, we need to change the numbers 1, 2, 3, 4, and 5 in Figure 2 to 4, 2, 5, 3, and 1 in turn.
So how do we know that we need to change to 4, 2, 5, 3, 1?

Yes, it is violence!
Try all the possibilities, in fact, try the full arrangement of 1, 2, 3, 4, 5

For example, 1, 2, 3, 4, 5 are not working, then I will try 1, 2, 3, 5,
4 and then try 1, 2, 4, 3, 5, and then try again

If the two graphs are isomorphic, then a solution must be found to convert graph 2 into graph 1, otherwise it proves that the two graphs are not isomorphic

Here is the c++ code:

#include<bits/stdc++.h>
using namespace std;
int n;
int a[110][110];//存图1 
int b[110][110];//存图2 
int c[110][110];//存图2行变换之后的图 
int d[110][110];//存图2列变换之后的图 
int q[110];

bool check(){
    
    
//	转换行 
	for(int i=0;i<n;i++){
    
    
		for(int j=0;j<n;j++){
    
    
			c[i][j]=b[q[i]][j];
		}
	}
//	转换列 
	for(int j=0;j<n;j++){
    
    
		for(int i=0;i<n;i++){
    
    
			d[i][j]=c[i][q[j]];
		}
	} 
//	判断同构 
	for(int i=0;i<n;i++){
    
    
		for(int j=0;j<n;j++){
    
    
			if(a[i][j]!=d[i][j]){
    
    
				return false;
			}
		}
	}
	return true;
}

int main(){
    
    
	cout<<"请输入两矩阵的大小:"<<endl;
	cin>>n; 
	cout<<"请输入第一个矩阵:"<<endl;
	for(int i=0;i<n;i++){
    
    
		for(int j=0;j<n;j++){
    
    
			cin>>a[i][j];
		}
	}
	cout<<"请输入第二个矩阵:"<<endl;
	for(int i=0;i<n;i++){
    
    
		for(int j=0;j<n;j++){
    
    
			cin>>b[i][j];
		}
	}
	cout<<"运行中..."<<endl;
	for(int i=0;i<n;i++){
    
    
		q[i]=i;
	}
//	全排列遍历 
	do{
    
    
		if(check()){
    
    
			cout<<"两个图是重构的!"<<endl;
			return 0; 
		}
	}while(next_permutation(q,q+n));//这个是c++提供的全排列模板,也可以自己写全排列 
	
	 
	cout<<"两个图是不重构的!"<<endl;
	
} 


It can be put together when performing transformation and column transformation, and it is separated for easy understanding!

5. Test sample

Friends who write their own code can use the following test samples that have been constructed:

Example 1:

5
0 1 0 0 0
1 0 1 1 0
0 1 0 0 0
0 1 0 0 1
0 0 0 1 0
0 1 1 0 0
1 0 0 1 1
1 0 0 0 0
0 1 0 0 0
0 1 0 0 0


//输出:
//yes

Example 2:

5
0 1 1 0 0
1 0 1 1 0
0 1 0 0 0
0 1 0 0 1
0 0 0 1 0
0 1 1 0 0
1 0 0 1 1
1 0 0 0 0
0 1 0 0 0
0 1 0 0 0


//输出:
//no

Example 3:

6
0 1 0 0 0 0
1 0 1 0 0 0
0 1 0 1 0 0
0 0 1 0 1 1
0 0 0 1 0 0
0 0 0 1 0 0
0 1 0 0 0 0
1 0 1 0 0 1
0 1 0 1 0 0
0 0 1 0 1 0
0 0 0 1 0 0
0 1 0 0 0 0

//输出:
//yes

Example 4:

9
0 1 0 0 0 0 0 0 0
1 0 0 1 0 0 1 0 0
0 0 0 1 0 0 0 0 0
0 1 1 0 1 0 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 0
1 0 1 1 0 0 0 0 0
0 1 0 0 0 0 0 1 1
0 1 0 0 1 0 1 0 0
0 0 0 1 0 1 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0

//输出:
//yes

Example 5:

9
0 1 0 0 0 0 0 0 0
1 0 0 1 0 0 1 0 0
0 0 0 1 0 0 0 0 0
0 1 1 0 1 0 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 1 0
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0
1 0 1 1 0 0 0 0 0
0 1 0 0 0 0 0 1 1
0 1 0 0 1 0 1 0 0
0 0 0 1 0 1 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0

//输出:
//no

6. Complexity analysis

Time complexity O(n 2 *n!)
Space complexity O(n 2 )

Guess you like

Origin blog.csdn.net/weixin_52115456/article/details/127798795