def _layout(self): self._initialize() # order the nodes ordered_nodes = CFGUtils.quasi_topological_sort_nodes(self.graph) # conver the graph to an acylic graph acyclic_graph = self._to_acyclic_graph(self.graph, ordered_nodes=ordered_nodes) # assign row and column to each node self._assign_grid_locations(self.graph, acyclic_graph, ordered_nodes=ordered_nodes) # edge routing edge_router = EdgeRouter(self.graph, self._cols, self._rows, self._locations, self._max_col, self._max_row) self.edges = edge_router.edges self._vertical_edges = edge_router.vertical_edges self._horizontal_edges = edge_router.horizontal_edges # determine the maximum index for each grid self._set_max_grid_edge_id() # determine row and column sizes self._make_grids() # calculate coordinates of nodes self._calculate_coordinates()
def _to_acyclic_graph(self, graph, ordered_nodes=None): """ Convert a given DiGraph into an acyclic graph. :param networkx.DiGraph graph: The graph to convert. :param list ordered_nodes: A list of nodes sorted in a topological order. :return: The converted acyclic graph. """ if ordered_nodes is None: # take the quasi-topological order of the graph ordered_nodes = CFGUtils.quasi_topological_sort_nodes(graph) acyclic_graph = networkx.DiGraph() # add each node and its edge into the graph visited = set() for node in ordered_nodes: visited.add(node) acyclic_graph.add_node(node) for successor in graph.successors(node): if successor not in visited: acyclic_graph.add_edge(node, successor) return acyclic_graph
def sort_nodes(self, nodes=None): sorted_nodes = CFGUtils.quasi_topological_sort_nodes(self.cfg.graph) if nodes is not None: sorted_nodes = [n for n in sorted_nodes if n in set(nodes)] return sorted_nodes
def _assign_grid_locations(self, graph, acyclic_graph, ordered_nodes=None): """ Assign locations to each node in the graph in a bottom-up manner. :param networkx.DiGraph graph: The original graph. :param networkx.DiGraph acyclic_graph: The acyclic graph to work on. :param list ordered_nodes: A list of nodes sorted in a topological order. :return: None """ if ordered_nodes is None: # take the quasi-topological order of the graph ordered_nodes = CFGUtils.quasi_topological_sort_nodes(acyclic_graph) self._assign_rows(graph, acyclic_graph, ordered_nodes) self._assign_columns(acyclic_graph)