private void DetermineFollowNodesInSubGraph(ILogicalConstruct theGraph) { this.GetVerticesAndAdjacencyMatrix(theGraph); V_0 = MaxWeightDisjointPathsFinder.GetOptimalEdgesInDAG(this.adjacencyMatrix).GetEnumerator(); try { while (V_0.MoveNext()) { V_1 = V_0.get_Current(); this.orderedVertexArray[V_1.get_Key()].set_CFGFollowNode(this.orderedVertexArray[V_1.get_Value()].get_FirstBlock()); if (this.orderedVertexArray[V_1.get_Key()] as ConditionLogicalConstruct == null) { continue; } V_2 = this.orderedVertexArray[V_1.get_Key()] as ConditionLogicalConstruct; if (V_2.get_CFGFollowNode() != V_2.get_TrueCFGSuccessor()) { continue; } V_2.Negate(this.typeSystem); } } finally { ((IDisposable)V_0).Dispose(); } return; }
/// <summary> /// Determines the follow nodes in the given subgraph. /// </summary> /// <remarks> /// Every node can follow only one node. /// Everey node can be followed by only one node. /// The follow node relation cannot form a back edge. (i.e. B can be the follow node of A <=> (A, B) is not a backedge) /// Let G = (V, E) be the original graph. /// Let G' = (V, E') be the subgraph of G, where E' = E \ { e | e is from E && e is backedge in the DFS traversal }. /// /// The solution is to find a cover of vertex-disjoint paths of G' that will yield the minimum number of gotos. /// The gotos will be the edges that are not in the cover. So we want the edges that will yeild the greatest number of gotos to /// be in the cover. If we find a good weight function for the edges in the graph (i.e. correctly determines how much gotos there will be between /// two nodes), then all we have to do is find a cover of vertex-disjoint paths of G' with maximum total weight. /// </remarks> /// <param name="theGraph"></param> private void DetermineFollowNodesInSubGraph(ILogicalConstruct theGraph) { //Creates the adjacency matrix for the mentioned subgraph - G'. GetVerticesAndAdjacencyMatrix(theGraph); //Since no back edge is left in G', then G' is a DAG. List <KeyValuePair <int, int> > followEdges = MaxWeightDisjointPathsFinder.GetOptimalEdgesInDAG(adjacencyMatrix); foreach (KeyValuePair <int, int> followEdge in followEdges) { orderedVertexArray[followEdge.Key].CFGFollowNode = orderedVertexArray[followEdge.Value].FirstBlock; if (orderedVertexArray[followEdge.Key] is ConditionLogicalConstruct) { ConditionLogicalConstruct theCondition = orderedVertexArray[followEdge.Key] as ConditionLogicalConstruct; if (theCondition.CFGFollowNode == theCondition.TrueCFGSuccessor) { //If the follow node of a condition construct is the true successor, then we need to negate the condition construct. theCondition.Negate(typeSystem); } } } }
/// <summary> /// Finds the optimal vertex-disjoint path cover of maximum total weight of the given directed acyclic graph. /// </summary> /// <remarks> /// Let G = (V, E) be the graph represented by the specified <paramref name="adjacencyMatrix"/>, with weight function - W((vi, vj)) = adjacencyMatrix[i, j]. /// Let Gb = (X, Y, Eb) is a bipartite graph where: /// X = { xi | vi from V }, Y = { yi | vi from V } /// Eb = { (xi, yj) | (vi, vj) from E } /// Wb((xi, yj)) = W((vi, vj)) for each (vi, vj) from E /// /// As stated in chapter 4 in "Approximation Algorithms for Covering a Graph by Vertex-Disjoint Paths of Maximum Total Weight": /// The problem of findig the vertex-disjoint path cover of maximum total weight of G, /// can be reduced to the problem of finding a maximum weight bipartite matching of Gb. /// Since G is a DAG then the produced cover will be optimal. (mentioned at end of chapter 4) /// /// Implementation details: /// In the implementation of the algorithms below we often need a set of all of the nodes of the graph. /// So we define the set Z with the following properties: /// |V| = |X| = |Y| = n /// Z = { zi | xi from X } U { z(i + n) | yi from Y } /// </remarks> /// <param name="adjacencyMatrix"></param> /// <returns></returns> public static List<KeyValuePair<int, int>> GetOptimalEdgesInDAG(int[,] adjacencyMatrix) { MaxWeightDisjointPathsFinder pathsFinder = new MaxWeightDisjointPathsFinder(adjacencyMatrix); return pathsFinder.MaximumWeightBipartiteGraphMatching(); }
/// <summary> /// Finds the optimal vertex-disjoint path cover of maximum total weight of the given directed acyclic graph. /// </summary> /// <remarks> /// Let G = (V, E) be the graph represented by the specified <paramref name="adjacencyMatrix"/>, with weight function - W((vi, vj)) = adjacencyMatrix[i, j]. /// Let Gb = (X, Y, Eb) is a bipartite graph where: /// X = { xi | vi from V }, Y = { yi | vi from V } /// Eb = { (xi, yj) | (vi, vj) from E } /// Wb((xi, yj)) = W((vi, vj)) for each (vi, vj) from E /// /// As stated in chapter 4 in "Approximation Algorithms for Covering a Graph by Vertex-Disjoint Paths of Maximum Total Weight": /// The problem of findig the vertex-disjoint path cover of maximum total weight of G, /// can be reduced to the problem of finding a maximum weight bipartite matching of Gb. /// Since G is a DAG then the produced cover will be optimal. (mentioned at end of chapter 4) /// /// Implementation details: /// In the implementation of the algorithms below we often need a set of all of the nodes of the graph. /// So we define the set Z with the following properties: /// |V| = |X| = |Y| = n /// Z = { zi | xi from X } U { z(i + n) | yi from Y } /// </remarks> /// <param name="adjacencyMatrix"></param> /// <returns></returns> public static List <KeyValuePair <int, int> > GetOptimalEdgesInDAG(int[,] adjacencyMatrix) { MaxWeightDisjointPathsFinder pathsFinder = new MaxWeightDisjointPathsFinder(adjacencyMatrix); return(pathsFinder.MaximumWeightBipartiteGraphMatching()); }