import java.util.Enumeration; import java.io.*; import java.util.*; import java.lang.*; class Graph { public int v;//number of vertices public int adj[][];//adjacency matrix public boolean visited[];//for vertex i, visited[i] true if visited, false otherwise public int v20;//nb of nodes of indegree 2 outdegree 0 public int v21;//nb of nodes of indegree 2 outdegree 1 //! we'll do adj[x][y] = arc x-> y //! allows also multiedges (i.e. entries > 1 ) public Graph( int vertices ) { v = vertices; adj = new int[v][v]; visited = new boolean[v]; } public void printDot(int num,String name) { System.out.println("#"+name+"\ndigraph G_"+num+" {\n"); for( int x=0; x "+y); } } System.out.println("}"); System.out.println(); } public void dumpGraph(int num,String name) { //System.out.println("digraph G_"+num+" {"); try{ Generators.output.write("#"+name+"\ndigraph G_"+num+" {\n"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } for( int x=0; x "+y); try{ Generators.output.write(x+ " -> "+y+"\n"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } try{ Generators.output.write("}\n\n"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //System.out.println("}"); //System.out.println(); } public void dumpGraph(int num) { //System.out.println("digraph G_"+num+" {"); try{ Generators.output.write("\ndigraph G_"+num+" {\n"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } for( int x=0; x "+y); try{ Generators.output.write(x+ " -> "+y+"\n"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } try{ Generators.output.write("}\n\n"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //System.out.println("}"); //System.out.println(); } //All vertices of "this" in toVisit have their image in "two" defined in currentPermutation public boolean recIsomorphic( Graph two , LinkedList toVisit, boolean[] visited, int nbVisited, int[] currentPermutation, boolean print) { if (print){ System.out.println("call"); } if (toVisit.isEmpty()){ if (print){ System.out.println("all visited:"); for (int bloum=0;bloum"+currentPermutation[bloum]); //} } printDot(1,""); System.out.println("and:"); two.printDot(1,""); System.out.println("-------"); **/ while (x-1){ System.out.print(" "+bloum+"->"+currentPermutation[bloum]); } } } if (visited[nextVertex]){ if (print){ System.out.println("been down there"+nextVertex); } return recIsomorphic(two ,toVisit,visited,nbVisited+1,currentPermutation,print); } visited[nextVertex]=true; if (this.getOutDegree(nextVertex)==0){ if (two.getOutDegree(currentPermutation[nextVertex])==0){ if (print){ System.out.println("been there"+nextVertex); } return recIsomorphic(two ,toVisit,visited,nbVisited+1,currentPermutation,print); } else { return false; } } if (print){ System.out.println("been here"); } if (this.getOutDegree(nextVertex)==1){ if (two.getOutDegree(currentPermutation[nextVertex])==1){ int sonThis=0; while(adj[nextVertex][sonThis]==0){ sonThis++; } int sonTwo=0; while(two.adj[currentPermutation[nextVertex]][sonTwo]==0){ sonTwo++; } if (currentPermutation[sonThis]>=0){ if (currentPermutation[sonThis]!=sonTwo){ return false; } else { toVisit.add(sonThis); return recIsomorphic(two ,toVisit,visited,nbVisited+1,currentPermutation,print); } } else { toVisit.add(sonThis); int delp=0; while (delp=0){ if (currentPermutation[sonThis1]==sonTwo2){ //then sonThis2 has to be associated with sonTwo1 if (currentPermutation[sonThis2]>=0){ if (currentPermutation[sonThis2]==sonTwo1){ toVisit.add(sonThis1); toVisit.add(sonThis2); return recIsomorphic(two ,toVisit,visited,nbVisited+1,currentPermutation,print); } else { return false; } } else { toVisit.add(sonThis1); toVisit.add(sonThis2); int delp=0; while (delp=0){ if (currentPermutation[sonThis2]==sonTwo2){ toVisit.add(sonThis1); toVisit.add(sonThis2); return recIsomorphic(two ,toVisit,visited,nbVisited+1,currentPermutation,print); } else { return false; } } else { toVisit.add(sonThis1); toVisit.add(sonThis2); int delp=0; while (delp=0){ if (currentPermutation[sonThis2]==sonTwo1){ //then sonThis1 has to be associated with sonTwo2 toVisit.add(sonThis1); toVisit.add(sonThis2); int delp=0; while (delp0){ if (recDirectedPath(x,j)) { found=true; } } x++; } return found; } } else return false; } //Determines whether the graph is isomorphic to one of those in graphs public boolean containedIn(Vector graphs){ Enumeration enoom = graphs.elements(); boolean isnew = true; int i=5; nogood: while( enoom.hasMoreElements() ){ Graph two = (Graph) enoom.nextElement(); if( this.isomorphic( two ) ){ isnew = false; System.out.println("nope, G_"+(graphs.size()+1)+" isomorphic to G_"+(i)); break nogood; } i++; } return (!isnew); } //Rule R1 applied to 2 arcs. //If both arcs link the same nodes, they //are considered to be the same one //=> use ruleR1multi if it's not the case public void ruleR1(int e1i, int e1j, int e2i, int e2j) { //3 nodes have been added, 2 split and 1 recomb if ((e1i==e2i) && (e1j==e2j)){ //R1 performed on one same edge adj[e1i][e1j]=adj[e1i][e1j]-1; adj[e1i][v-3]=1; adj[v-3][v-2]=1; adj[v-2][e1j]=1; } else { adj[e1i][e1j]=adj[e1i][e1j]-1; adj[e2i][e2j]=adj[e2i][e2j]-1; adj[e1i][v-3]=1; adj[e2i][v-2]=1; adj[v-3][e1j]=1; adj[v-2][e2j]=1; } adj[v-3][v-1]=1; adj[v-2][v-1]=1; } //Rule R2 applied to 2 arcs. //If both arcs link the same nodes, they //are considered to be the same one //=> use ruleR2multi if it's not the case public void ruleR2(int e1i, int e1j, int e2i, int e2j) { //2 nodes have been added, 1 split and 1 recomb if ((e1i==e2i) && (e1j==e2j)){ //R2 performed on one same edge adj[e1i][e1j]=adj[e1i][e1j]-1; adj[e1i][v-2]=1; adj[v-2][v-1]=2; adj[v-1][e1j]=1; } else { adj[e1i][e1j]=adj[e1i][e1j]-1; adj[e2i][e2j]=adj[e2i][e2j]-1; adj[e1i][v-2]=1; adj[e2i][v-1]=1; adj[v-2][e1j]=1; adj[v-1][e2j]=1; adj[v-2][v-1]=1; } } //Rule R1 applied to 2 different arcs which link the same nodes public void ruleR1multi(int e1i, int e1j, int e2i, int e2j) { if ((e1i==e2i) && (e1j==e2j)){ //3 nodes have been added, 2 split and 1 recomb adj[e1i][e1j]=0; adj[e1i][v-3]=1; adj[e1i][v-2]=1; adj[v-3][e1j]=1; adj[v-2][e1j]=1; adj[v-3][v-1]=1; adj[v-2][v-1]=1; } } //Rule R2 applied to 2 different arcs which link the same nodes public void ruleR2multi(int e1i, int e1j, int e2i, int e2j) { if ((e1i==e2i) && (e1j==e2j)){ //2 nodes have been added, 1 split and 1 recomb adj[e1i][e1j]=0; adj[e1i][v-2]=1; adj[e1i][v-1]=1; adj[v-2][e1j]=1; adj[v-1][e1j]=1; adj[v-1][v-2]=1; } } //Rule R1 applied to a hybrid node and an arc public void ruleR1(int i,int ei, int ej) { //1 recomb node is attached below hybrid node i and arc e=(ei,ej) adj[ei][ej]=adj[ei][ej]-1; adj[ei][v-2]=1; adj[v-2][ej]=1; adj[v-2][v-1]=1; adj[i][v-1]=1; } //Rule R2 applied to a hybrid node and an arc public void ruleR2(int i,int ei, int ej) { //1 recomb node is inserted below hybrid node i inside arc e=(ei,ej) adj[ei][ej]=adj[ei][ej]-1; adj[ei][v-1]=1; adj[v-1][ej]=1; adj[i][v-1]=1; } //Rule R1 applied to 2 different hybrid nodes public void ruleR1(int i, int j) { //1 recomb node is attached below 2 hybrid nodes adj[i][v-1]=1; adj[j][v-1]=1; } }