Necklaces¶
The algorithm used in this file comes from
Sawada, Joe. A fast algorithm to generate necklaces with fixed content, Theoretical Computer Science archive Volume 301, Issue 1-3 (May 2003) doi:10.1016/S0304-3975(03)00049-5
- sage.combinat.necklace.Necklaces(content)[source]¶
Return the set of necklaces with evaluation
content
.A necklace is a list of integers that such that the list is the smallest lexicographic representative of all the cyclic shifts of the list.
See also
INPUT:
content
– list or tuple of nonnegative integers
EXAMPLES:
sage: Necklaces([2,1,1]) Necklaces with evaluation [2, 1, 1] sage: Necklaces([2,1,1]).cardinality() 3 sage: Necklaces([2,1,1]).first() [1, 1, 2, 3] sage: Necklaces([2,1,1]).last() [1, 2, 1, 3] sage: Necklaces([2,1,1]).list() [[1, 1, 2, 3], [1, 1, 3, 2], [1, 2, 1, 3]] sage: Necklaces([0,2,1,1]).list() [[2, 2, 3, 4], [2, 2, 4, 3], [2, 3, 2, 4]] sage: Necklaces([2,0,1,1]).list() [[1, 1, 3, 4], [1, 1, 4, 3], [1, 3, 1, 4]]
>>> from sage.all import * >>> Necklaces([Integer(2),Integer(1),Integer(1)]) Necklaces with evaluation [2, 1, 1] >>> Necklaces([Integer(2),Integer(1),Integer(1)]).cardinality() 3 >>> Necklaces([Integer(2),Integer(1),Integer(1)]).first() [1, 1, 2, 3] >>> Necklaces([Integer(2),Integer(1),Integer(1)]).last() [1, 2, 1, 3] >>> Necklaces([Integer(2),Integer(1),Integer(1)]).list() [[1, 1, 2, 3], [1, 1, 3, 2], [1, 2, 1, 3]] >>> Necklaces([Integer(0),Integer(2),Integer(1),Integer(1)]).list() [[2, 2, 3, 4], [2, 2, 4, 3], [2, 3, 2, 4]] >>> Necklaces([Integer(2),Integer(0),Integer(1),Integer(1)]).list() [[1, 1, 3, 4], [1, 1, 4, 3], [1, 3, 1, 4]]
- class sage.combinat.necklace.Necklaces_evaluation(content)[source]¶
Bases:
UniqueRepresentation
,Parent
Necklaces with a fixed evaluation (content).
INPUT:
content
– list or tuple of nonnegative integers
- cardinality()[source]¶
Return the number of integer necklaces with the evaluation
content
.The formula for the number of necklaces of content \(\alpha\) a composition of \(n\) is:
\[\sum_{d|gcd(\alpha)} \phi(d) \binom{n/d}{\alpha_1/d, \ldots, \alpha_\ell/d},\]where \(\phi(d)\) is the Euler \(\phi\) function.
EXAMPLES:
sage: Necklaces([]).cardinality() 0 sage: Necklaces([2,2]).cardinality() 2 sage: Necklaces([2,3,2]).cardinality() 30 sage: Necklaces([0,3,2]).cardinality() 2
>>> from sage.all import * >>> Necklaces([]).cardinality() 0 >>> Necklaces([Integer(2),Integer(2)]).cardinality() 2 >>> Necklaces([Integer(2),Integer(3),Integer(2)]).cardinality() 30 >>> Necklaces([Integer(0),Integer(3),Integer(2)]).cardinality() 2
Check to make sure that the count matches up with the number of necklace words generated.
sage: comps = [[],[2,2],[3,2,7],[4,2],[0,4,2],[2,0,4]] + Compositions(4).list() sage: ns = [Necklaces(comp) for comp in comps] sage: all(n.cardinality() == len(n.list()) for n in ns) # needs sage.libs.pari True
>>> from sage.all import * >>> comps = [[],[Integer(2),Integer(2)],[Integer(3),Integer(2),Integer(7)],[Integer(4),Integer(2)],[Integer(0),Integer(4),Integer(2)],[Integer(2),Integer(0),Integer(4)]] + Compositions(Integer(4)).list() >>> ns = [Necklaces(comp) for comp in comps] >>> all(n.cardinality() == len(n.list()) for n in ns) # needs sage.libs.pari True