示例#1
0
    def uncompactify(self):
        r"""
        Returns the tree obtained from self by splitting edges so that they
        are labelled by exactly one letter. The resulting tree is
        isomorphic to the suffix trie.

        EXAMPLES::

            sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree, SuffixTrie
            sage: abbab = Words("ab")("abbab")
            sage: s = SuffixTrie(abbab)
            sage: t = ImplicitSuffixTree(abbab)
            sage: t.uncompactify().is_isomorphic(s.to_digraph())
            True
        """
        tree = self.to_digraph(word_labels=True)
        newtree = DiGraph()
        newtree.add_vertices(range(tree.order()))
        new_node = tree.order() + 1
        for (u, v, label) in tree.edge_iterator():
            if len(label) == 1:
                newtree.add_edge(u, v)
            else:
                newtree.add_edge(u, new_node, label[0])
                for w in label[1:-1]:
                    newtree.add_edge(new_node, new_node + 1, w)
                    new_node += 1
                newtree.add_edge(new_node, v, label[-1])
                new_node += 1
        return newtree
示例#2
0
    def uncompactify(self):
        r"""
        Returns the tree obtained from self by splitting edges so that they
        are labelled by exactly one letter. The resulting tree is
        isomorphic to the suffix trie.

        EXAMPLES::

            sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree, SuffixTrie
            sage: abbab = Words("ab")("abbab")
            sage: s = SuffixTrie(abbab)
            sage: t = ImplicitSuffixTree(abbab)
            sage: t.uncompactify().is_isomorphic(s.to_digraph())
            True
        """
        tree = self.to_digraph(word_labels=True)
        newtree = DiGraph()
        newtree.add_vertices(range(tree.order()))
        new_node = tree.order() + 1
        for (u,v,label) in tree.edge_iterator():
            if len(label) == 1:
                newtree.add_edge(u,v)
            else:
                newtree.add_edge(u,new_node,label[0]);
                for w in label[1:-1]:
                    newtree.add_edge(new_node,new_node+1,w)
                    new_node += 1
                newtree.add_edge(new_node,v,label[-1])
                new_node += 1
        return newtree
