Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: algorithm for 'best subsets'

by Limbic~Region (Chancellor)
on Mar 03, 2005 at 03:19 UTC ( [id://436077]=note: print w/replies, xml ) Need Help??


in reply to algorithm for 'best subsets'

halley,
In between the commercials of Lost and Alias (literally), I came up with the following:
#!/usr/bin/perl use strict; use warnings; my %items = ( a => [ qw/one six/ ], b => [ qw/two three five/ ], c => [ qw/one two five/ ], ); my $tuple = 2; # $common may be 0 my ($common, @list) = tuples(\%items, $tuple); print "Requiring each key contain a minimum of $tuple in common,\n"; print "$common keys is the most that can be found:\n"; print "$_\n" for @list; sub tuples { my ($data, $by) = @_; my ($max, $bit) = (0, 0); my (@key, %tuple); for ( keys %$data ) { for ( @{ $data->{ $_ } } ) { $tuple{ $_ } = '' if ! exists $tuple{ $_ }; vec($tuple{ $_ }, $bit, 1) = 1; } ++$bit; } my $next = combo($by, sort keys %tuple); while ( my @combo = $next->() ) { my $common; $common = defined $common ? $common & $tuple{ $_ } : $tuple{ $ +_ } for @combo; my $tot = unpack("b*", $common) =~ tr/1//; if ( $tot > $max ) { ($max, @key) = ($tot, "@combo"); } elsif ( $tot == $max ) { push @key, "@combo"; } } return ($max, @key); } sub combo { my $by = shift; return sub { () } if ! $by || $by =~ /\D/ || @_ < $by; my @list = @_; my @position = (0 .. $by - 2, $by - 2); my @stop = @list - $by .. $#list; my $end_pos = $#position; my $done = undef; return sub { return () if $done; my $cur = $end_pos; { if ( ++$position[ $cur ] > $stop[ $cur ] ) { $position[ --$cur ]++; redo if $position[ $cur ] > $stop[ $cur ]; my $new_pos = $position[ $cur ]; @position[ $cur .. $end_pos ] = $new_pos .. $new_pos + + $by; } } $done = 1 if $position[0] == $stop[0]; return @list[ @position ]; } }
I think it does what you want but it is quite rough around the edges. I will see about cleaning it up tomorrow. Do you happen to have a bigger sample so that I can benchmark?

Cheers - L~R

Update: Made minor cleanups to code

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://436077]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-19 00:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found