public int topDownUnorderedMaxCommonSubtreeIso(Node r1, Node r2) { //Cannot find a isomophism when the labels differ if (r1.getId() != r2.getId()) { return(0); } //The isomorphism has size 0 or 1 if one of the nodes are leaf nodes if (r1.isLeaf() || r2.isLeaf()) { return((r1.getId() == r2.getId()) ? 1 : 0); } int result; Node rp1 = r1.Parent; Node rp2 = r2.Parent; //Use LCS if r1 and r2 are root nodes in subtrees that represents method bodies. if ((rp1 != null && r1.getId() == SyntaxKind.Block && rp1.getId() == SyntaxKind.MethodDeclaration) && (rp2 != null && r2.getId() == SyntaxKind.Block && rp2.getId() == SyntaxKind.MethodDeclaration)) { int res = lcs(r1, r2); result = res; } else { int p = r1.Size; int q = r2.Size; //Each child of r1 has a corresponding vertex in the bipartite graph. A map from node to vertex. Dictionary <Node, Vertex> T1G = new Dictionary <Node, Vertex>(p); //Each child of r2 has a corresponding vertex in the bipartite graph. A map from node to vertex. Dictionary <Node, Vertex> T2G = new Dictionary <Node, Vertex>(q); //A map from vertex to node. Dictionary <Vertex, Node> GT = new Dictionary <Vertex, Node>(p + q); //There is maximum p*q edges in the bipartite graph. List <Edge> edges = new List <Edge>(p * q); //The vertices that represents the children of r1. List <Vertex> U = new List <Vertex>(p); foreach (Node v1 in r1.Children) { //q is the number of neighbors that v can have in the bipartite graph. Vertex v = new Vertex(q); U.Add(v); GT.Add(v, v1); T1G.Add(v1, v); } //The vertices that represents the children of r2. List <Vertex> W = new List <Vertex>(q); foreach (Node v2 in r2.Children) { //p is the number of neighbors that w can have in the bipartite graph. Vertex w = new Vertex(p); W.Add(w); GT.Add(w, v2); T2G.Add(v2, w); } //List of matched edges List <Edge> list = null; foreach (Node v1 in r1.Children) { foreach (Node v2 in r2.Children) { //Find max common subtree between v1 and v2 int res = topDownUnorderedMaxCommonSubtreeIso(v1, v2); //If max common subtree if (res != 0) { Vertex v = T1G[v1]; //Insert edge between v1 and v2 Edge e = v.insertEdge(T2G[v2]); //Set cost of edge to res (size of max common subtree) e.setCost(res); edges.Add(e); } } } //Find the children of r1 and r2 that are part of r1's and r2's max common subtree BipartiteMatching bm = new BipartiteMatching(); list = bm.maxWeightBipartiteMatching(U, W, edges, p, q); //Can map r1 to r2 int ress = 1; //Go through the mached edges in the bipartite graph foreach (Edge e in list) { List <Node> nodeList; //All edges goes from the children of r1 to the children of r2 Node v = GT[e.getSource()]; Node w = GT[e.getTarget()]; //v is already in B if (bMap.ContainsKey(v)) { nodeList = bMap[v]; } //First time we insert v. Create a list for the nodes that can be mapped to v. else { nodeList = new List <Node>(100); } //Insert w into the list nodeList.Add(w); bMap[v] = nodeList; //Add the size of the max common subtree between v and w to res. ress += e.getCost(); } result = ress; } return(result); }
public int topDownUnorderedMaxCommonSubtreeIso(Node r1, Node r2) { //Cannot find a isomophism when the labels differ if (r1.getId() != r2.getId()) { return 0; } //The isomorphism has size 0 or 1 if one of the nodes are leaf nodes if (r1.isLeaf() || r2.isLeaf()) { return (r1.getId() == r2.getId()) ? 1 : 0; } int result; Node rp1 = r1.Parent; Node rp2 = r2.Parent; //Use LCS if r1 and r2 are root nodes in subtrees that represents method bodies. if ((rp1 != null && r1.getId() == SyntaxKind.Block && rp1.getId() == SyntaxKind.MethodDeclaration) && (rp2 != null && r2.getId() == SyntaxKind.Block && rp2.getId() == SyntaxKind.MethodDeclaration)) { int res = lcs(r1, r2); result = res; } else { int p = r1.Size; int q = r2.Size; //Each child of r1 has a corresponding vertex in the bipartite graph. A map from node to vertex. Dictionary<Node, Vertex> T1G = new Dictionary<Node, Vertex>(p); //Each child of r2 has a corresponding vertex in the bipartite graph. A map from node to vertex. Dictionary<Node, Vertex> T2G = new Dictionary<Node, Vertex>(q); //A map from vertex to node. Dictionary<Vertex, Node> GT = new Dictionary<Vertex, Node>(p + q); //There is maximum p*q edges in the bipartite graph. List<Edge> edges = new List<Edge>(p * q); //The vertices that represents the children of r1. List<Vertex> U = new List<Vertex>(p); foreach (Node v1 in r1.Children) { //q is the number of neighbors that v can have in the bipartite graph. Vertex v = new Vertex(q); U.Add(v); GT.Add(v, v1); T1G.Add(v1, v); } //The vertices that represents the children of r2. List<Vertex> W = new List<Vertex>(q); foreach (Node v2 in r2.Children) { //p is the number of neighbors that w can have in the bipartite graph. Vertex w = new Vertex(p); W.Add(w); GT.Add(w, v2); T2G.Add(v2, w); } //List of matched edges List<Edge> list = null; foreach (Node v1 in r1.Children) { foreach (Node v2 in r2.Children) { //Find max common subtree between v1 and v2 int res = topDownUnorderedMaxCommonSubtreeIso(v1, v2); //If max common subtree if (res != 0) { Vertex v = T1G[v1]; //Insert edge between v1 and v2 Edge e = v.insertEdge(T2G[v2]); //Set cost of edge to res (size of max common subtree) e.setCost(res); edges.Add(e); } } } //Find the children of r1 and r2 that are part of r1's and r2's max common subtree BipartiteMatching bm = new BipartiteMatching(); list = bm.maxWeightBipartiteMatching(U, W, edges, p, q); //Can map r1 to r2 int ress = 1; //Go through the mached edges in the bipartite graph foreach (Edge e in list) { List<Node> nodeList; //All edges goes from the children of r1 to the children of r2 Node v = GT[e.getSource()]; Node w = GT[e.getTarget()]; //v is already in B if (bMap.ContainsKey(v)) { nodeList = bMap[v]; } //First time we insert v. Create a list for the nodes that can be mapped to v. else { nodeList = new List<Node>(100); } //Insert w into the list nodeList.Add(w); bMap[v] = nodeList; //Add the size of the max common subtree between v and w to res. ress += e.getCost(); } result = ress; } return result; }