示例#3
0
def _digraph_mutate(dg, k, frozen=None):
    """
    Return a digraph obtained from ``dg`` by mutating at vertex ``k``.

    Vertices can be labelled by anything, and frozen vertices must
    be explicitly given.

    INPUT:

    - ``dg`` -- a digraph with integral edge labels with ``n+m`` vertices
    - ``k`` -- the vertex at which ``dg`` is mutated
    - ``frozen`` -- the list of frozen vertices (default is the empty list)

    EXAMPLES::

        sage: from sage.combinat.cluster_algebra_quiver.mutation_class import _digraph_mutate
        sage: from sage.combinat.cluster_algebra_quiver.quiver import ClusterQuiver
        sage: dg = ClusterQuiver(['A',4]).digraph()
        sage: dg.edges()
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]
        sage: _digraph_mutate(dg,2).edges()
        [(0, 1, (1, -1)), (1, 2, (1, -1)), (3, 2, (1, -1))]

    TESTS::

       sage: dg = DiGraph([('a','b',(1,-1)),('c','a',(1,-1))])
       sage: _digraph_mutate(dg,'a').edges()
       [('a', 'c', (1, -1)), ('b', 'a', (1, -1)), ('c', 'b', (1, -1))]
       sage: _digraph_mutate(dg,'a',frozen=['b','c']).edges()
       [('a', 'c', (1, -1)), ('b', 'a', (1, -1))]

       sage: dg = DiGraph([('a','b',(2,-2)),('c','a',(2,-2)),('b','c',(2,-2))])
       sage: _digraph_mutate(dg,'a').edges()
       [('a', 'c', (2, -2)), ('b', 'a', (2, -2)), ('c', 'b', (2, -2))]
    """
    # assert sorted(list(dg)) == list(range(n + m))
    # this is not assumed anymore
    if frozen is None:
        frozen = []

    edge_it = dg.incoming_edge_iterator(dg, True)
    edges = {(v1, v2): label for v1, v2, label in edge_it}
    edge_it = dg.incoming_edge_iterator([k], True)
    in_edges = [(v1, v2, label) for v1, v2, label in edge_it]
    edge_it = dg.outgoing_edge_iterator([k], True)
    out_edges = [(v1, v2, label) for v1, v2, label in edge_it]

    in_edges_new = [(v2, v1, (-label[1], -label[0]))
                    for (v1, v2, label) in in_edges]
    out_edges_new = [(v2, v1, (-label[1], -label[0]))
                     for (v1, v2, label) in out_edges]
    diag_edges_new = []
    diag_edges_del = []

    for (v1, v2, label1) in in_edges:
        l11, l12 = label1
        for (w1, w2, label2) in out_edges:
            if v1 in frozen and w2 in frozen:
                continue
            l21, l22 = label2
            if (v1, w2) in edges:
                diag_edges_del.append((v1, w2))
                a, b = edges[(v1, w2)]
                a, b = a + l11 * l21, b - l12 * l22
                diag_edges_new.append((v1, w2, (a, b)))
            elif (w2, v1) in edges:
                diag_edges_del.append((w2, v1))
                a, b = edges[(w2, v1)]
                a, b = b + l11 * l21, a - l12 * l22
                if a < 0:
                    diag_edges_new.append((w2, v1, (b, a)))
                elif a > 0:
                    diag_edges_new.append((v1, w2, (a, b)))
            else:
                a, b = l11 * l21, -l12 * l22
                diag_edges_new.append((v1, w2, (a, b)))

    del_edges = [tuple(ed[:2]) for ed in in_edges + out_edges]
    del_edges += diag_edges_del
    new_edges = in_edges_new + out_edges_new
    new_edges += diag_edges_new
    new_edges += [(v1, v2, edges[(v1, v2)]) for (v1, v2) in edges
                  if (v1, v2) not in del_edges]

    dg_new = DiGraph()
    dg_new.add_vertices(list(dg))
    for v1, v2, label in new_edges:
        dg_new.add_edge(v1, v2, label)

    return dg_new
示例#4
0
        def dual_equivalence_graph(self, X=None, index_set=None, directed=True):
            r"""
            Return the dual equivalence graph indexed by ``index_set``
            on the subset ``X`` of ``self``.

            Let `b \in B` be an element of weight `0`, so `\varepsilon_j(b)
            = \varphi_j(b)` for all `j \in I`, where `I` is the indexing
            set. We say `b'` is an `i`-elementary dual equivalence
            transformation of `b` (where `i \in I`) if

            * `\varepsilon_i(b) = 1` and `\varepsilon_{i-1}(b) = 0`, and
            * `b' = f_{i-1} f_i e_{i-1} e_i b`.

            We can do the inverse procedure by interchanging `i` and `i-1`
            above.

            .. NOTE::

                If the index set is not an ordered interval, we let
                `i - 1` mean the index appearing before `i` in `I`.

            This definition comes from [Assaf08]_ Section 4 (where our
            `\varphi_j(b)` and `\varepsilon_j(b)` are denoted by
            `\epsilon(b, j)` and `-\delta(b, j)`, respectively).

            The dual equivalence graph of `B` is defined to be the
            colored graph whose vertices are the elements of `B` of
            weight `0`, and whose edges of color `i` (for `i \in I`)
            connect pairs `\{ b, b' \}` such that `b'` is an
            `i`-elementary dual equivalence transformation of `b`.

            .. NOTE::

                This dual equivalence graph is a generalization of
                `\mathcal{G}\left(\mathcal{X}\right)` in [Assaf08]_
                Section 4 except we do not require
                `\varepsilon_i(b) = 0, 1` for all `i`.

            This definition can be generalized by choosing a subset `X`
            of the set of all vertices of `B` of weight `0`, and
            restricting the dual equivalence graph to the vertex set
            `X`.

            INPUT:

            - ``X`` -- (optional) the vertex set `X` (default:
              the whole set of vertices of ``self`` of weight `0`)
            - ``index_set`` -- (optional) the index set `I`
              (default: the whole index set of ``self``); this has
              to be a subset of the index set of ``self`` (as a list
              or tuple)
            - ``directed`` -- (default: ``True``) whether to have the
              dual equivalence graph be directed, where the head of
              an edge `b - b'` is `b` and the tail is
              `b' = f_{i-1} f_i e_{i-1} e_i b`)

            .. SEEALSO::

                :meth:`sage.combinat.partition.Partition.dual_equivalence_graph`

            REFERENCES:

            .. [Assaf08] Sami Assaf. *A combinatorial realization of Schur-Weyl
               duality via crystal graphs and dual equivalence graphs*.
               FPSAC 2008, 141-152, Discrete Math. Theor. Comput. Sci. Proc.,
               AJ, Assoc. Discrete Math. Theor. Comput. Sci., (2008).
               :arxiv:`0804.1587v1`

            EXAMPLES::

                sage: T = crystals.Tableaux(['A',3], shape=[2,2])
                sage: G = T.dual_equivalence_graph()
                sage: sorted(G.edges())
                [([[1, 3], [2, 4]], [[1, 2], [3, 4]], 2),
                 ([[1, 2], [3, 4]], [[1, 3], [2, 4]], 3)]
                sage: T = crystals.Tableaux(['A',4], shape=[3,2])
                sage: G = T.dual_equivalence_graph()
                sage: sorted(G.edges())
                [([[1, 3, 5], [2, 4]], [[1, 3, 4], [2, 5]], 4),
                 ([[1, 3, 5], [2, 4]], [[1, 2, 5], [3, 4]], 2),
                 ([[1, 3, 4], [2, 5]], [[1, 2, 4], [3, 5]], 2),
                 ([[1, 2, 5], [3, 4]], [[1, 3, 5], [2, 4]], 3),
                 ([[1, 2, 4], [3, 5]], [[1, 2, 3], [4, 5]], 3),
                 ([[1, 2, 3], [4, 5]], [[1, 2, 4], [3, 5]], 4)]

                sage: T = crystals.Tableaux(['A',4], shape=[3,1])
                sage: G = T.dual_equivalence_graph(index_set=[1,2,3])
                sage: G.vertices()
                [[[1, 3, 4], [2]], [[1, 2, 4], [3]], [[1, 2, 3], [4]]]
                sage: G.edges()
                [([[1, 3, 4], [2]], [[1, 2, 4], [3]], 2),
                 ([[1, 2, 4], [3]], [[1, 2, 3], [4]], 3)]

            TESTS::

                sage: T = crystals.Tableaux(['A',4], shape=[3,1])
                sage: G = T.dual_equivalence_graph(index_set=[2,3])
                sage: sorted(G.edges())
                [([[1, 2, 4], [3]], [[1, 2, 3], [4]], 3),
                 ([[2, 4, 5], [3]], [[2, 3, 5], [4]], 3)]
                sage: sorted(G.vertices())
                [[[1, 3, 4], [2]],
                 [[1, 2, 4], [3]],
                 [[2, 4, 5], [3]],
                 [[1, 2, 3], [4]],
                 [[2, 3, 5], [4]],
                 [[1, 1, 1], [5]],
                 [[1, 1, 5], [5]],
                 [[1, 5, 5], [5]],
                 [[2, 3, 4], [5]]]
            """
            if index_set is None:
                index_set = self.index_set()

            def wt_zero(x):
                for i in index_set:
                    if x.epsilon(i) != x.phi(i):
                        return False
                return True

            if X is None:
                X = [x for x in self if wt_zero(x)]
                checker = lambda x: True
            elif any(not wt_zero(x) for x in X):
                raise ValueError("the elements are not all weight 0")
            else:
                checker = lambda x: x in X

            edges = []
            for x in X:
                for k, i in enumerate(index_set[1:]):
                    im = index_set[k]
                    if x.epsilon(i) == 1 and x.epsilon(im) == 0:
                        y = x.e(i).e(im).f(i).f(im)
                        if checker(y):
                            edges.append([x, y, i])
            from sage.graphs.all import DiGraph

            G = DiGraph(edges)
            G.add_vertices(X)
            if have_dot2tex():
                G.set_latex_options(
                    format="dot2tex", edge_labels=True, color_by_label=self.cartan_type()._index_set_coloring
                )
            return G
