ANALYSIS of ALGORITHMS, Bulletin Board

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Generalized inversions.




Greetings.

Consider all n-choose-k k-tuples of permutation indices < n, where 0,
1, ... n-1 are the elements being permuted. Let the k-tuple be ordered
in ascending order. Such a tuple is a k-inversion of a permutation p
if the k elements referenced by the indices are out of order.

Problems.

1. Use an elementary counting argument to show that the expected
number of k-inversions in a random permutation is

      k!-1  / n \
      ----  |   |
       k!   \ k /.

Verify this result by computing and evaluating the generating
functions of the k-inversions of a permutation of n elements, n>=k.

2. Compute additional statistics like the variance or factorial
moments.

3. The generating functions for ordinary inversions (k=2) factor very
nicely. What can you say about the factors of the generating functions 
when k>2? Is there a closed form product formula for the generating
functions for k>2?

Here are some sample data.

riedel@linuxfast:combinatorics > geninvs.pl 2
[0 1]
2 1 + z
1/2 0.5
[1 2] [0 2] [0 1]
3 1 + 2z + 2z^2 + z^3
9/6 1.5
[2 3] [1 3] [1 2] [0 3] [0 2] [0 1]
4 1 + 3z + 5z^2 + 6z^3 + 5z^4 + 3z^5 + z^6
72/24 3
riedel@linuxfast:combinatorics > geninvs.pl 3
[0 1 2]
3 1 + 5z
5/6 0.833333333333333
[1 2 3] [0 2 3] [0 1 3] [0 1 2]
4 1 + 3z^2 + 6z^3 + 14z^4
80/24 3.33333333333333
[2 3 4] [1 3 4] [1 2 4] [1 2 3] [0 3 4] [0 2 4] [0 2 3] [0 1 4] [0 1 3] [0 1 2]
5 1 + 4z^3 + 6z^5 + 9z^6 + 7z^7 + 24z^8 + 27z^9 + 42z^10
1000/120 8.33333333333333
[3 4 5] [2 4 5] [2 3 5] [2 3 4] [1 4 5] [1 3 5] [1 3 4] [1 2 5] [1 2 4] [1 2 3] 
[0 4 5] [0 3 5] [0 3 4] [0 2 5] [0 2 4] [0 2 3] [0 1 5] [0 1 4] [0 1 3] [0 1 2]
6 1 + 5z^4 + 8z^7 + 6z^8 + 6z^9 + 16z^10 + 12z^11 + 24z^12 + 32z^13 + 37z^14 + 5
4z^15 + 74z^16 + 70z^17 + 133z^18 + 110z^19 + 132z^20
12000/720 16.6666666666667
riedel@linuxfast:combinatorics > geninvs.pl 4
[0 1 2 3]
4 1 + 23z
23/24 0.958333333333333
[1 2 3 4] [0 2 3 4] [0 1 3 4] [0 1 2 4] [0 1 2 3]
5 1 + 4z^3 + 12z^4 + 103z^5
575/120 4.79166666666667
[2 3 4 5] [1 3 4 5] [1 2 4 5] [1 2 3 5] [1 2 3 4] [0 3 4 5] [0 2 4 5] [0 2 3 5] 
[0 2 3 4] [0 1 4 5] [0 1 3 5] [0 1 3 4] [0 1 2 5] [0 1 2 4] [0 1 2 3]
6 1 + 5z^6 + 8z^9 + 12z^10 + 6z^11 + 10z^12 + 63z^13 + 102z^14 + 513z^15
10350/720 14.375
[3 4 5 6] [2 4 5 6] [2 3 5 6] [2 3 4 6] [2 3 4 5] [1 4 5 6] [1 3 5 6] [1 3 4 6] 
[1 3 4 5] [1 2 5 6] [1 2 4 6] [1 2 4 5] [1 2 3 6] [1 2 3 5] [1 2 3 4] [0 4 5 6] 
[0 3 5 6] [0 3 4 6] [0 3 4 5] [0 2 5 6] [0 2 4 6] [0 2 4 5] [0 2 3 6] [0 2 3 5] 
[0 2 3 4] [0 1 5 6] [0 1 4 6] [0 1 4 5] [0 1 3 6] [0 1 3 5] [0 1 3 4] [0 1 2 6] 
[0 1 2 5] [0 1 2 4] [0 1 2 3]
7 1 + 6z^10 + 10z^16 + 18z^19 + 12z^20 + 13z^22 + 24z^24 + 32z^25 + 72z^26 + 10z
^27 + 46z^28 + 142z^29 + 116z^30 + 146z^31 + 196z^32 + 665z^33 + 770z^34 + 2761z
^35
169050/5040 33.5416666666667
[4 5 6 7] [3 5 6 7] [3 4 6 7] [3 4 5 7] [3 4 5 6] [2 5 6 7] [2 4 6 7] [2 4 5 7] 
[2 4 5 6] [2 3 6 7] [2 3 5 7] [2 3 5 6] [2 3 4 7] [2 3 4 6] [2 3 4 5] [1 5 6 7] 
[1 4 6 7] [1 4 5 7] [1 4 5 6] [1 3 6 7] [1 3 5 7] [1 3 5 6] [1 3 4 7] [1 3 4 6] 
[1 3 4 5] [1 2 6 7] [1 2 5 7] [1 2 5 6] [1 2 4 7] [1 2 4 6] [1 2 4 5] [1 2 3 7] 
[1 2 3 6] [1 2 3 5] [1 2 3 4] [0 5 6 7] [0 4 6 7] [0 4 5 7] [0 4 5 6] [0 3 6 7] 
[0 3 5 7] [0 3 5 6] [0 3 4 7] [0 3 4 6] [0 3 4 5] [0 2 6 7] [0 2 5 7] [0 2 5 6] 
[0 2 4 7] [0 2 4 6] [0 2 4 5] [0 2 3 7] [0 2 3 6] [0 2 3 5] [0 2 3 4] [0 1 6 7] 
[0 1 5 7] [0 1 5 6] [0 1 4 7] [0 1 4 6] [0 1 4 5] [0 1 3 7] [0 1 3 6] [0 1 3 5] 
[0 1 3 4] [0 1 2 7] [0 1 2 6] [0 1 2 5] [0 1 2 4] [0 1 2 3]
8 1 + 7z^15 + 12z^25 + 15z^29 + 10z^31 + 8z^34 + 28z^35 + 40z^38 + 41z^41 + 10z^42 + 24z^43 + 44z^44 + 84z^45 + 24z^46 + 89z^47 + 12z^49 + 142z^50 + 136z^51 + 96z^52 + 115z^53 + 333z^54 + 156z^55 + 112z^56 + 312z^57 + 199z^58 + 600z^59 + 573z^60 + 804z^61 + 503z^62 + 885z^63 + 1782z^64 + 1204z^65 + 2148z^66 + 2477z^67 + 5982z^68 + 5545z^69 + 15767z^70
2704800/40320 67.0833333333333


