class_docstr: A connected graph of Vertex/Edge objects. A GraphBase is a *component* of a Graph that contains a connected set of Vertex and Edges.
  
  Attributes:
      verticesPoset (Poset[Vertex]): the partially ordered set of vertices of the graph.
      edgesPoset (Poset[Edge]): the partially ordered set of edges of the graph.
      loops (set[Edge]): the set of *loop* edges (of degree 0).
      directed (bool): indicates if the graph is considered *oriented* or not.
class_docstr_tok: ["A","connected","graph","of","Vertex\/Edge","objects",".","A","GraphBase","is","a","*","component","*","of","a","Graph","that","contains","a","connected","set","of","Vertex","and","Edges",".","Attributes",":","verticesPoset","(","Poset","[","Vertex","]",")",":","the","partially","ordered","set","of","vertices","of","the","graph",".","edgesPoset","(","Poset","[","Edge","]",")",":","the","partially","ordered","set","of","edges","of","the","graph",".","loops","(","set","[","Edge","]",")",":","the","set","of","*","loop","*","edges","(","of","degree","0",")",".","directed","(","bool",")",":","indicates","if","the","graph","is","considered","*","oriented","*","or","not","."]
docstr:     Minimum FAS algorithm (feedback arc set) creating a DAG. Returns the set of strongly connected components
      ("scs") by using Tarjan algorithm. These are maximal sets of vertices such that there is a path from each vertex to every other vertex.
      The algorithm performs a DFS from the provided list of root vertices. A cycle is of course a strongly connected component,but a strongly connected component can include several cycles.
      The Feedback Acyclic Set of edge to be removed/reversed is provided by marking the edges with a "feedback" flag.
      Complexity is O(V+E).
  
  :param roots:
  :return:
docstr_tok: ["Minimum","FAS","algorithm","(","feedback","arc","set",")","creating","a","DAG",".","Returns","the","set","of","strongly","connected","components","(","``","scs","''",")","by","using","Tarjan","algorithm",".","These","are","maximal","sets","of","vertices","such","that","there","is","a","path","from","each","vertex","to","every","other","vertex",".","The","algorithm","performs","a","DFS","from","the","provided","list","of","root","vertices",".","A","cycle","is","of","course","a","strongly","connected","component",",","but","a","strongly","connected","component","can","include","several","cycles",".","The","Feedback","Acyclic","Set","of","edge","to","be","removed\/reversed","is","provided","by","marking","the","edges","with","a","``","feedback","''","flag",".","Complexity","is","O","(","V+E",")",".",":","param","roots",":",":","return",":"]
code: def get_scs_with_feedback(self, roots=None):
      """
          Minimum FAS algorithm (feedback arc set) creating a DAG. Returns the set of strongly connected components
          ("scs") by using Tarjan algorithm. These are maximal sets of vertices such that there is a path from each vertex to every other vertex.
          The algorithm performs a DFS from the provided list of root vertices. A cycle is of course a strongly connected component,but a strongly connected component can include several cycles.
          The Feedback Acyclic Set of edge to be removed/reversed is provided by marking the edges with a "feedback" flag.
          Complexity is O(V+E).
  
      :param roots:
      :return:
      """
  
      from sys import getrecursionlimit, setrecursionlimit
      from .vertex import Vertex
  
      limit = getrecursionlimit()
      edge_poset_count = self.norm() + 10
      if edge_poset_count > limit:
          setrecursionlimit(edge_poset_count)
  
      def visitor(v, coll):
          v.ind = v.ncur
          v.low_link = v.ncur
          Vertex.ncur += 1
          self.stack.append(v)
          v.mark = True
          for e in v.e_out():
              w = e.v[1]
              if w.ind == 0:
                  visitor(w, coll)
                  v.low_link = min(v.low_link, w.low_link)
              elif w.mark:
                  e.feedback = True
              if w in self.stack:
                  v.low_link = min(v.low_link, w.ind)
          if v.low_link == v.ind:
              q = [self.stack.pop()]
              while q[0] != v:
                  q.insert(0, self.stack.pop())
              coll.append(q)
          v.mark = False
  
      if roots is None:
          roots = self.roots()
      self.stack = []
      flipped_edges = []
      Vertex.ncur = 1
      for v in self.verticesPoset:
          v.ind = 0
      # start exploring tree from roots:
      for v in roots:
          v = self.verticesPoset.get(v)
          if v.ind == 0:
              visitor(v, flipped_edges)
      # now possibly unvisited vertices:
      for v in self.verticesPoset:
          if v.ind == 0:
              visitor(v, flipped_edges)
      # clean up Tarjan-specific data:
      for v in self.verticesPoset:
          del v.ind
          del v.low_link
          del v.mark
      del Vertex.ncur
      del self.stack
      setrecursionlimit(limit)
      return flipped_edges
  
imports: from graphistry.layout.utils import Poset
label_desc: Use image node_id 20 for calling the GraphBase obj's underlying member method code with example usage: obj.get_scs_with_feedback(roots) and returns: flipped_edges