示例#5
0
        def dual_equivalence_graph(self,
                                   X=None,
                                   index_set=None,
                                   directed=True):
            r"""
            Return the dual equivalence graph indexed by ``index_set``
            on the subset ``X`` of ``self``.

            Let `b \in B` be an element of weight `0`, so `\varepsilon_j(b)
            = \varphi_j(b)` for all `j \in I`, where `I` is the indexing
            set. We say `b'` is an `i`-elementary dual equivalence
            transformation of `b` (where `i \in I`) if

            * `\varepsilon_i(b) = 1` and `\varepsilon_{i-1}(b) = 0`, and
            * `b' = f_{i-1} f_i e_{i-1} e_i b`.

            We can do the inverse procedure by interchanging `i` and `i-1`
            above.

            .. NOTE::

                If the index set is not an ordered interval, we let
                `i - 1` mean the index appearing before `i` in `I`.

            This definition comes from [Assaf08]_ Section 4 (where our
            `\varphi_j(b)` and `\varepsilon_j(b)` are denoted by
            `\epsilon(b, j)` and `-\delta(b, j)`, respectively).

            The dual equivalence graph of `B` is defined to be the
            colored graph whose vertices are the elements of `B` of
            weight `0`, and whose edges of color `i` (for `i \in I`)
            connect pairs `\{ b, b' \}` such that `b'` is an
            `i`-elementary dual equivalence transformation of `b`.

            .. NOTE::

                This dual equivalence graph is a generalization of
                `\mathcal{G}\left(\mathcal{X}\right)` in [Assaf08]_
                Section 4 except we do not require
                `\varepsilon_i(b) = 0, 1` for all `i`.

            This definition can be generalized by choosing a subset `X`
            of the set of all vertices of `B` of weight `0`, and
            restricting the dual equivalence graph to the vertex set
            `X`.

            INPUT:

            - ``X`` -- (optional) the vertex set `X` (default:
              the whole set of vertices of ``self`` of weight `0`)
            - ``index_set`` -- (optional) the index set `I`
              (default: the whole index set of ``self``); this has
              to be a subset of the index set of ``self`` (as a list
              or tuple)
            - ``directed`` -- (default: ``True``) whether to have the
              dual equivalence graph be directed, where the head of
              an edge `b - b'` is `b` and the tail is
              `b' = f_{i-1} f_i e_{i-1} e_i b`)

            .. SEEALSO::

                :meth:`sage.combinat.partition.Partition.dual_equivalence_graph`

            REFERENCES:

            .. [Assaf08] Sami Assaf. *A combinatorial realization of Schur-Weyl
               duality via crystal graphs and dual equivalence graphs*.
               FPSAC 2008, 141-152, Discrete Math. Theor. Comput. Sci. Proc.,
               AJ, Assoc. Discrete Math. Theor. Comput. Sci., (2008).
               :arxiv:`0804.1587v1`

            EXAMPLES::

                sage: T = crystals.Tableaux(['A',3], shape=[2,2])
                sage: G = T.dual_equivalence_graph()
                sage: sorted(G.edges())
                [([[1, 3], [2, 4]], [[1, 2], [3, 4]], 2),
                 ([[1, 2], [3, 4]], [[1, 3], [2, 4]], 3)]
                sage: T = crystals.Tableaux(['A',4], shape=[3,2])
                sage: G = T.dual_equivalence_graph()
                sage: sorted(G.edges())
                [([[1, 3, 5], [2, 4]], [[1, 3, 4], [2, 5]], 4),
                 ([[1, 3, 5], [2, 4]], [[1, 2, 5], [3, 4]], 2),
                 ([[1, 3, 4], [2, 5]], [[1, 2, 4], [3, 5]], 2),
                 ([[1, 2, 5], [3, 4]], [[1, 3, 5], [2, 4]], 3),
                 ([[1, 2, 4], [3, 5]], [[1, 2, 3], [4, 5]], 3),
                 ([[1, 2, 3], [4, 5]], [[1, 2, 4], [3, 5]], 4)]

                sage: T = crystals.Tableaux(['A',4], shape=[3,1])
                sage: G = T.dual_equivalence_graph(index_set=[1,2,3])
                sage: G.vertices()
                [[[1, 3, 4], [2]], [[1, 2, 4], [3]], [[1, 2, 3], [4]]]
                sage: G.edges()
                [([[1, 3, 4], [2]], [[1, 2, 4], [3]], 2),
                 ([[1, 2, 4], [3]], [[1, 2, 3], [4]], 3)]

            TESTS::

                sage: T = crystals.Tableaux(['A',4], shape=[3,1])
                sage: G = T.dual_equivalence_graph(index_set=[2,3])
                sage: sorted(G.edges())
                [([[1, 2, 4], [3]], [[1, 2, 3], [4]], 3),
                 ([[2, 4, 5], [3]], [[2, 3, 5], [4]], 3)]
                sage: sorted(G.vertices())
                [[[1, 3, 4], [2]],
                 [[1, 2, 4], [3]],
                 [[2, 4, 5], [3]],
                 [[1, 2, 3], [4]],
                 [[2, 3, 5], [4]],
                 [[1, 1, 1], [5]],
                 [[1, 1, 5], [5]],
                 [[1, 5, 5], [5]],
                 [[2, 3, 4], [5]]]
            """
            if index_set is None:
                index_set = self.index_set()

            def wt_zero(x):
                for i in index_set:
                    if x.epsilon(i) != x.phi(i):
                        return False
                return True

            if X is None:
                X = [x for x in self if wt_zero(x)]
                checker = lambda x: True
            elif any(not wt_zero(x) for x in X):
                raise ValueError("the elements are not all weight 0")
            else:
                checker = lambda x: x in X

            edges = []
            for x in X:
                for k, i in enumerate(index_set[1:]):
                    im = index_set[k]
                    if x.epsilon(i) == 1 and x.epsilon(im) == 0:
                        y = x.e(i).e(im).f(i).f(im)
                        if checker(y):
                            edges.append([x, y, i])
            from sage.graphs.all import DiGraph
            G = DiGraph(edges)
            G.add_vertices(X)
            if have_dot2tex():
                G.set_latex_options(
                    format="dot2tex",
                    edge_labels=True,
                    color_by_label=self.cartan_type()._index_set_coloring)
            return G