Regards,

Marko Riedel


----------------------------------------------------------------------

#! /usr/bin/perl -w
#

sub fact {
  my ($n) = @_;

  return 1 if $n==0 or $n==1;

  my ($p) = (1);
  $p*=$n-- while $n>1;

  return $p;
}

sub nchoosek {
  my ($n, $k) = @_;

  return fact($n)/fact($k)/fact($n-$k);
}

sub toarray {
  my ($n, $k, $index) = @_;
  my ($m, $l, $pos, $v, @b) = ($n, $k, 0); 

  while($m>$l){
    $v=nchoosek($m-1, $l);

    $m--;
    if($index>=$v){
      push @b, $pos;
      $l--;
      $index-=$v;
    }
    $pos++;
  }
  push @b, $pos++
    while $l-->0;

  return \@b;
}

sub nextperm {
  my ($n, $i, $j) = @_;
  my (@crep, $rem, @source, @perm, $item);
 
  for($j=1; $j<=$n; $j++){
    $rem=$i%$j;
    unshift @crep, $rem;
    $i=($i-$rem)/$j;
  }

  @source=(0..$n-1);
  for($j=0; $j<$n; $j++){
    $item=splice @source, $crep[$j], 1;
    push @perm, $item;
  }

  return \@perm;
}

sub invtuples {
  my ($n, $k) = @_;
  my ($i, @ituples);
  
  for($i=0; $i<nchoosek($n, $k); $i++){
    push @ituples, toarray($n, $k, $i);
  }

  return \@ituples;
}

sub inversions {
  my ($perm, $k, $ituples) = @_;
  my ($count, $i, $tuple) = (0);

  foreach $tuple (@$ituples){
    for($i=0; $i<$k-1; $i++){
      last if 
	$perm->[$tuple->[$i]]>$perm->[$tuple->[$i+1]];
    }
    $count++ if $i<$k-1;
  }

  return $count;
}

sub gf2string {
  my ($poly, @str, $term) = @_;

  foreach my $i ($poly->[0] .. $poly->[1]){
    if(defined $poly->[2][$i]){
      $term=($i == 0 ? '' : ($i == 1 ? 'z' : "z^$i"));
      push @str, 
      ($poly->[2][$i] == 1 ? 
       ($i==0 ? '1' : '') : "$poly->[2][$i]") .	$term;
    } 
  }

  return join ' + ', @str;
}

sub gfat1 {
  my ($poly, $total, $total1) = (@_, 0, 0);

  foreach my $i ($poly->[0] .. $poly->[1]){
    if(defined $poly->[2][$i]){
      $total  += $poly->[2][$i];
      $total1 += $i * $poly->[2][$i];
    }
  }

  return [$total1, $total];
}



MAIN: {
  my ($deg) = @ARGV;

  die "$0 <n>\n" if not defined $deg;

  for(my $n=$deg; $n<=2*$deg; $n++){
    my ($gf, $ituples, $invs) = 
      ([undef, undef, []], invtuples($n, $deg));

    print join ' ' , map {"[@$_]"} @$ituples;
    print "\n";

    for(my $i=0; $i<fact($n); $i++){
      $invs=inversions(nextperm($n, $i), $deg, $ituples);

      $gf->[0]=$invs 
	if not defined $gf->[0] or $gf->[0]>$invs;
      $gf->[1]=$invs 
	if not defined $gf->[1] or $gf->[1]<$invs;
      $gf->[2][$invs]=0 
	if not defined $gf->[2][$invs];
      $gf->[2][$invs]++;
    }

    print "$n " . gf2string($gf) . "\n";
    my ($at1, $f, $pred) = (gfat1($gf), fact($deg));
    print "$at1->[0]/$at1->[1] ";
    $pred=nchoosek($n, $deg)*($f-1)/$f;
    print "$pred\n";
  }
}

Date Prev | Date Next | Date Index | Thread Index