Ejemplo n.º 1
0
    def gather_pairs(self, start_obj):  # bit slow
        """
        Gather all connected pairs of nodes in a graph, going forward, and backward if reverse_name is defined.
        """
        get_id = self._get_id

        forw_iterator = Iterator(self.name)
        back_iterator = Iterator(
            self.reverse_name) if self.reverse_name else None

        gathered = set()
        queue = deque([start_obj])
        pairs = []

        while len(queue):
            obj = queue.popleft()

            for forw_obj in forw_iterator.iter_object(obj):
                key = (get_id(obj), get_id(forw_obj))
                if key not in gathered:
                    pairs.append((obj, forw_obj))
                    queue.append(forw_obj)
                gathered.add(key)

            if back_iterator:
                for back_obj in back_iterator.iter_object(obj):
                    key = (get_id(back_obj), get_id(obj))
                    if key not in gathered:
                        pairs.append((back_obj, obj))
                        queue.append(back_obj)
                    gathered.add(key)
        return pairs
Ejemplo n.º 2
0
    def gather(self, start_obj):  # bit slow
        """
        Gather all nodes in a graph, going forward and backward if reverse_name is defined.
        """
        get_id = self._get_id

        forw_iterator = Iterator(self.name)
        back_iterator = Iterator(
            self.reverse_name) if self.reverse_name else None

        gathered = {}
        queue = deque([start_obj])
        while len(queue):
            obj = queue.popleft()
            gathered[get_id(obj)] = obj

            for forw_obj in forw_iterator.iter_object(obj):
                if get_id(forw_obj) not in gathered:
                    queue.append(forw_obj)

            if back_iterator:
                for back_obj in back_iterator.iter_object(obj):
                    if get_id(back_obj) not in gathered:
                        queue.append(back_obj)

        return list(gathered.values())
Ejemplo n.º 3
0
 def reachable(self, start_obj, target_obj):
     """ return whether target_obj can be reached from start_obj through the graph """
     iterator = Iterator(self.name)
     for obj in iterator(start_obj):
         if target_obj in iterator.iter_object(obj):
             return True
     return False
Ejemplo n.º 4
0
 def endpoints(self, start_obj):
     """ return a list of endpoint nodes (with no next node in the graph), starting from start_obj"""
     endpoints = []
     iterator = Iterator(self.name)
     for obj in iterator(start_obj):
         if not list(iterator.iter_object(obj)):
             endpoints.append(obj)
     return endpoints
Ejemplo n.º 5
0
 def walk(self, start_obj, key, on_visit=None):
     """
     iterate through the graph, with a key function selecting the next connected node
     :param start_obj: starting point in the graph
     :param key: function to pick the next node in the graph, as in 'next_node = key(node)'
     :param on_visit: optional callback applied to the visited node
     :return: yield nodes encountered in the graph one-by-one
     """
     yield from Iterator(self.name).walk(start_obj,
                                         key=key,
                                         on_visit=on_visit)
Ejemplo n.º 6
0
 def iterate(self, start_obj, cyclic=False, breadth_first=False):
     """
     iterate through the graph
     :param start_obj: starting object from which the graph is followed
     :param cyclic: whether nodes in the graph will be repeated
     :param breadth_first: depth_first iteration if false (default) else breadth_first iteration
     :yield: nodes in the graph
     """
     yield from Iterator(self.name).iterate(start_obj,
                                            cyclic=cyclic,
                                            breadth_first=breadth_first)
Ejemplo n.º 7
0
 def shortest_path(self,
                   start_obj,
                   target_obj,
                   get_cost=None,
                   heuristic=None):
     """
      Finds the shortest path through the graph from start_obj to target_obj
     :param start_obj: node to start from
     :param target_obj: node to which the path must be calculated
     :param get_cost(node, next_node): cost function: must return cost for following edge between node and next_node. Default
         results in a shortest path defined by the number of edges between start and end.
     :param heuristic(node, target_node): optional heuristic function to calculate an under estimate of the remaining
         cost from a node to the target node (often resulting in faster path_finding, using A*).
     :return: list of nodes of the shortest path
     """
     return Iterator(self.name).shortest_path(start_obj,
                                              target_obj,
                                              get_cost=get_cost,
                                              heuristic=heuristic)