示例#6
0
    def RandomPoset(n,p):
        r"""
        Generate a random poset on ``n`` vertices according to a
        probability ``p``.

        INPUT:

        - ``n`` - number of vertices, a non-negative integer

        - ``p`` - a probability, a real number between 0 and 1 (inclusive)

        OUTPUT:

        A poset on ``n`` vertices.  The construction decides to make an
        ordered pair of vertices comparable in the poset with probability
        ``p``, however a pair is not made comparable if it would violate
        the defining properties of a poset, such as transitivity.

        So in practice, once the probability exceeds a small number the
        generated posets may be very similar to a chain.  So to create
        interesting examples, keep the probability small, perhaps on the
        order of `1/n`.

        EXAMPLES::

            sage: Posets.RandomPoset(17,.15)
            Finite poset containing 17 elements

        TESTS::

            sage: Posets.RandomPoset('junk', 0.5)
            Traceback (most recent call last):
            ...
            TypeError: number of elements must be an integer, not junk

            sage: Posets.RandomPoset(-6, 0.5)
            Traceback (most recent call last):
            ...
            ValueError: number of elements must be non-negative, not -6

            sage: Posets.RandomPoset(6, 'garbage')
            Traceback (most recent call last):
            ...
            TypeError: probability must be a real number, not garbage

            sage: Posets.RandomPoset(6, -0.5)
            Traceback (most recent call last):
            ...
            ValueError: probability must be between 0 and 1, not -0.5
        """
        try:
            n = Integer(n)
        except:
            raise TypeError("number of elements must be an integer, not {0}".format(n))
        if n < 0:
            raise ValueError("number of elements must be non-negative, not {0}".format(n))
        try:
            p = float(p)
        except:
            raise TypeError("probability must be a real number, not {0}".format(p))
        if p < 0 or p> 1:
            raise ValueError("probability must be between 0 and 1, not {0}".format(p))
        
        D = DiGraph(loops=False,multiedges=False)
        D.add_vertices(range(n))
        for i in range(n):
            for j in range(n):
                if random.random() < p:
                    D.add_edge(i,j)
                    if not D.is_directed_acyclic():
                        D.delete_edge(i,j)
        return Poset(D,cover_relations=False)
