def assert_model_graph_structure(G): """ verification on the structure of the graph """ # only one terminal node if len(gh.get_terminal_nodes(G)) != 1: raise ValueError("I should have only one terminal node") # connex graph if not gh.is_connected(G): raise ValueError("the graph should be connected") # no cycle if gh.has_cycle(G): raise ValueError("The graph shouldn't have any cycle") for node in G.nodes: if is_composition_model(node): successors = list(G.successors(node)) if len(successors) == 0: raise ValueError("Composition node %s has no successor" % str(node)) for successor in successors: predecessors = list(G.predecessors(successor)) if predecessors != [node]: raise ValueError( "The node %s has more than one parent, which is impossible for a child of a composition node (%s)" % (str(successor), str(node)))
def assert_model_graph_structure(G): """ verification on the structure of the graph """ # only one terminal node if len(gh.get_terminal_nodes(G)) != 1: raise ValueError("I should have only one terminal node") # connex graph if not gh.is_connected(G): raise ValueError("the graph should be connected") # no cycle if gh.has_cycle(G): raise ValueError("The graph shouldn't have any cycle") for node in G.nodes: if StepCategories.is_composition_step(node[0]): if len(list(G.successors(node))) == 0: raise ValueError("Composition node %s has no successor" % node) for node in G.nodes: if StepCategories.is_composition_step(node[0]): successors = gh.get_all_successors(G, node) predecessors = gh.get_all_predecessors(G, node) if not gh.is_it_a_partition(list(G.nodes), [successors, [node], predecessors]): raise ValueError("Incorrect split around composition node %s" % node)
def test_has_cycle(): G = graph_from_edges_string("A - B - C; D - C") assert not has_cycle(G) G = graph_from_edges_string("A - B - C - A") assert has_cycle(G)
def register_new_class(self, category, klass, hyper=None, default_hyper=None, is_allowed=None, depends_on=None, **kwargs): if not isinstance(klass, type): raise TypeError("klass should be klass") key = category, klass.__name__ if key in self.all_registered: raise ValueError("%s has already been registered" % str(key)) self.all_registered.append(key) self.init_parameters[key] = get_init_parameters(klass) if hyper is not None: self.hyper_parameters[key] = hyper if default_hyper is not None: self.default_hyper_parameters[key] = default_hyper if is_allowed is not None: self.is_allowed[key] = is_allowed if kwargs: self.informations[key] = {k: v for k, v in kwargs.items()} if klass.__name__ not in DICO_NAME_KLASS._mapping: raise ValueError( "You should also register that klass : %s within the 'simple register' file" % klass.__name__) self.step_dependencies.add_node(category) if depends_on is not None: if not isinstance(depends_on, (list, tuple, set)): depends_on = (depends_on, ) for depending_step in depends_on: if depending_step not in StepCategories.alls: raise ValueError(f"{depending_step} is not a know step") self.step_dependencies.add_edge(depending_step, category) if has_cycle(self.step_dependencies): raise ValueError( f"adding this dependency {depending_step} -> {category} create a cycle" ) self._drawing_order = { step: n for n, step in enumerate(iter_graph( self.step_dependencies)) } return self