思考图相似的问题: 如果一个图和另一个相似但,顶点标注不同,能否判断出来。
思路如下:
用矩阵表示图
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个顶点交换