示例#7
0
def _digraph_mutate(dg, k, frozen=None):
    """
    Return a digraph obtained from ``dg`` by mutating at vertex ``k``.

    Vertices can be labelled by anything, and frozen vertices must
    be explicitly given.

    INPUT:

    - ``dg`` -- a digraph with integral edge labels with ``n+m`` vertices
    - ``k`` -- the vertex at which ``dg`` is mutated
    - ``frozen`` -- the list of frozen vertices (default is the empty list)

    EXAMPLES::

        sage: from sage.combinat.cluster_algebra_quiver.mutation_class import _digraph_mutate
        sage: from sage.combinat.cluster_algebra_quiver.quiver import ClusterQuiver
        sage: dg = ClusterQuiver(['A',4]).digraph()
        sage: dg.edges()
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]
        sage: _digraph_mutate(dg,2).edges()
        [(0, 1, (1, -1)), (1, 2, (1, -1)), (3, 2, (1, -1))]

    TESTS::

       sage: dg = DiGraph([('a','b',(1,-1)),('c','a',(1,-1))])
       sage: _digraph_mutate(dg,'a').edges()
       [('a', 'c', (1, -1)), ('b', 'a', (1, -1)), ('c', 'b', (1, -1))]
       sage: _digraph_mutate(dg,'a',frozen=['b','c']).edges()
       [('a', 'c', (1, -1)), ('b', 'a', (1, -1))]

       sage: dg = DiGraph([('a','b',(2,-2)),('c','a',(2,-2)),('b','c',(2,-2))])
       sage: _digraph_mutate(dg,'a').edges()
       [('a', 'c', (2, -2)), ('b', 'a', (2, -2)), ('c', 'b', (2, -2))]
    """
    # assert sorted(list(dg)) == list(range(n + m))
    # this is not assumed anymore
    if frozen is None:
        frozen = []

    edge_it = dg.incoming_edge_iterator(dg, True)
    edges = {(v1, v2): label for v1, v2, label in edge_it}
    edge_it = dg.incoming_edge_iterator([k], True)
    in_edges = [(v1, v2, label) for v1, v2, label in edge_it]
    edge_it = dg.outgoing_edge_iterator([k], True)
    out_edges = [(v1, v2, label) for v1, v2, label in edge_it]

    in_edges_new = [(v2, v1, (-label[1], -label[0]))
                    for (v1, v2, label) in in_edges]
    out_edges_new = [(v2, v1, (-label[1], -label[0]))
                     for (v1, v2, label) in out_edges]
    diag_edges_new = []
    diag_edges_del = []

    for (v1, v2, label1) in in_edges:
        l11, l12 = label1
        for (w1, w2, label2) in out_edges:
            if v1 in frozen and w2 in frozen:
                continue
            l21, l22 = label2
            if (v1, w2) in edges:
                diag_edges_del.append((v1, w2))
                a, b = edges[(v1, w2)]
                a, b = a + l11 * l21, b - l12 * l22
                diag_edges_new.append((v1, w2, (a, b)))
            elif (w2, v1) in edges:
                diag_edges_del.append((w2, v1))
                a, b = edges[(w2, v1)]
                a, b = b + l11 * l21, a - l12 * l22
                if a < 0:
                    diag_edges_new.append((w2, v1, (b, a)))
                elif a > 0:
                    diag_edges_new.append((v1, w2, (a, b)))
            else:
                a, b = l11 * l21, -l12 * l22
                diag_edges_new.append((v1, w2, (a, b)))

    del_edges = [tuple(ed[:2]) for ed in in_edges + out_edges]
    del_edges += diag_edges_del
    new_edges = in_edges_new + out_edges_new
    new_edges += diag_edges_new
    new_edges += [(v1, v2, edges[(v1, v2)]) for (v1, v2) in edges
                  if (v1, v2) not in del_edges]

    dg_new = DiGraph()
    dg_new.add_vertices(list(dg))
    for v1, v2, label in new_edges:
        dg_new.add_edge(v1, v2, label)

    return dg_new
