Graph-Maker-Other
view release on metacpan or search on metacpan
devel/lib/Graph/Maker/Permutations.pm view on Meta::CPAN
The default C<rel_type =E<gt> 'transpose'> is graph edges where swapping two
elements in the permutation gives a lexicographically bigger permutation.
from x ... y transpose
to y ... x values x<y
--> 2,1,3 --> 2,3,1 --\
/ \ ^ v N => 3
1,2,3 --------X-------> 3,2,1 rel_type => "transpose"
\ / v ^
--> 1,3,2 --> 3,1,2 --/
Each permutation has binomial(N,2) element pairs, and across all
permutations they are, by symmetry, half smaller-bigger and half
bigger-smaller so
num edges = N!*N*(N-1)/4
= 0,0,1,9,72,600,5400,... (A001809)
=cut
# GP-DEFINE transpose_num_edges(N) = N!*N*(N-1)/4;
# GP-Test vector(7,N,N--; transpose_num_edges(N)) == [0,0,1,9,72,600,5400]
#
# The "transpose_..." relation types below restrict to just some transposes so
# are edge subsets of full "transpose".
=pod
=head2 Transpose Cover
Option C<rel_type =E<gt> 'transpose_cover'> restricts to those transposes
which are cover relations of the transposes (so the Hasse diagram). This
means if a path u -E<gt> z -E<gt> ... -E<gt> v exists then omit direct u
-E<gt> v. In N=3 this means no edge 123 -E<gt> 321.
--> 2,1,3 --> 2,3,1 --\
/ \ ^ v N => 3
1,2,3 X 3,2,1 rel_type => "transpose_cover"
\ / v ^
--> 1,3,2 --> 3,1,2 --/
A cover is when the x...y swap has, between those locations, no values
between x and y. If such an intermediate t then could do the x,y swap by
three transposes x,t, t,y, x,t, which in each case are lex increases. This
is seen across the top of N=3 above. Other combinations using t are
possible too. The number of covers is
num edges = sum 1<=i<j<N of N!/(j-i+1)
= 0,0,1,8,58,444,3708,... (A002538)
This sum is per David Callan in OEIS A002538. Elements i and j are to be
swapped. Those and the i+1,i+2,...,j-1 values between them are ordered
(j-i+1)! ways (within the whole permutation). But cannot have intermediate
values between i,j. Perms of i..j with i,j adjacent are only (j-i)!, so
fraction (j-i)!/(j-i+1)! = 1/(j-i+1) of all N! perms.
=cut
# GP-DEFINE \\ formula per A002538 but starting N=2 at value=1
# GP-DEFINE transpose_cover_num_edges(N) = /* per A002538 */ \
# GP-DEFINE if(N<=1,0, (N+1)*transpose_cover_num_edges(N-1) + (N-1)*(N-1)!);
# GP-Test vector(7,N,N--; transpose_cover_num_edges(N)) == [0,0,1,8,58,444,3708]
#
# new element N at any of N positions
# covers in N-1 still good so N*covers(N-1)
# covers i to N has new N bigger
# so x ... N with N at any position
#
# sum N* for i<j<N
# then j=N
# vector(10,N, sum(i=1,N-1, N!/(N-i+1)))
# vector(10,N, sum(i=1,N-1, N!/(N-i+1)) + N*transpose_cover_num_edges(N-1))
# A001705 gen Stirling
# vector(10,N, sum(i=1,N-1, N!/(N-i+1)) - transpose_cover_num_edges(N-1))
=pod
An "inversion" in a permutation is a pair of out-of-order elements, so x...y
with xE<gt>y. A cover transpose increases the number of inversions by +1.
A transpose of x,y with xE<lt>y goes to yE<gt>x so +1 inversions. If an
element tE<gt>y is between them then +1 inversion for new t,x position but
-1 for new y,t. Similarly the other way for an element smaller E<lt>x. An
element t between x and y values would be +2 inversions. So an equivalent
definition is to take cover as step by +1 inversion.
=head2 Transpose Adjacent
Option C<rel_type =E<gt> 'transpose_adjacent'> restricts to swapping an
adjacent pair of elements. This is the weak Bruhat order.
from x y transpose_adjacent
to y x values x<y
--> 2,1,3 --> 2,3,1 --\
/ v N => 3
1,2,3 3,2,1 rel_type => "transpose_cover"
\ ^
--> 1,3,2 --> 3,1,2 --/
Each of the N-1 non-last elements has a next neighbour and by symmetry they
are half smaller-bigger and half bigger-smaller so
num edges = N!*(N-1)/2, or 0 if N=0
= 0,0,1,6,36,240,1800,... (A001286)
=cut
# GP-DEFINE transpose_adjacent_num_edges(N) = if(N==0,0, N!*(N-1)/2);
# GP-Test vector(7,N,N--; transpose_adjacent_num_edges(N)) == \
# GP-Test [0,0,1,6,36,240,1800]
=pod
=head2 Transpose Cyclic
Option C<rel_type =E<gt> 'transpose_cyclic'> restricts to transposing an
adjacent pair of elements, with adjacent including wraparound so first and
last can swap.
( run in 0.417 second using v1.01-cache-2.11-cpan-39bf76dae61 )