Strawberry Perl:“内存不足!”

时间:2017-03-07 19:30:37

标签: perl memory

尝试运行以下代码:

$combs = combinations(\@set,$k);
while (my $c = $combs->next)
{
        $nrc=1;
}

给我“记忆力不足!”当我按下Ctrl + C(因为它花费的时间过长而且它不应该),如果我传递一个集合,例如,(0..450)和数字组合($ k)为6.这个问题不会发生,比方说,一套0..45和$ k = 6。

请注意,while循环似乎什么都不做,在原始脚本中它打印出组合并递增一个计数器,该计数器将保存组合的总数。但由于我不确定问题是什么,我决定消除它。 我已经阅读了CPAN上的算法:组合,并指出内存使用量很小,所以我不知道发生了什么。

我在Windows 10机器上使用Strawberry Perl 32bit。

感谢。

---------------------完成代码

#!/usr/bin/perl

use List::MoreUtils "uniq";
use Algorithm::Combinatorics "combinations";

my $argc = $#ARGV+1;
my @set;

if ($argc == 0)
{
    print STDERR "Valor minimo de rango: "; # range min
    my $minrange = int <STDIN>;
    print STDERR "Valor maximo de rango: "; #range max
    my $maxrange = int <STDIN>;

    @set = uniq sort { $a <=> $b }($minrange...$maxrange);
}
elsif ($argc == 1)
{
    open(SETFROMFILE,"<$ARGV[0]") or die "No se puedo abrir el fichero, $!";
    chomp(@set = <SETFROMFILE>);
    close(SETFROMFILE);
    @set = uniq sort { $a <=> $b } @set;
}
else
{
    print STDERR "Uso: $0 [file]\n";
    exit;
}

my $nrc = 0;

print STDERR "\n";
print STDERR "Numeros a combinar: "; # get subset
my $k = <STDIN>;

if ($k == 0) { exit; }

$combs = combinations(\@set,$k);

print STDERR "\n";

while (my $c = $combs->next)
{
    print join(";",@$c) . "\n";
    $nrc++;
}

print STDERR "\n";
print STDERR "numero total de combinaciones: $nrc\n";

2 个答案:

答案 0 :(得分:3)

它对我有用。

use strict;
use warnings;

use Algorithm::Combinatorics qw( combinations );

sub show_mem { system('ps', '--no-heading', '-o', 'rss', $$); }

my @set = (0..450);
my $k = 6;

my $count = 0;
#show_mem();
my $combs = combinations(\@set, $k);
#show_mem();
while (my $c = $combs->next) {
   ++$count;
   if (($count % 100_000) == 0) {
      print("$count\n");
      #show_mem();
   }
}

输出:

  784
  784
100000
  776
200000
  784
300000
  788
400000
  776
500000
  780
600000
  784
700000
  768
800000
  784
900000
  784
1000000
  776
...

当然,永远需要通过所有C(451,6)= 11,303,769,578,640组合! (我们在机器上讨论251天 [1] 。)

(注意11,303,769,578,640对于32位整数来说太大了。幸运的是,Perl将切换到使用双精度浮点数,并且这些数字足以容纳所有数字,包括那个数字。 )

顺便说一下,如果您只需要组合数,可以使用

my $count = 1;  $count *= ( @set - $_ + 1 ) / $_ for 1..$k;
  1. 我如何定时:

    use Algorithm::Combinatorics qw( combinations );
    use Time::HiRes              qw( time );
    
    my @set = (0..450);
    my $k = 6;
    
    my $count = 0;
    my $combs = combinations(\@set, $k);
    my $s = time;
    while (my $c = $combs->next) {
       ++$count;
       last if $count == 1_000_000;
    }
    my $e = time;
    print($e-$s, "\n");
    

答案 1 :(得分:-2)

450个中有6个项目的 11.1万亿组合。我对内存不足感到惊讶!