示例#8
0
    def RandomPoset(n, p):
        r"""
        Generate a random poset on ``n`` vertices according to a
        probability ``p``.

        INPUT:

        - ``n`` - number of vertices, a non-negative integer

        - ``p`` - a probability, a real number between 0 and 1 (inclusive)

        OUTPUT:

        A poset on ``n`` vertices.  The construction decides to make an
        ordered pair of vertices comparable in the poset with probability
        ``p``, however a pair is not made comparable if it would violate
        the defining properties of a poset, such as transitivity.

        So in practice, once the probability exceeds a small number the
        generated posets may be very similar to a chain.  So to create
        interesting examples, keep the probability small, perhaps on the
        order of `1/n`.

        EXAMPLES::

            sage: Posets.RandomPoset(17,.15)
            Finite poset containing 17 elements

        TESTS::

            sage: Posets.RandomPoset('junk', 0.5)
            Traceback (most recent call last):
            ...
            TypeError: number of elements must be an integer, not junk

            sage: Posets.RandomPoset(-6, 0.5)
            Traceback (most recent call last):
            ...
            ValueError: number of elements must be non-negative, not -6

            sage: Posets.RandomPoset(6, 'garbage')
            Traceback (most recent call last):
            ...
            TypeError: probability must be a real number, not garbage

            sage: Posets.RandomPoset(6, -0.5)
            Traceback (most recent call last):
            ...
            ValueError: probability must be between 0 and 1, not -0.5
        """
        try:
            n = Integer(n)
        except:
            raise TypeError(
                "number of elements must be an integer, not {0}".format(n))
        if n < 0:
            raise ValueError(
                "number of elements must be non-negative, not {0}".format(n))
        try:
            p = float(p)
        except:
            raise TypeError(
                "probability must be a real number, not {0}".format(p))
        if p < 0 or p > 1:
            raise ValueError(
                "probability must be between 0 and 1, not {0}".format(p))

        D = DiGraph(loops=False, multiedges=False)
        D.add_vertices(range(n))
        for i in range(n):
            for j in range(n):
                if random.random() < p:
                    D.add_edge(i, j)
                    if not D.is_directed_acyclic():
                        D.delete_edge(i, j)
        return Poset(D, cover_relations=False)