Ticket #14498: trac_14498_trees_research_algorithms_EliX-jbp.patch

File trac_14498_trees_research_algorithms_EliX-jbp.patch, 13.5 KB (added by elixyre, 7 years ago)
  • sage/combinat/abstract_tree.py

    # HG changeset patch
    # User Jean-Baptiste Priez <jbp@kerios.fr>
    # Date 1367061247 -7200
    # Node ID 3e91cc3ca6facc277fea4dad9eb017c7ac7dddd9
    # Parent  edc0cfe0d5c55a0b0a989087ff87510b8dd31198
    several research algorithms on binary trees
      -> over/under (Loday-Ronco)
      -> pred/succ in the tamari lattice
      -> hook length formula
    
    diff --git a/sage/combinat/abstract_tree.py b/sage/combinat/abstract_tree.py
    a b incoherent with the data structure. 
    6161
    6262- Florent Hivert (2010-2011): initial revision
    6363- Frédéric Chapoton (2011): contributed some methods
     64- Jean-Baptiste Priez (2013): several transversal algorithms
    6465"""
    6566
    6667from sage.structure.list_clone import ClonableArray
  • sage/combinat/binary_tree.py

    diff --git a/sage/combinat/binary_tree.py b/sage/combinat/binary_tree.py
    a b objects. 
    1111**AUTHORS:**
    1212
    1313- Florent Hivert (2010-2011): initial implementation.
     14- Jean-Baptiste Priez (2013):
     15      -> several classical algorithms
     16      -> some research algorithms from _[LodayRonco] 
     17
     18References
     19----------
     20
     21.. [LodayRonco] Hopf algebra of the planar binary trees,
     22    Jean-Louis Loday and
     23    Maria O. Ronco
    1424"""
    1525#*****************************************************************************
    1626#       Copyright (C) 2010 Florent Hivert <Florent.Hivert@univ-rouen.fr>,
    class BinaryTree(AbstractClonableTree, C 
    626636        '''
    627637        B = self.parent()._element_constructor_
    628638        return B( [B( [self[0], self[1][0]] ), self[1][1]] )
     639   
     640    def sylvestrohedron_greater( self ):
     641        '''
     642        The list of all trees greater than ''self''.
     643        This is the transitive ideal of its successors.
     644       
     645        The tree
     646            __o__
     647           /     \
     648          o       o
     649         / \     /
     650        o   o   o
     651       
     652        has these trees greater than it:
     653       
     654        To          , o        , o        , o        ,  o       ,   o      ,
     655        | \            \          \          \           \           \     
     656        |  o            o          o           o         _o_        __o__   
     657        |   \            \          \           \       /   \      /     \ 
     658        |    o            o          o          _o_    o     o    o       o
     659        |     \            \        / \        /   \    \     \    \     / 
     660        |      o            o      o   o      o     o    o     o    o   o   
     661        |       \            \          \          /                       
     662        |        o            o          o        o                         
     663        |         \          /                                             
     664        L          o        o                                               
     665           o        ,   o      ,   _o_      ,   _o__     ,   __o__    ,   ___o___  ,
     666          / \          / \        /   \        /    \       /     \      /       \ 
     667         o   o        o   o      o     o      o     _o_    o       o    o         o
     668              \            \          / \          /   \    \       \    \       / 
     669               o            o        o   o        o     o    o       o    o     o   
     670                \            \            \            /      \            \       
     671                 o            o            o          o        o            o       
     672                  \          /                                                     
     673                   o        o                                                       
     674                                                                                   
     675                                                                                   
     676             _o_    ,     __o__  T
     677            /   \        /     \ |
     678           o     o      o       o|
     679          / \     \    / \     / |
     680         o   o     o  o   o   o  |
     681                                 |
     682                                 |
     683                                 |
     684                                 |
     685                                 |
     686                                 J
     687       
     688       
     689        TESTS::
     690
     691            sage: B = BinaryTree
     692            sage: b = B([None, B([None, B([None, B([])])])]);b
     693            [., [., [., [., .]]]]
     694            sage: b.sylvestrohedron_greater()
     695            [[., [., [., [., .]]]]]
     696            sage: b = B([B([B([B([]), None]), None]), None]);b
     697            [[[[., .], .], .], .]
     698            sage: b.sylvestrohedron_greater()
     699            [[., [., [., [., .]]]], [., [., [[., .], .]]], [., [[., .], [., .]]], [., [[., [., .]], .]], [., [[[., .], .], .]], [[., .], [., [., .]]], [[., .], [[., .], .]], [[., [., .]], [., .]], [[., [., [., .]]], .], [[., [[., .], .]], .], [[[., .], .], [., .]], [[[., .], [., .]], .], [[[., [., .]], .], .], [[[[., .], .], .], .]]
     700        '''
     701        from sage.combinat.tools import transitive_ideal
     702        return transitive_ideal( lambda x: x.sylvestrohedron_succ(), self )
     703
     704    def sylvestrohedron_pred( self ):
     705        '''
     706        Compute the list of predecessor of ''self'' in the
     707        sylvestrohedron.
     708        This list is computed by all left rotate possible on
     709        its nodes.
     710       
     711        For this tree
     712       
     713            __o__
     714           /     \
     715          o       o
     716         / \     /
     717        o   o   o
     718       
     719        the list is
     720       
     721        T       o ,       _o_  T
     722        |      /         /   \ |
     723        |    _o_        o     o|
     724        |   /   \      /     / |
     725        |  o     o    o     o  |
     726        | / \        /         |
     727        Lo   o      o          J
     728       
     729        TESTS::
     730
     731            sage: B = BinaryTree
     732            sage: b = B([B([B([B([]), None]), None]), None]);b
     733            [[[[., .], .], .], .]
     734            sage: b.sylvestrohedron_pred()
     735            []
     736            sage: b = B([None, B([None, B([None, B([])])])]);b
     737            [., [., [., [., .]]]]
     738            sage: b.sylvestrohedron_pred()
     739            [[[., .], [., [., .]]], [., [[., .], [., .]]], [., [., [[., .], .]]]]
     740        '''
     741        res = []
     742        if self.is_empty(): return []
     743        if not self[1].is_empty(): res.append( self.left_rotate() )
     744        B = self.parent()._element_constructor_
     745        return ( res +
     746                [B( [g, self[1]] ) for g in self[0].sylvestrohedron_pred()] +
     747                [B( [self[0], d] ) for d in self[1].sylvestrohedron_pred()] )
     748
     749    def sylvestrohedron_smaller( self ):
     750        '''
     751        The list of all trees smaller than ''self''.
     752        This is the transitive ideal of its predecessors.
     753       
     754        The tree
     755            __o__
     756           /     \
     757          o       o
     758         / \     /
     759        o   o   o
     760       
     761        has these trees smaller than it:
     762       
     763        T    __o__  ,       _o_  ,        o ,         o,         o,           oT
     764        |   /     \        /   \         /           /          /            / |
     765        |  o       o      o     o      _o_          o          o            o  |
     766        | / \     /      /     /      /   \        / \        /            /   |
     767        |o   o   o      o     o      o     o      o   o      o            o    |
     768        |              /            / \          /          /            /     |
     769        |             o            o   o        o          o            o      |
     770        |                                      /          / \          /       |
     771        |                                     o          o   o        o        |
     772        |                                                            /         |
     773        L                                                           o          J
     774       
     775        TESTS::
     776
     777            sage: B = BinaryTree
     778            sage: b = B([None, B([None, B([None, B([])])])]);b
     779            [., [., [., [., .]]]]
     780            sage: b.sylvestrohedron_smaller()
     781            [[., [., [., [., .]]]], [., [., [[., .], .]]], [., [[., .], [., .]]], [., [[., [., .]], .]], [., [[[., .], .], .]], [[., .], [., [., .]]], [[., .], [[., .], .]], [[., [., .]], [., .]], [[., [., [., .]]], .], [[., [[., .], .]], .], [[[., .], .], [., .]], [[[., .], [., .]], .], [[[., [., .]], .], .], [[[[., .], .], .], .]]
     782            sage: b = B([B([B([B([]), None]), None]), None]);b
     783            [[[[., .], .], .], .]
     784            sage: b.sylvestrohedron_smaller()
     785            [[[[[., .], .], .], .]]
     786        '''
     787        from sage.combinat.tools import transitive_ideal
     788        return transitive_ideal( lambda x: x.sylvestrohedron_pred(), self )
     789
     790    def sylvestrohedron_succ( self ):
     791        '''
     792        Compute the list of successors of ''self'' in the sylvestrohedron.
     793        There is the list of all trees obtains by a right rotate of
     794        one of its nodes.
     795       
     796        The list of successor of
     797       
     798            __o__
     799           /     \
     800          o       o
     801         / \     /
     802        o   o   o
     803
     804        is
     805       
     806        T  _o__     ,   ___o___  ,     _o_    T
     807        | /    \       /       \      /   \   |
     808        |o     _o_    o         o    o     o  |
     809        |     /   \    \       /    / \     \ |
     810        |    o     o    o     o    o   o     o|
     811        |         /      \                    |
     812        L        o        o                   J
     813       
     814        TESTS::
     815
     816            sage: B = BinaryTree
     817            sage: b = B([B([B([B([]), None]), None]), None]);b
     818            [[[[., .], .], .], .]
     819            sage: b.sylvestrohedron_succ()
     820            [[[[., .], .], [., .]], [[[., .], [., .]], .], [[[., [., .]], .], .]]
     821        '''
     822        res = []
     823        if self.is_empty(): return []
     824        B = self.parent()._element_constructor_
     825        if not self[0].is_empty(): res.append( self.right_rotate() )
     826        return ( res +
     827             [B( [g, self[1]] ) for g in self[0].sylvestrohedron_succ()] +
     828             [B( [self[0], d] ) for d in self[1].sylvestrohedron_succ()] )
     829
     830    def hook_length_formula( self ):
     831        '''
     832        Compute the number of permutations which give
     833        by binary search insertion algorithm the same
     834        shape tree (`self`).
     835       
     836        .. MATH::
     837       
     838            f_{eq} (T) = \frac{\mid T\mid !}{\prod_{t\in T} \mid t\mid}
     839       
     840        where `\mid T\mid` is the node number of `T` and `t\in T` the set
     841        of all subtree of `T`.
     842       
     843        There is 20 permutations which give this shape binary tree:
     844       
     845            __o__
     846           /     \
     847          o       o
     848         / \     /
     849        o   o   o
     850       
     851        by the binary search insertion algorithm.
     852         
     853        TESTS::
     854       
     855            sage: b = BinaryTree([[[],[]],[[],None]]); b
     856            [[[., .], [., .]], [[., .], .]]
     857            sage: b.hook_length_formula()
     858            20
     859        '''
     860        from sage.symbolic.ring import SymbolicRing
     861        from sage.misc.functional import integral
     862        from sage.functions.other import factorial
     863        t = SymbolicRing().var( 't' )
     864        def _tmp( self ):
     865            if self.is_empty() : return t ** 0
     866            else : return integral( _tmp( self[0] ) * _tmp( self[1] ), t )
     867        return _tmp( self )( t = 1 ) * factorial( self.node_number() )
     868   
     869    def over(self, bt):
     870        '''
     871        The ``over`` (`/`) operation defined by Loday-Ronco [LodayRonco]_::
     872       
     873              o       __o__       _o_       
     874             / \  /  /     \  =  /   \       
     875            o   o   o       o   o     o     
     876                     \     /           \     
     877                      o   o           __o__ 
     878                                     /     \
     879                                    o       o
     880                                     \     /
     881                                      o   o 
     882       
     883        TESTS::
     884       
     885            sage: b1 = BinaryTree([[],[]])
     886            sage: b2 = BinaryTree([[None,[]],[[],None]])
     887            sage: b1.over(b2)
     888            [[., .], [., [[., [., .]], [[., .], .]]]]
     889        '''
     890        B = self.parent()._element_constructor_
     891        if self.is_empty(): return bt
     892        lab = None
     893        if hasattr(self, "label"):
     894            lab = self.label()
     895        else: return B( [self[0], self[1].over(bt)], lab)
     896   
     897    def __div__(self, bt):
     898        '''
     899        The ``over`` operation on trees.
     900        .. see ::method::*over*.
     901       
     902        TESTS::
     903       
     904            sage: b1 = BinaryTree([[],[]])
     905            sage: b2 = BinaryTree([[None,[]],[[],None]])
     906            sage: b1/b2
     907            [[., .], [., [[., [., .]], [[., .], .]]]]
     908        '''
     909        return self.over(bt)
     910   
     911    def under(self, bt):
     912        '''
     913        The ``under`` (`\`) operation defined by Loday-Ronco [LodayRonco]_::
     914       
     915        TESTS::
     916       
     917            sage: b1 = BinaryTree([[],[[None,[]],None]])
     918            sage: b2 = BinaryTree([[],[None,[]]])
     919            sage: b1.under(b2)
     920            [[[[., .], [[., [., .]], .]], .], [., [., .]]]
     921        '''
     922        B = self.parent()._element_constructor_
     923        if bt.is_empty(): return self
     924        lab = None
     925        if hasattr(bt, "label"):
     926            lab = bt.label()
     927        else: return B( [self.under(bt[0]), bt[1]], lab)
     928       
     929    def _backslash_(self, bt):
     930        '''
     931        The ``under`` operation on trees.
     932        .. see ::method::*under*.
     933       
     934        TESTS::
     935       
     936            sage: b1 = BinaryTree([[],[[None,[]],None]])
     937            sage: b2 = BinaryTree([[],[None,[]]])
     938            sage: b1\b2
     939            [[[[., .], [., .]], [., .]], [[., .], .]]
     940        '''
     941        return self.under(bt)     
    629942
    630943
    631944from sage.structure.parent import Parent