尝试运行以下代码:
$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";
答案 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;
我如何定时:
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万亿组合。我对内存不足感到惊讶!