# HG changeset patch
# User Nathann Cohen
# Date 1365581838 7200
# Node ID 55162ee978f3fee3c4cf0b11fc74f91ad806c3a0
# Parent d6beda1cb55b76c26ba6167d653882eec02b5cbd
Move digraph.feedback_vertex_set to generic_digraph.py
diff git a/sage/graphs/digraph.py b/sage/graphs/digraph.py
 a/sage/graphs/digraph.py
+++ b/sage/graphs/digraph.py
@@ 1592,210 +1592,6 @@
return [(u,v) for (u,v) in self.edges(labels=None) if b_sol[(u,v)]==1]
 def feedback_vertex_set(self, value_only=False, solver=None, verbose=0, constraint_generation = True):
 r"""
 Computes the minimum feedback vertex set of a digraph.

 The minimum feedback vertex set of a digraph is a set of vertices
 that intersect all the circuits of the digraph.
 Equivalently, a minimum feedback vertex set of a DiGraph is a set
 `S` of vertices such that the digraph `GS` is acyclic. For more
 information, see the
 `Wikipedia article on feedback vertex sets
 `_.

 INPUT:

  ``value_only``  boolean (default: ``False``)

  When set to ``True``, only the minimum cardinal of a minimum vertex
 set is returned.

  When set to ``False``, the ``Set`` of vertices of a minimal feedback
 vertex set is returned.

  ``solver``  (default: ``None``) Specify a Linear Program (LP)
 solver to be used. If set to ``None``, the default one is used. For
 more information on LP solvers and which default solver is used,
 see the method
 :meth:`solve `
 of the class
 :class:`MixedIntegerLinearProgram `.

  ``verbose``  integer (default: ``0``). Sets the level of
 verbosity. Set to 0 by default, which means quiet.

  ``constraint_generation`` (boolean)  whether to use constraint
 generation when solving the Mixed Integer Linear Program (default:
 ``True``).

 ALGORITHM:

 This problem is solved using Linear Programming, which certainly is not
 the best way and will have to be replaced by a better algorithm. The
 program to be solved is the following:

 .. MATH::

 \mbox{Minimize : }&\sum_{v\in G} b_v\\
 \mbox{Such that : }&\\
 &\forall (u,v)\in G, d_ud_v+nb_u+nb_v\geq 0\\
 &\forall u\in G, 0\leq d_u\leq G\\

 A brief explanation:

 An acyclic digraph can be seen as a poset, and every poset has a linear
 extension. This means that in any acyclic digraph the vertices can be
 ordered with a total order `<` in such a way that if `(u,v)\in G`, then
 `u .5]


 else:

 ######################################
 # Orderingbased MILP Implementation #
 ######################################

 p = MixedIntegerLinearProgram(maximization=False, solver=solver)

 b = p.new_variable(binary = True)
 d = p.new_variable(integer = True)
 n = self.order()

 # The removed vertices cover all the back arcs ( third condition )
 for (u,v) in self.edges(labels=None):
 p.add_constraint(d[u]d[v]+n*(b[u]+b[v]),min=1)

 for u in self:
 p.add_constraint(d[u],max=n)

 p.set_objective(p.sum([b[v] for v in self]))

 if value_only:
 return Integer(round(p.solve(objective_only=True, log=verbose)))
 else:
 p.solve(log=verbose)
 b_sol=p.get_values(b)

 return [v for v in self if b_sol[v]==1]


### Construction
def reverse(self):
diff git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
 a/sage/graphs/generic_graph.py
+++ b/sage/graphs/generic_graph.py
@@ 6175,6 +6175,209 @@
else:
raise ValueError("``algorithm`` (%s) should be 'tsp' or 'backtrack'."%(algorithm))
+ def feedback_vertex_set(self, value_only=False, solver=None, verbose=0, constraint_generation = True):
+ r"""
+ Computes the minimum feedback vertex set of a digraph.
+
+ The minimum feedback vertex set of a digraph is a set of vertices
+ that intersect all the circuits of the digraph.
+ Equivalently, a minimum feedback vertex set of a DiGraph is a set
+ `S` of vertices such that the digraph `GS` is acyclic. For more
+ information, see the
+ `Wikipedia article on feedback vertex sets
+ `_.
+
+ INPUT:
+
+  ``value_only``  boolean (default: ``False``)
+
+  When set to ``True``, only the minimum cardinal of a minimum vertex
+ set is returned.
+
+  When set to ``False``, the ``Set`` of vertices of a minimal feedback
+ vertex set is returned.
+
+  ``solver``  (default: ``None``) Specify a Linear Program (LP)
+ solver to be used. If set to ``None``, the default one is used. For
+ more information on LP solvers and which default solver is used,
+ see the method
+ :meth:`solve `
+ of the class
+ :class:`MixedIntegerLinearProgram `.
+
+  ``verbose``  integer (default: ``0``). Sets the level of
+ verbosity. Set to 0 by default, which means quiet.
+
+  ``constraint_generation`` (boolean)  whether to use constraint
+ generation when solving the Mixed Integer Linear Program (default:
+ ``True``).
+
+ ALGORITHM:
+
+ This problem is solved using Linear Programming, which certainly is not
+ the best way and will have to be replaced by a better algorithm. The
+ program to be solved is the following:
+
+ .. MATH::
+
+ \mbox{Minimize : }&\sum_{v\in G} b_v\\
+ \mbox{Such that : }&\\
+ &\forall (u,v)\in G, d_ud_v+nb_u+nb_v\geq 0\\
+ &\forall u\in G, 0\leq d_u\leq G\\
+
+ A brief explanation:
+
+ An acyclic digraph can be seen as a poset, and every poset has a linear
+ extension. This means that in any acyclic digraph the vertices can be
+ ordered with a total order `<` in such a way that if `(u,v)\in G`, then
+ `u .5]
+
+
+ else:
+
+ ######################################
+ # Orderingbased MILP Implementation #
+ ######################################
+
+ p = MixedIntegerLinearProgram(maximization=False, solver=solver)
+
+ b = p.new_variable(binary = True)
+ d = p.new_variable(integer = True)
+ n = self.order()
+
+ # The removed vertices cover all the back arcs ( third condition )
+ for (u,v) in self.edges(labels=None):
+ p.add_constraint(d[u]d[v]+n*(b[u]+b[v]),min=1)
+
+ for u in self:
+ p.add_constraint(d[u],max=n)
+
+ p.set_objective(p.sum([b[v] for v in self]))
+
+ if value_only:
+ return Integer(round(p.solve(objective_only=True, log=verbose)))
+ else:
+ p.solve(log=verbose)
+ b_sol=p.get_values(b)
+
+ return [v for v in self if b_sol[v]==1]
+
def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, vertex_bound=False, method = None, solver=None, verbose=0):
r"""
Returns a maximum flow in the graph from ``x`` to ``y``