A degree sequence is a sequence of numbers representing the degrees of the vertices of a graph; it is typically presented in descending arrangment, such as {4,4,3,3,2,2}. That degree sequence corresponds to a graph with 6 vertices (A,B,C,D,E,F, let's call them) with the edges: A-B, A-C, A-D, A-E, B-A, B-C, B-D, B-F, C-A, C-B, C-E, D-A, D-B, D-F, E-A, E-C, F-B, F-D. As you can see, A has 4 edges, B has 4 edges, C has 3 edges, D has 3 edges, E has 2 edges, and F has 2 edges. It is possible to have multiple distinct graphs with the same degree sequence ({2,2,2,1,1} is the example shown at the above URL). This function only produces one.
sub graph_from_degree_sequence { # create edge hash and empty graph my $v = 'a'; my %e = map +($v++ => $_), @_; my %g; # algorithm is as follows: while (1) { # sort the vertices of the graph by degree (high to low) my @order = sort { $e{$b} <=> $e{$a} } keys %e; # if the degree of the vertex with the highest # degree is zero, then we're done last if $e{$order[0]} == 0; # otherwise, connect this vertex to the next N # vertices (in order of their degrees), where N is # the degree of the vertex with the highest degree for (1 .. $e{$order[0]}) { # decrement the connected vertex's degree, and # check to see if it's less than zero -- if it # is, this degree sequence cannot produce a graph --$e{$order[$_]} < 0 and return; # create the edges between the two push @{ $g{$order[0]} }, $order[$_]; push @{ $g{$order[$_]} }, $order[0]; } # set the degree of this vertex to zero, which # means it is not to be connected to anymore $e{$order[0]} = 0; } return \%g; }
The code could be modified to remove completed vertices from %e, and then check to ensure that the degree of the vertex with the highest degree is equal to or less than the number of eligible vertices:
sub graph_from_degree_sequence { my $v = 'a'; my %e = map +($v++ => $_), @_; my %g; while (1) { # this will only have non-zero-degree vertices my @order = sort { $e{$b} <=> $e{$a} } keys %e # if there aren't any, we're done or last; # if there aren't enough available vertices to # connect to, this degree sequence is no good return if @order < $e{$order[0]}; for (1 .. $e{$order[0]}) { # each vertex's degree is guaranteed to be at # least 1, so if it becomes 0, make it ineligible --$e{$order[$_]} or delete $e{$order[$_]}; # create the edges between the two push @{ $g{$order[0]} }, $order[$_]; push @{ $g{$order[$_]} }, $order[0]; } delete $e{$order[0]}; } return \%g; }
This second method seems to be faster than the first method in most cases. The trade is deleting hash elements, instead of sorting extra values that can't be used, and (through benchmarking) it appears to pay off.

In reply to Construct Graph from a Degree Sequence by japhy

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.