use strict;
use warnings;
use Algorithm::Knapsack qw( );
use constant DVD_CAPACITY => ...;
# Replace this function
sub process_dvd {
my ($dvd) = @_;
use Data::Dumper qw( Dumper );
local $Data::Dumper::Useqq = 1;
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Indent = 1;
print(Dumper($dvd));
}
sub fill_bag {
my ($bag_size, $items) = @_;
my @weights;
for my $size (keys(%$items)) {
push @weights, ($size) x @{$items->{$size}};
}
return undef if !@weights;
my $knapsack = Algorithm::Knapsack->new(
capacity => $bag_size,
weights => \@weights,
);
$knapsack->compute();
my $solution = ( $knapsack->solutions() )[0]
or die("No solution\n");
my @bag;
for my $size (@$solution) {
my $item = shift( @{$items->{$size}} );
push @bag, $item;
}
return \@bag;
}
{
my %files;
for my $file (...) {
my $size = -s $file;
push @{ $files{$size} }, $file;
}
while (my $dvd = fill_bag(DVD_CAPACITY, \%files)) {
process_dvd($dvd);
}
}
Untested.
Update: Added solution.
Update: Fixed solution.
|