Sub-graph isomorphism algorithm Ullmann as early as 1976, we are interested to search the original text to see. Here I will briefly explain.
Given two graphs Q and G, their corresponding matrices are respectively and. Our goal is to find the matrix.
Algorithm steps:
Step1. Setup Matrix MNXM, such that m[i][j]=1, if 1) the i-th vertex in Q hasthe same label as the j-th vertex in G; and 2) The i-th vertex have Smallervertex degree than the j-th vertex in G.
STEP2.MATRIXESM is generated by systematically changing to 0 all but one of the 1 's in Eachof the rows of M, subject to T He definitory condition that no column of Amatrix M is contain more than one 1.
Step3.verify Matrix M ' by the following equation
In order to improve the efficiency of the algorithm, the following refinement are used.
Refinement:
Letthe i-th Vertex v in Q corresponds to the j-th vertex u in g.each neighbor vertex ofv in Q m UST correspond to some neighbor Vertexof u in G. Otherwise,vcannot correspond to u.
1. Considering the matrix M, for each 1 in M, we refine it by the followingequation. If fails, change 1 through 0 in M.
2. If there exists at least one row (in M) has no 1, we report no subgraphisomorphism from Q to G.
The next step is to paste the code directly.
Package Ucas.iie.graph.action;import Java.io.bufferedreader;import Java.io.fileinputstream;import Java.io.ioexception;import Java.io.inputstreamreader;import Java.util.arraylist;import Ucas.iie.graph.bean.edgebean;import Ucas.iie.graph.bean.graphbean;import Ucas.iie.graph.bean.vertexbean;public Class Isomorphismimpl {Private arraylist<graphbean> query_g;//query sub-diagram private arraylist<graphbean> mydb_g;/ /Figure Total Data Public Isomorphismimpl () {query_g = new arraylist<graphbean> (); mydb_g = new arraylist<graphbean> ();} /** * * @param query * @param db * @return return the initial matrix M0 */public int[][] GETMATRIXM (graphbean query, Graphbean db) {int row = Query.getvlist (). Size (), int column = Db.getvlist (). Size (); int[][] M0 = new int[row][column];//System.out.println ("M0 : "); for (int i = 0; i < row; i++) {for (int j = 0; j < column; J + +) {String VI = query.getvlist (). get (i). Getvertex (); String VJ = Db.getvlist (). Get (J). Getvertex (); if (Db.getvdegree (VJ) >= Query.getvdegree (vi)) M0[I][J] = 1;ELSEM0[I][J] = 0;//System.out.print (m0[i][j] + "");} System.out.println ("");} return M0;} Public arraylist<graphbean> Getquery_g () {return query_g;} public void Setquery_g (arraylist<graphbean> query_g) {this.query_g = Query_g;} Public arraylist<graphbean> Getmydb_g () {return mydb_g;} public void Setmydb_g (arraylist<graphbean> mydb_g) {this.mydb_g = Mydb_g;} /** * * @param queryfile * Query the path of the child map * @param the total data path of the DBFile * graph * @throws ioexception */public void in Itgraphdb (String queryfile, String dbfile) throws IOException {//Read data from Query sub-graph BufferedReader q_br = new BufferedReader (New in Putstreamreader (New FileInputStream (Queryfile))); String Linedata = Q_br.readline (); Graphbean qgb;if (Linedata.startswith ("t #")) {//First sub-graph QGB = new Graphbean (); while ((Linedata = Q_br.readline ()) = null) {if (Linedata.startswith ("t #")) {This.query_g.add (QGB); QGB = new Graphbean (); continue;} else if (Linedata.startswith (" V ")) {//vertex string vs[] = Linedata.split (" "); VErtexbean vb = new Vertexbean (); Vb.setvertex (vs[1]); Vb.setlabel (vs[2]); Qgb.getvlist (). Add (VB);} else {//edge string es[] = Linedata.split (""); Edgebean EB = New Edgebean (), Eb.setvertex_i (Es[1]); Eb.setvertex_j (es[2)); Eb.setlabel_e (es[3]); Qgb.getelist (). Add ( EB);}}} Read graph data BufferedReader db_br = new BufferedReader (new InputStreamReader (New FileInputStream (DBFile)); linedata = Db_ Br.readline (); Graphbean dbgb;if (Linedata.startswith ("t #")) {//DBGB = new Graphbean (); while ((Linedata = Db_br.readline ()) = null) {if (Linedata.startswith ("t #")) {This.mydb_g.add (DBGB);d BGB = new Graphbean (); continue;} else if (Linedata.startswith ("V")) {//vertex string vs[] = Linedata.split (""); Vertexbean vb = new Vertexbean (), Vb.setvertex (Vs[1]), Vb.setlabel (vs[2]);d bgb.getvlist (). Add (VB);} else if (Linedata.startswith ("E")) {//edge string es[] = Linedata.split (""); Edgebean EB = New Edgebean (), Eb.setvertex_i (Es[1]), Eb.setvertex_j (Es[2]), Eb.setlabel_e (es[3]);d bgb.getelist (). Add ( EB);}}} /** * Returns the label of the edge * @param i *@param J * @param eblist * @return */public string Getlabel (String I, String J, arraylist<edgebean> Eblist) {for (in t k = 0; K < Eblist.size (); k++) {Edgebean EB = eblist.get (k); String VI = eb.getvertex_i (); String VJ = Eb.getvertex_j (), if (I.equals (vi) && j.equals (VJ)) return eb.getlabel_e (); else if (J.equals (vi) & & I.equals (VJ)) return Eb.getlabel_e ();} return null;} public boolean isisomorphism (Graphbean subgraph, Graphbean graphdb) {int m0[][] = GETMATRIXM (subgraph, graphdb); int MA[][ ] = Subgraph.getmatrix (); int mb[][] = Graphdb.getmatrix (); arraylist<edgebean> EBQ = Subgraph.getelist (); arraylist<edgebean> ebdb = Graphdb.getelist ();//for arbitrary ma[i][x] = 1 ==> exists y m[x][y]mb[y][j] = 1 otherwise m0[i][j] = 0for ( int i = 0; I < Subgraph.getvlist (). Size (); i++) {for (int j = 0; J < graphdb.getvlist (). Size (); j + +) {if (m0[i][j] = = 1) {String Ilabel = subgraph.getvlist (). Get ( i). Getlabel (); String JLabel = Graphdb.getvlist (). Get (J). Getlabel (); if (Ilabel.equals (JLAbel) {for (int x = 0; x < subgraph.getvlist (). Size (); x + +) {Boolean tag = False;if (Ma[i][x] = = 1) {String Label_ix = Getlabel (String.valueof (i), string.valueof (x), EBQ); for (int y = 0; y < graphdb.getvlist (). Size (); y++) {if (m0[x][y] * MB[Y][J] = = 1) {String Label_yj = Getlabel (string.valueof (y), string.valueof (j), EBDB); if (Label_ix.equals (Label_yj)) {/ Compare the labels on the edges between vertices to see if they are equal. tag = True;break;}}} Breakif (!tag) {m0[i][j] = 0;break;}}} Break} else {//if (Ilabel.equals (JLabel)) m0[i][j] = 0;}} if (m0[i][j] = = 1)}}//System.out.println ("M ':"); for (int i = 0; I < Subgraph.getvlist (). Size (); i++) {int sumi = 0;for (int j = 0; J < graphdb.getvlist (). Size (); j + +) {//System.out.print (M0[i][j] + ""); Sumi + = m0[ I][J];} if (Sumi = = 0) {//System.out.println ("M0 has one row element is 0"); return false;} One row of elements is 0, exit directly//SYSTEM.OUT.PRINTLN ();} int raw = Subgraph.getvlist (). Size (), int col = graphdb.getvlist (). Size (), int f[] = new int[col];//F[i] = 1, indicates that column I has used int h[] = new int[raw];//h[d] = k,Indicates that row d of the column K is the nth row int d = 0;//M0 d line int k = 0;//M0 k column int[][][] matrixlist = new int[raw][][];//is used to record the m0for of each d corresponding to (int i = 0; i < F.length; i++) {F[i] =-1;} for (int i = 0; i < h.length; i++) {H[i] =-1;} while (true) {if (h[d] = =-1) {k = 0;matrixlist[d] = M0;} else {//backtracking k = h[d] + 1; F[H[D]] =-1; M0 = Matrixlist[d];} while (K < col) {//IS M0 's column if (m0[d][k] = = 1 && f[k] = = 1) {//Such a column is found and then jumps out, others traverse the break when backtracking;} k++;} if (k = = col) {//d row does not meet the condition of the column, back to the previous layer h[d] = -1;d--;} else {//m0[d][k]=1, the other elements of line d are 0for (int j = 0; J < Col; J + +) {M0[d ][J] = 0;} M0[d][k] = 1; H[d] = k; F[k] = 1;d++;} if (d = =-1) {//SYSTEM.OUT.PRINTLN ("different structure"); return false;} if (d = = raw) {//A M0 is found, followed by verifying if (This.istruefor (MA, MB, M0)) {//Condition//System.out.println ("isomorphic"); return true;} else { Backtracking d = raw-1;}} if}//while}/** * for all element int ma[i][j]=1 ==> mc=m*{(M*MB) ^t},mc[i][j]=1 * * @param MA * @param MB * @param M * @return */public boolean istruefor (int[][) MA, int[][] MB, int m[][]) {Boolean flag = True;int raw = m.length;int column = mb[0].length;int tmp[][] = new Int[raw][colu mn];//tmp[][]=m*mbfor (int i = 0; i < raw; i++) {//rawsfor (int j = 0; j < column; J + +) {//columnsfor (int k = 0; K < M[0].length; k++) {Tmp[i][j] + = m[i][k] * mb[k][j];}}} int tmp_t[][] = new int[column][raw];//transpose for (int i = 0; i < raw; i++) {//rawsfor (int j = 0; j < column; J + +) {// Columnstmp_t[j][i] = Tmp[i][j];}} int mc[][] = new int[ma.length][ma[0].length];//System.out.println ("MC:"); for (int i = 0; i < ma.length; i++) {//rawsfor (int j = 0; J < Ma[0].length; J + +) {//columnsfor (int k = 0; k < m[0].length; k++) {Mc[i][j] + = m[ I][K] * tmp_t[k][j];} System.out.print (Mc[i][j] + "");} System.out.println ();} for (int i = 0; i < ma.length; i++) {//rawsfor (int j = 0; J < Ma[0].length; J + +) {//Columnsif (ma[i][j] = = 1) {if (Mc[i][j] = = 1) continue;elsereturn false;}}} return flag;} public static void Main (string[] args) {IsomOrphismimpl II = new Isomorphismimpl (); String queryfile = "c:\\users\\fernando\\desktop\\q24.my"; String dbfile = "C:\\users\\fernando\\desktop\\mygraphdb.data"; try {ii.initgraphdb (queryfile, DBFile); arraylist<graphbean> query_g = Ii.getquery_g (); System.out.println ("Sub-image (size):" + query_g.size ()); arraylist<graphbean> db_g = Ii.getmydb_g (); SYSTEM.OUT.PRINTLN ("Total map (size):" + db_g.size ()); for (int i = 0; i < query_g.size (); i++) {for (int j = 0; J < Db_g.siz E (); J + +) {Graphbean TQ = Query_g.get (i); Graphbean TDB = Db_g.get (j), if (Ii.isisomorphism (TQ, TDB)) {System.err.println ("t #" + i + "with t #" + j + "isomorphic");}}} catch (IOException e) {//TODO auto-generated catch Blocke.printstacktrace ();}}}
Package Ucas.iie.graph.bean;import Java.util.arraylist;public class Graphbean {/** graph data format * t # 0 = No. 0 Figure v 0 2v 1 2v 2 2v 3 2v 4 2e 0 1 2e 1 2 2e 2 3 2e 3 4 2 */private arraylist<vertexbean> vlist;private arraylist<edgebean> elist;p Ublic Graphbean () {vList = new arraylist<vertexbean> (); eList = new arraylist<edgebean> ();} Public arraylist<vertexbean> getvlist () {return vList;} public void Setvlist (arraylist<vertexbean> vList) {this.vlist = vList;} Public arraylist<edgebean> getelist () {return eList;} public void Setelist (arraylist<edgebean> eList) {this.elist = eList;} Public int[][] Getmatrix () {int[][] M = new Int[vlist.size ()][vlist.size ()];for (int index = 0; index < elist.size (); dex++) {Edgebean EB = elist.get (index); int i = Integer.parseint (Eb.getvertex_i ()); int J = Integer.parseint (eb.getvertex_ J ()); M[I][J] = 1; M[j][i] = 1;} System.out.println ("MA/MB:");//for (int i = 0; I < vlist.size (); i++) {//for (int j = 0; J < vlist.size(); J + +) {//system.out.print (M[i][j] + "");//}//system.out.println ();//}return M;} /** * * @param v * @return Returns the degree of the vertex v */public int getvdegree (String v) {int sumdeg = 0;for (int i = 0; i < elist.size (); i++) {if (Elist.get (i). Getvertex_i (). Equals (v) | | Elist.get (i). Getvertex_j (). Equals (v)) {sumdeg + +;}} return sumdeg;} Public String toString () {String res = ""; for (int i = 0; I < this.vList.size (); i++) {res + = "V" + vlist.get (i). Getvertex () + "" + vlist.get (i). Getlabel () + "\ r \ n";} for (int j = 0; J < This.eList.size (); j + +) {res + = "E" + Elist.get (j). Getvertex_i () + "" + Elist.get (j). Getvertex_j ( ) + "" +elist.get (j). Getlabel_e () + "\ r \ n";} return res;} public static void Main (string[] args) {new Graphbean (). Getmatrix ();}}
Package Ucas.iie.graph.bean;public class Edgebean {//"E i j K" means the edge <i,j> label of the graph is the data format of the K/** graph * t # 0 represents the No. 0 Figure v 0 2 V 1 2v 2 2v 3 2v 4 2e 0 1 2e 1 2 2e 2 3 2e 3 4 2 */private string Vertex_i;private string vertex_j;private string label_e; Public String getvertex_i () {return vertex_i;} public void Setvertex_i (String vertex_i) {this.vertex_i = vertex_i;} Public String Getvertex_j () {return vertex_j;} public void Setvertex_j (String vertex_j) {this.vertex_j = Vertex_j;} Public String Getlabel_e () {return label_e;} public void Setlabel_e (String label_e) {this.label_e = Label_e;}}
Package Ucas.iie.graph.bean;public class Vertexbean {//"V I j" means that the label of the vertex I of the graph is the data format of the J/** Graph * t # 0 represents the No. 0 Figure v 0 2v 1 2v 2 2v 3 2v 4 2e 0 1 2e 1 2 2e 2 3 2e 3 4 2 */private string Vertex;private string Label;public string Getvertex () {return ve Rtex;} public void Setvertex (String vertex) {This.vertex = vertex;} Public String Getlabel () {return label;} public void SetLabel (String label) {this.label = label;}}
The sub-graph isomorphism algorithm Ullmann implemented and took the refinement (Java language)