class_docstr: Breadth First sampler that generates the composite of a number of sampled paths from a starting node.
  It can be used to extract a random sub-graph starting from a set of initial nodes.
class_docstr_tok: ["Breadth","First","sampler","that","generates","the","composite","of","a","number","of","sampled","paths","from","a","starting","node",".","It","can","be","used","to","extract","a","random","sub-graph","starting","from","a","set","of","initial","nodes","."]
docstr: Performs a sampled breadth-first walk starting from the root nodes.
  
  Args:
      nodes (list): A list of root node ids such that from each node n BFWs will be generated up to the
      given depth d.
      in_size (int): The number of in-directed nodes to sample with replacement at each depth of the walk.
      out_size (int): The number of out-directed nodes to sample with replacement at each depth of the walk.
      n (int, default 1): Number of walks per node id.
      seed (int, optional): Random number generator seed; default is None
      weighted (bool, optional): If True, sample neighbours using the edge weights in the graph.
  
  
  Returns:
      A list of multi-hop neighbourhood samples. Each sample expresses multiple undirected walks, but the in-node
      neighbours and out-node neighbours are sampled separately. Each sample has the format:
  
          [[node]
           [in_1...in_n]  [out_1...out_m]
           [in_1.in_1...in_n.in_p] [in_1.out_1...in_n.out_q]
              [out_1.in_1...out_m.in_p] [out_1.out_1...out_m.out_q]
           [in_1.in_1.in_1...in_n.in_p.in_r] [in_1.in_1.out_1...in_n.in_p.out_s] ...
           ...]
  
      where a single, undirected walk might be, for example:
  
          [node out_i  out_i.in_j  out_i.in_j.in_k ...]
