class_docstr: Edmonds algorithm [1]_ for finding optimal branchings and spanning
  arborescences.
  
  This algorithm can find both minimum and maximum spanning arborescences and
  branchings.
  
  Notes
  -----
  While this algorithm can find a minimum branching, since it isn't required
  to be spanning, the minimum branching is always from the set of negative
  weight edges which is most likely the empty set for most graphs.
  
  References
  ----------
  .. [1] J. Edmonds, Optimum Branchings, Journal of Research of the National
         Bureau of Standards, 1967, Vol. 71B, p.233-240,
         https://archive.org/details/jresv71Bn4p233
docstr: So we need the code in _init and find_optimum to successfully run edmonds algorithm.
  Responsibilities of the _init function:
  - Check that the kind argument is in {min, max} or raise a NetworkXException.
  - Transform the graph if we need a minimum arborescence/branching.
    - The current method is to map weight -> -weight. This is NOT a good approach since
      the algorithm can and does choose to ignore negative weights when creating a branching
      since that is always optimal when maximzing the weights. I think we should set the edge
      weights to be (max_weight + 1) - edge_weight.
  - Transform the graph into a MultiDiGraph, adding the partition information and potoentially
    other edge attributes if we set preserve_attrs = True.
  - Setup the buckets and union find data structures required for the algorithm.
code: def _init(
      self, attr, default, kind, style, preserve_attrs, seed, partition
  ):
      """
      So we need the code in _init and find_optimum to successfully run edmonds algorithm.
      Responsibilities of the _init function:
      - Check that the kind argument is in {min, max} or raise a NetworkXException.
      - Transform the graph if we need a minimum arborescence/branching.
        - The current method is to map weight -> -weight. This is NOT a good approach since
          the algorithm can and does choose to ignore negative weights when creating a branching
          since that is always optimal when maximzing the weights. I think we should set the edge
          weights to be (max_weight + 1) - edge_weight.
      - Transform the graph into a MultiDiGraph, adding the partition information and potoentially
        other edge attributes if we set preserve_attrs = True.
      - Setup the buckets and union find data structures required for the algorithm.
      """
      if kind not in KINDS:
          raise nx.NetworkXException("Unknown value for `kind`.")
  
      # Store inputs.
      self.attr = attr
      self.default = default
      self.kind = kind
      self.style = style
  
      # Determine how we are going to transform the weights.
      if kind == "min":
          self.trans = trans = _min_weight
      else:
          self.trans = trans = _max_weight
  
      if attr is None:
          # Generate a random attr the graph probably won't have.
          attr = random_string(seed=seed)
  
      # This is the actual attribute used by the algorithm.
      self._attr = attr
  
      # This attribute is used to store whether a particular edge is still
      # a candidate. We generate a random attr to remove clashes with
      # preserved edges
      self.candidate_attr = "candidate_" + random_string(seed=seed)
  
      # The object we manipulate at each step is a multidigraph.
      self.G = G = MultiDiGraph_EdgeKey()
      for key, (u, v, data) in enumerate(
          self.G_original.edges(data=True)
      ):
          d = {attr: trans(data.get(attr, default))}
  
          if data.get(partition) is not None:
              d[partition] = data.get(partition)
  
          if preserve_attrs:
              for d_k, d_v in data.items():
                  if d_k != attr:
                      d[d_k] = d_v
  
          G.add_edge(u, v, key, **d)
  
      self.level = 0
  
      # These are the "buckets" from the paper.
      #
      # As in the paper, G^i are modified versions of the original graph.
      # D^i and E^i are nodes and edges of the maximal edges that are
      # consistent with G^i. These are dashed edges in figures A-F of the
      # paper. In this implementation, we store D^i and E^i together as a
      # graph B^i. So we will have strictly more B^i than the paper does.
      self.B = MultiDiGraph_EdgeKey()
      self.B.edge_index = {}
      self.graphs = []  # G^i
      self.branchings = []  # B^i
      self.uf = nx.utils.UnionFind()
  
      # A list of lists of edge indexes. Each list is a circuit for graph G^i.
      # Note the edge list will not, in general, be a circuit in graph G^0.
      self.circuits = []
      # Stores the index of the minimum edge in the circuit found in G^i
      # and B^i. The ordering of the edges seems to preserve the weight
      # ordering from G^0. So even if the circuit does not form a circuit
      # in G^0, it is still true that the minimum edge of the circuit in
      # G^i is still the minimum edge in circuit G^0 (despite their weights
      # being different).
      self.minedge_circuit = []
  
imports: import string
  from dataclasses import dataclass, field
  from enum import Enum
  from operator import itemgetter
  from queue import PriorityQueue
  import networkx
  from networkx.utils import py_random_state
  from .recognition import is_arborescence, is_branching
label_desc: Use image node_id 2 for calling the Edmonds obj's underlying member method code with example usage: obj._init(attr, default, kind, style, preserve_attrs, seed, partition) without return types