简体   繁体   English

背包重量>最大尺寸

[英]knapsack weight > max size

I am currently having a query that results like this 我目前正在查询这样的结果

A,B,C,D, E = item A,B,C,D,E =项目

numbers = weight 数字 =重量

  1. A 15 15
  2. B 23 B 23
  3. C 10 C 10
  4. D 8 8天
  5. E 88 E 88

     use Algorithm::Bucketizer; my $b = Algorithm::Bucketizer->new( bucketsize => 30); for my $i (1..10) { $b->add_item($i, 30+$i); } for my $bucket ($b->buckets()) { for my $item ($bucket->items()) { print "Bucket ", $bucket->serial(), ": Item $item\\n"; } print "\\n"; } 

http://search.cpan.org/~mschilli/Algorithm-Bucketizer-0.13/Bucketizer.pm http://search.cpan.org/~mschilli/Algorithm-Bucketizer-0.13/Bucketizer.pm

Using this module I am applying the knapsack algorithm to try to distribute the weights of the items to buckets 使用此模块,我正在应用背包算法来尝试将物品的重量分配到铲斗

my $bucketizer = Algorithm::Bucketizer->new(bucketsize => $size);

The problem is that when the weight is bigger that the size I am searching for that weight gets excluded. 问题是,当重量大于我要搜索的重量时,该重量将被排除。

Example: 例:

bucketsize => 30 bucketsize => 30

  1. E 88 this will get excluded E 88这将被排除

Is there another algorithm that could possibly fix this situation? 是否有另一种算法可以解决这种情况? Or is there a way to modify this one to not exclude the weight that is bigger than the size? 还是有一种方法可以修改此方法以不排除大于尺寸的重量?

Is is it possible to adjust it to work like this? 是否可以将其调整为这样?

If weight > size then fill only a bucket with that weight 如果重量>大小,则仅用该重量填充一个水桶

Just pass the bucket size instead of the actual size for any items over the bucket size. 只需传递存储桶大小,而不是超过存储桶大小的任何项目的实际大小即可。

use Algorithm::Bucketizer qw( );
use List::Util            qw( min );

my @items = ...;
my $bucket_size = 30;

my $bzer = Algorithm::Bucketizer->new( bucketsize => $bucket_size );
for my $i (0..$#items) {
    $bzer->add_item( $i => min($items[$i], $bucket_size) );
}

my @bucketed_items = map { [ $bucket->items() ] } $bzer->buckets();

Alternatively, since you know oversized values will take up an entire bucket, filter them out and add them back to the results. 另外,由于您知道过大的值会占用整个存储桶,因此请过滤掉它们并将其添加回结果中。

use Algorithm::Bucketizer qw( );

my @items = ...;
my $bucket_size = 30;

my $bzer = Algorithm::Bucketizer->new( bucketsize => $bucket_size );
my @bucketed_items;
for my $i (0..$#items) {
    if ($items[$i] >= $bucket_size) {
        push @bucketed_items, [ $i ];
    } else {
        $bzer->add_item( $i => $items[$i] );
    }
}

push @bucketed_items, map { [ $bucket->items() ] } $bzer->buckets();

I don't see where you're stuck. 我看不到你被困在哪里。 You merely add a pre-processing step to the existing algorithm. 您只需将预处理步骤添加到现有算法中即可。 You make a single pass over the weights. 您一次过权重。 When you find one >= bucketsize , simply fill one bucket with that weight. 当您找到一个>= bucketsize ,只需用该重量填充一个水桶即可。 Then remove that weight and the bucket from the problem set and continue as usual. 然后从问题集中卸下那只重物和铲斗,然后照常继续操作。

In your example above, you would start with 在上面的示例中,您将从

bucket[0] = 88
weights = [15, 23, 10, 8]

Continue with your usual solution, appending the 88-kg bucket after you return. 继续执行通常的解决方案,在返回后再附加88千克的水桶。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM