def strong_components(self): """ Generates sets containing the sets of nodes in each strongly connected component (U{http://mathworld.wolfram.com/StronglyConnectedComponent.html}). @rtype: C{generator} @return: a generator of sets of nodes for each strongly connected component """ import traversals visited = set() order = list(traversals.dfs(self, post=True)) top_order = reversed(order) for node in top_order: if not node in visited: component = set() for node in traversals.dfs(self, node, pre=True, adj=self.parents): if not node in visited: component.add(node) visited.add(node) yield component
def flatten(self): # flatten the structure (in place) so that # all nodes are either leaf or parents of leaf nodes for node in dfs(self, post=True): grand_children = set() for child in list(self.children[node]): if self.outdegree(child): self.del_edge((node, child)) grand_children |= self.children[child] for gc in grand_children: self.add_edge((node, gc))
def structure_is_valid(self): # the induced graph containing the nodes reachable from # each root should be a tree for root in self.root_nodes: visited = set() num_edges = 0 num_nodes = 0 for node in dfs(self, root, post=True): num_nodes += 1 num_edges += self.outdegree(node) if not num_nodes == num_edges + 1: return False return True
def deepen(self): # deepen structure (in place) to provide # nicer layout for humans for node in list(dfs(self, post=True)): children = list(self.children[node]) if children: it = iter(children) new_parents = set(self.parents[next(it)]) new_parents.remove(node) for child in it: if not new_parents: break new_parents &= self.parents[child] for p in new_parents: for child in children: self.del_edge((p, child)) self.add_edge((p, node))
def reachable(self, node): # return a generator of the leaf # nodes reachable from node for n in dfs(self, node, post=True): if not self.children[n]: yield n
from content import distances, city_adjacency from traversals import dfs, bfs, iter_deep_dfs, bidir_search, \ greedily_best_first_search, min_sum_estimation, informational_search from decision_tree import visualize, make_dot_file start = "Харьков" end = "Ниж.Новгород" print('__Неинформированный поиск__') # DFS dfs_dist, dfs_way = dfs(city_adjacency, start, end) print(f'DFS:\t\t\t\t\t\t{dfs_dist, dfs_way}') # BFS bfs_dist, bfs_way = bfs(city_adjacency, start, end) print(f'BFS:\t\t\t\t\t\t{bfs_dist, bfs_way}') # с ограничением глубины: max_depth = 7 md_dfs_dist, md_dfs_way = dfs(city_adjacency, start, end, max_depth=max_depth) print(f'DFS with max_depth of {max_depth}:\t{md_dfs_dist, md_dfs_way}') # с итеративным углублением id_dfs_dist, id_dfs_way = iter_deep_dfs(city_adjacency, start, end) print(f'Iteration deepening:\t\t{id_dfs_dist, id_dfs_way}') # с двунаправленным поиском bds_dist, bds_way = bidir_search(city_adjacency, start, end) print(f'Bidirectional search:\t\t{bds_dist, bds_way}') print('__Информативный поиск__') # жадный поиск по первому наилучшему соответствию gbfs_dist, gbfs_way = informational_search(greedily_best_first_search, city_adjacency, distances, start,