Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Random Trees

by FoxtrotUniform (Prior)
on Feb 11, 2003 at 01:10 UTC ( #234289=snippet: print w/replies, xml ) Need Help??
Description:

Ever needed (or wanted) to generate a tree (in this case, a graph on n vertices with n-1 edges) at random? Dismayed that the obvious method (adding a 1-2 edge, then randomly picking a vertex to connect 3 to, then 4) doesn't produce all possible trees (1-3-2 simply can't be done)? Your prayers are answered! This code uses Prüfer sequences (for which Google generates no useful introductory hits) to describe trees... turns out you can rank the nn-2 labelled trees, generate the Prüfer sequence corresponding to that rank, then reconstruct the tree from the sequence.

This code is pretty much a straight implementation of the pseudocode in Combinatorial Algorithms: Generation, Enumeration, and Search.

use strict;
use POSIX qw(floor);
use Data::Dumper;

# rank_to_prufer(r, n)
# Generates the Prufer sequence for the n-vertex tree of rank
#  r.
sub rank_to_prufer
{
  my ($rank, $n) = @_;
  my @prufer     = ();

  for(my $i = $n - 2; $i > 0; $i--) {
    my   $new = $rank % $n + 1;
    unshift @prufer, $new;
    $rank = POSIX::floor(($rank - $new + 1) / $n);
  }

  return @prufer;
}

# prufer_to_tree(seq)
# Generates the tree corresponding to the Prufer sequence seq
sub prufer_to_tree
{
  my @prufer  = @_;
  my $n       = scalar @prufer + 2;
  my @edges   = ();
  my @degrees = (1) x $n;

  push @prufer, 1;

  for (0 .. $n - 3) {
    my $i = $prufer[$_] - 1;
    $degrees[$i]++;
  }

  for (0 .. $n - 2) {
    my $x = $n-1;
    while($degrees[$x] != 1) {$x--;}
    my $y = $prufer[$_] - 1;
    $degrees[$x]--;
    $degrees[$y]--;
    my @edge = ($x+1, $y+1);
    push @edges, \@edge;
  }

  return @edges;
}

# example call -- generate a random 6-vertex tree
my @tree = &prufer_to_tree(&rank_to_prufer(rand(1296), 6));
Replies are listed 'Best First'.
Re: Random Trees
by dmitri (Priest) on Feb 11, 2003 at 20:16 UTC

      That was actually the first thing I googled for. Apparently, though, "Prufer" is the more common Anglicism, and neither produced any useful introductory documents.

      So what the hell, I'll give it a shot.

      The idea is to generate a unique sequence for each labelled tree on N vertices. What you end up doing is removing vertices one at a time, starting with the highest label leaf vertex (you can start with the lowest, it doesn't matter, as long as you're consistent). When you remove a vertex, you add the label of the vertex it was adjacent to to the sequence. Keep going until you only have two vertices left. You've got a Prüfer sequence!

      So, for example, if you have the tree:

      1--3--2--4 |\ | 5 6

      You'd start by removing vertex 6 (highest label leaf vertex). Add 3 to the Prüfer sequence (which is now 3), and you have the tree:

      1--3--2--4 \ 5

      Now remove 5 and add 3, you have (3, 3) and the tree:

      1--3--2--4

      Remove 4, add 2, you get (3, 3, 2) -- eventually, you end up with (3, 3, 2, 3) and the tree 1--3.

      It turns out that there's a one-to-one correspondence between labelled trees and Prüfer sequences, so each Prüfer sequence uniquely determines a tree. (Which is why the code I posted earlier works.)

      Going from a Prüfer sequence to a tree is left as an exercise for the reader. :-)

      --
      F o x t r o t U n i f o r m
      Found a typo in this node? /msg me
      The hell with paco, vote for Erudil!

Re: Random Trees
by prashantpokhriyal (Novice) on Sep 30, 2017 at 15:29 UTC
    when I'm using vertex = 1 it is returning me one edge, which can't be possible.
      Yeah, it doesn't work for $n=1, because it's not possible for rank_to_prufer to return a list of length $n-2==-1. I suppose it should just die in that case. Is this a big problem for you?

      Also, this thread is 14 years old, and Foxtrot hasn't been here in almost 11. Maybe threads should be auto-locked at some point?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://234289]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2017-11-19 18:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:













    Results (282 votes). Check out past polls.

    Notices?