docstr_tok: ["Performs","a","sampled","breadth-first","walk","starting","from","the","root","nodes",".","Args",":","nodes","(","list",")",":","A","list","of","root","node","ids","such","that","from","each","node","n","BFWs","will","be","generated","up","to","the","given","depth","d.","in_size","(","int",")",":","The","number","of","in-directed","nodes","to","sample","with","replacement","at","each","depth","of","the","walk",".","out_size","(","int",")",":","The","number","of","out-directed","nodes","to","sample","with","replacement","at","each","depth","of","the","walk",".","n","(","int",",","default","1",")",":","Number","of","walks","per","node","id",".","seed","(","int",",","optional",")",":","Random","number","generator","seed",";","default","is","None","weighted","(","bool",",","optional",")",":","If","True",",","sample","neighbours","using","the","edge","weights","in","the","graph",".","Returns",":","A","list","of","multi-hop","neighbourhood","samples",".","Each","sample","expresses","multiple","undirected","walks",",","but","the","in-node","neighbours","and","out-node","neighbours","are","sampled","separately",".","Each","sample","has","the","format",":","[","[","node","]","[","in_1","...","in_n","]","[","out_1","...","out_m","]","[","in_1.in_1","...","in_n.in_p","]","[","in_1.out_1","...","in_n.out_q","]","[","out_1.in_1","...","out_m.in_p","]","[","out_1.out_1","...","out_m.out_q","]","[","in_1.in_1.in_1","...","in_n.in_p.in_r","]","[","in_1.in_1.out_1","...","in_n.in_p.out_s","]","...","...","]","where","a","single",",","undirected","walk","might","be",",","for","example",":","[","node","out_i","out_i.in_j","out_i.in_j.in_k","...","]"]
code: def run(
      self, nodes, in_size, out_size, n=1, seed=None, weighted=False
  ):
      """
      Performs a sampled breadth-first walk starting from the root nodes.
  
      Args:
          nodes (list): A list of root node ids such that from each node n BFWs will be generated up to the
          given depth d.
          in_size (int): The number of in-directed nodes to sample with replacement at each depth of the walk.
          out_size (int): The number of out-directed nodes to sample with replacement at each depth of the walk.
          n (int, default 1): Number of walks per node id.
          seed (int, optional): Random number generator seed; default is None
          weighted (bool, optional): If True, sample neighbours using the edge weights in the graph.
  
  
      Returns:
          A list of multi-hop neighbourhood samples. Each sample expresses multiple undirected walks, but the in-node
          neighbours and out-node neighbours are sampled separately. Each sample has the format:
  
              [[node]
               [in_1...in_n]  [out_1...out_m]
               [in_1.in_1...in_n.in_p] [in_1.out_1...in_n.out_q]
                  [out_1.in_1...out_m.in_p] [out_1.out_1...out_m.out_q]
               [in_1.in_1.in_1...in_n.in_p.in_r] [in_1.in_1.out_1...in_n.in_p.out_s] ...
               ...]
  
          where a single, undirected walk might be, for example:
  
              [node out_i  out_i.in_j  out_i.in_j.in_k ...]
      """
      self._check_neighbourhood_sizes(in_size, out_size)
      self._check_common_parameters(nodes, n, len(in_size), seed)
      py_and_np_rs = self._get_random_state(seed)
  
      max_hops = len(in_size)
      # A binary tree is a graph of nodes; however, we wish to avoid overusing the term 'node'.
      # Consider that each binary tree node carries some information.
      # We uniquely and deterministically number every node in the tree, so we
      # can represent the information stored in the tree via a flattened list of 'slots'.
      # Each slot (and corresponding binary tree node) now has a unique index in the flattened list.
      max_slots = 2 ** (max_hops + 1) - 1
  
      samples = []
  
      for node in nodes:  # iterate over root nodes
          for _ in range(
              n
          ):  # do n bounded breadth first walks from each root node
              q = list()  # the queue of neighbours
              # the list of sampled node-lists:
              sample = [[] for _ in range(max_slots)]
              # Add node to queue as (node, depth, slot)
              q.append((node, 0, 0))
  
              while len(q) > 0:
                  # remove the top element in the queue
                  # index 0 pop the item from the front of the list
                  cur_node, cur_depth, cur_slot = q.pop(0)
                  sample[cur_slot].append(cur_node)  # add to the walk
                  depth = (
                      cur_depth + 1
                  )  # the depth of the neighbouring nodes
  
                  # consider the subgraph up to and including max_hops from root node
                  if depth > max_hops:
                      continue
                  # get in-nodes
                  neighbours = self._sample_neighbours_untyped(
                      self.graph.in_node_arrays,
                      py_and_np_rs,
                      cur_node,
                      in_size[cur_depth],
                      weighted,
                  )
                  # add them to the back of the queue
                  slot = 2 * cur_slot + 1
                  q.extend(
                      [
                          (sampled_node, depth, slot)
                          for sampled_node in neighbours
                      ]
                  )
                  # get out-nodes
                  neighbours = self._sample_neighbours_untyped(
                      self.graph.out_node_arrays,
                      py_and_np_rs,
                      cur_node,
                      out_size[cur_depth],
                      weighted,
                  )
                  # add them to the back of the queue
                  slot = slot + 1
                  q.extend(
                      [
                          (sampled_node, depth, slot)
                          for sampled_node in neighbours
                      ]
                  )
  
              # finished multi-hop neighbourhood sampling
              samples.append(sample)
  
      return samples
  
imports: import numpy
  import warnings
  from collections import defaultdict, deque
  from scipy import stats
  from scipy.special import softmax
  from ..core.schema import GraphSchema
  from ..core.graph import StellarGraph
  from ..core.utils import is_real_iterable
  from ..core.validation import require_integer_in_range, comma_sep
  from ..random import random_state
  from abc import ABC, abstractmethod
label_desc: Use image node_id 2 for calling the DirectedBreadthFirstNeighbours obj's underlying member method code with example usage: obj.run(nodes, in_size, out_size, n, seed, weighted) and returns: samples