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; } #### 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; }