首页 > 代码库 > 验证图是否相似

验证图是否相似

思考图相似的问题,如果一个图和另一个相似但,顶点标注不同,能否判断出来。

思路如下:

用矩阵表示图

1)枚举第二图的顶点的一个排列

     a) 通过swap的方法得到第二图的新图

    (发现交换顶点,只需要交换相应的行和列就得到新图)

     b) 匹配第一图和第二图的新图

     c) 相同就完成,否则回到1)

实现如下

package com.pnp.mapsim;

import java.util.Arrays;

public class Main {

	int[][] map1 = new int[][]{
			{-1, 0, 1, 0},
			{ 0,-1, 1, 1},
			{ 1, 1,-1, 1},
			{ 0, 1, 1, -1}
		};
		
		int[][] map2 = new int[][] {
			{-1, 1, 1, 1},
			{ 1,-1, 0, 1},
			{ 1, 0,-1, 0},
			{ 1, 1, 0, -1}
		};
		
	int [] idxArray = new int[] {
			1,2,3,4
	};
	
	static final int POINT_COUNT=4; 
	boolean isMath(int[][] m1, int[][] m2) {
		for (int i=0; i<POINT_COUNT; i++) {
			for (int j=0; j<POINT_COUNT; j++ ) {
				if ( m1[i][j] != m2[i][j])
					return false;
			}
		}
		System.out.println("--- mathed -----");
		System.out.println(Arrays.toString(idxArray));
		return true;
	}
	
	void swap(int[][] m, int p1, int p2) {
		System.out.println("=== swap: " + p1 + " " + p2);
		//swap row
		for(int i=0; i<POINT_COUNT; i++) {
			int tmp = m[p1][i];
			m[p1][i] = m[p2][i];
			m[p2][i] = tmp;		
		}
		//swap col
		for(int j=0; j<POINT_COUNT; j++) {
			int tmp = m[j][p1];
			m[j][p1] = m[j][p2];
			m[j][p2] = tmp;		
		}
		swapIdxArray(p1,p2);
	}
	
	void swapIdxArray(int p1, int p2) {
		int tmp = idxArray[p1];
		idxArray[p1] = idxArray[p2];
		idxArray[p2] = tmp;
	}
	
	
	boolean premu(int i) {
		if ( isMath(map1, map2))
			return true;
		
		int j=i+1;
		while( j<POINT_COUNT) {
			swap(map2,i,j);
			if ( premu(i+1) )
				return true;
			swap(map2,j,i);
			j++;
		}
		return false;
	}


	
	public static void main(String[] args) {
		Main m = new Main();
		for(int i=0; i<POINT_COUNT-1; i++)
			if ( m.premu(i) )
				return;
	}
}


运行结果貌似正确

=== swap: 0 1
=== swap: 1 2
=== swap: 2 3
=== swap: 3 2
=== swap: 2 1
=== swap: 1 3
=== swap: 2 3
=== swap: 3 2
=== swap: 3 1
=== swap: 1 0
=== swap: 0 2
--- mathed -----

第二图新图的顶点索引是 [3, 2, 1, 4], 就是第1个顶点和第3个顶点交换

验证图是否相似