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 { # 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; }
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.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; }
In reply to Construct Graph from a Degree Sequence by japhy
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |