code: function networkSimplex(g) {
    g = simplify(g);
    initRank(g);
    var t = feasibleTree(g);
    initLowLimValues(t);
    initCutValues(t, g);
  
    var e, f;
    while ((e = leaveEdge(t))) {
      f = enterEdge(t, g, e);
      exchangeEdges(t, g, e, f);
    }
  }
docs: /*
  The network simplex algorithm assigns ranks to each node in the input graph
  and iteratively improves the ranking to reduce the length of edges.
  
  Preconditions:
  
  1. The input graph must be a DAG.
  2. All nodes in the graph must have an object value.
  3. All edges in the graph must have "minlen" and "weight" attributes.
  
  Postconditions:
  
  1. All nodes in the graph will have an assigned "rank" attribute that has
  been optimized by the network simplex algorithm. Ranks start at 0.
  
  
  A rough sketch of the algorithm is as follows:
  
  1. Assign initial ranks to each node. We use the longest path algorithm,
  which assigns ranks to the lowest position possible. In general this
  leads to very wide bottom ranks and unnecessarily long edges.
  2. Construct a feasible tight tree. A tight tree is one such that all
  edges in the tree have no slack (difference between length of edge
  and minlen for the edge). This by itself greatly improves the assigned
  rankings by shorting edges.
  3. Iteratively find edges that have negative cut values. Generally a
  negative cut value indicates that the edge could be removed and a new
  tree edge could be added to produce a more compact graph.
  
  Much of the algorithms here are derived from Gansner, et al., "A Technique
  for Drawing Directed Graphs." The structure of the file roughly follows the
  structure of the overall algorithm.