@@ -343,41 +343,47 @@ pub fn layers(
343343 Ok ( pylist. into ( ) )
344344 }
345345}
346- /// Get the lexicographical topological sorted nodes from the provided DAG
347- ///
348- /// This function returns a list of nodes data in a graph lexicographically
349- /// topologically sorted using the provided key function. A topological sort
350- /// is a linear ordering of vertices such that for every directed edge from
351- /// node :math:`u` to node :math:`v`, :math:`u` comes before :math:`v`
352- /// in the ordering. If ``reverse`` is set to ``False``, the edges are treated
353- /// as if they pointed in the opposite direction.
354- ///
355- /// This function differs from :func:`~rustworkx.topological_sort` because
356- /// when there are ties between nodes in the sort order this function will
357- /// use the string returned by the ``key`` argument to determine the output
358- /// order used. The ``reverse`` argument does not affect the ordering of keys
359- /// from this function, only the edges of the graph.
360- ///
361- /// :param PyDiGraph dag: The DAG to get the topological sorted nodes from
362- /// :param callable key: key is a python function or other callable that
363- /// gets passed a single argument the node data from the graph and is
364- /// expected to return a string which will be used for resolving ties
365- /// in the sorting order.
366- /// :param bool reverse: If ``False`` (the default), perform a regular
367- /// topological ordering. If ``True``, return the lexicographical
368- /// topological order that would have been found if all the edges in the
369- /// graph were reversed. This does not affect the comparisons from the
370- /// ``key``.
371- /// :param Iterable[int] initial: If given, the initial node indices to start the topological
372- /// ordering from. If not given, the topological ordering will certainly contain every node in
373- /// the graph. If given, only the ``initial`` nodes and nodes that are dominated by the
374- /// ``initial`` set will be in the ordering. Notably, any node that has a natural in degree of
375- /// zero will not be in the output ordering if ``initial`` is given and the zero-in-degree node
376- /// is not in it. It is a :exc:`ValueError` to give an `initial` set where the nodes have even
377- /// a partial topological order between themselves.
378- ///
379- /// :returns: A list of node's data lexicographically topologically sorted.
380- /// :rtype: list
346+
347+ /// Get the lexicographical topological sorted nodes from the provided directed
348+ /// graph.
349+ ///
350+ /// This function returns a list of node data from the graph, sorted in
351+ /// lexicographical order based on the provided key function. A topological sort
352+ /// is a linear ordering of vertices such that for every directed edge from node
353+ /// :math:`u` to node :math:`v`, :math:`u` appears before :math:`v` in the
354+ /// ordering. If `reverse` is set to `False`, the edges are treated as if they
355+ /// point in the opposite direction.
356+ ///
357+ /// Unlike :func:`~rustworkx.topological_sort`, this function resolves ties
358+ /// between nodes using the string returned by the `key` argument. The `reverse`
359+ /// argument only affects the direction of the edges, not the ordering of keys.
360+ ///
361+ /// >>> G = rx.PyDiGraph()
362+ /// >>> a, b, c, d, e, f, g = G.add_nodes_from(["A", "B", "C", "D", "E", "F", "G"])
363+ /// >>> G.add_edges_from_no_data([(a, g), (b, g), (c, g), (d, g), (e, g), (f, g)])
364+ /// >>> rx.topological_sort(G)
365+ /// NodeIndices[5, 4, 3, 2, 1, 0, 6] # First 6 items in any order
366+ /// >>> rx.lexicographical_topological_sort(G, key=str)
367+ /// ['A', 'B', 'C', 'D', 'E', 'F', 'G'] # First 6 items in alphabetical order
368+ ///
369+ /// For a standard topological sort without lexicographical ordering, see
370+ /// :func:`~rustworkx.topological_sort`.
371+ ///
372+ /// :param PyDiGraph dag: The directed graph to sort.
373+ /// :param callable key: A callable that takes a single argument (node data) and
374+ /// returns a string used to resolve ties in the sorting order.
375+ /// :param bool reverse: If `False` (default), perform a regular topological
376+ /// ordering. If `True`, return the lexicographical order as if all edges
377+ /// were reversed. This does not affect the comparisons from the `key`.
378+ /// :param Iterable[int] initial: By default, the topological ordering will
379+ /// include all nodes in the graph. If ``initial`` node indices are
380+ /// provided, the ordering will only include those nodes and any nodes that
381+ /// are dominated by them. Providing an initial set where the nodes have
382+ /// even a partial topological order among themselves will raise a
383+ /// :exc:`ValueError`.
384+ ///
385+ /// :returns: A list of node data, lexicographically topologically sorted.
386+ /// :rtype: list[S]
381387#[ pyfunction]
382388#[ pyo3( signature = ( dag, /, key, * , reverse=false , initial=None ) ) ]
383389pub fn lexicographical_topological_sort (
@@ -413,19 +419,28 @@ pub fn lexicographical_topological_sort(
413419 . into ( ) )
414420}
415421
416- /// Return the topological generations of a DAG
422+ /// Return the topological generations of a directed graph.
417423///
418- /// A topological generation is node collection in which ancestors of a node in each
419- /// generation are guaranteed to be in a previous generation, and any descendants of
420- /// a node are guaranteed to be in a following generation. Nodes are guaranteed to
421- /// be in the earliest possible generation that they can belong to.
424+ /// A topological generation is a collection of nodes where all ancestors of a
425+ /// node are guaranteed to be in a previous generation, and all descendants of a
426+ /// node are guaranteed to be in a subsequent generation. Nodes are placed in
427+ /// the earliest possible generation they can belong to.
422428///
423- /// :param PyDiGraph graph: The DAG to get the topological generations from
429+ /// >>> G = rx.PyDiGraph()
430+ /// >>> G.add_nodes_from([0, 1, 2, 3, 4])
431+ /// >>> G.add_edges_from_no_data([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4)])
432+ /// >>> rx.topological_generations(G)
433+ /// [NodeIndices[0], NodeIndices[1, 2], NodeIndices[3], NodeIndices[4]]
424434///
425- /// :returns: A list of topological generations.
426- /// :rtype: list
435+ /// For a topologically sorted node list without generations, see :func:`~topological_sort`.
436+ ///
437+ /// For more advanced control over the nodes iteration, see :class:`~rustworkx.TopologicalSorter`.
427438///
428- /// :raises DAGHasCycle: if a cycle is encountered while sorting the graph
439+ /// :param PyDiGraph dag: The directed graph to get the topological generations from.
440+ /// :returns: A list of topological generations, where each generation is
441+ /// represented as a list of node indices.
442+ /// :rtype: list[NodeIndices]
443+ /// :raises DAGHasCycle: if a cycle is encountered while processing the graph.o
429444#[ pyfunction]
430445#[ pyo3( text_signature = "(dag, /)" ) ]
431446pub fn topological_generations ( dag : & digraph:: PyDiGraph ) -> PyResult < Vec < NodeIndices > > {
@@ -468,14 +483,29 @@ pub fn topological_generations(dag: &digraph::PyDiGraph) -> PyResult<Vec<NodeInd
468483 Ok ( generations)
469484}
470485
471- /// Return the topological sort of node indices from the provided graph
486+ /// Return the topological sort of node indices from the provided directed
487+ /// graph.
472488///
473- /// :param PyDiGraph graph: The DAG to get the topological sort on
489+ /// Computes a topological ordering of the nodes in the given directed graph,
490+ /// ensuring that for every directed edge from node :math:`u` to node :math:`v`,
491+ /// node :math:`u` appears before node :math:`v` in the resulting sequence. This
492+ /// is particularly useful in scenarios such as task scheduling and dependency
493+ /// resolution, where certain tasks must be completed before others.
474494///
495+ /// >>> G = rx.PyDiGraph()
496+ /// >>> G.add_nodes_from(["A", "B", "C", "D", "E", "F", "G"])
497+ /// >>> G.add_edges_from_no_data([(0, 1),(1, 2), (2, 3), (3, 4), (5, 2), (6, 3)])
498+ /// >>> rx.topological_sort(G)
499+ /// NodeIndices[6, 5, 0, 1, 2, 3, 4]
500+ ///
501+ /// For more advanced control over the nodes iteration, see :class:`~rustworkx.TopologicalSorter`.
502+ ///
503+ /// For custom sorting algorithm, see :func:`~lexicographical_topological_sort`.
504+ ///
505+ /// :param PyDiGraph graph: The directed graph to get the topological sort on.
475506/// :returns: A list of node indices topologically sorted.
476507/// :rtype: NodeIndices
477- ///
478- /// :raises DAGHasCycle: if a cycle is encountered while sorting the graph
508+ /// :raises DAGHasCycle: if a cycle is encountered while sorting the graph.
479509#[ pyfunction]
480510#[ pyo3( text_signature = "(graph, /)" ) ]
481511pub fn topological_sort ( graph : & digraph:: PyDiGraph ) -> PyResult < NodeIndices > {
0 commit comments