需要更好的数字组合解决方案

时间:2013-03-21 13:41:55

标签: linux perl

我的文件包含以下条目:

1,2
2,3
4,5
1,3
1,4
5,6
...

这告诉id:第一列与第二列匹配。现在我想找到只有所有组合的所有id组。即需要输出以下内容:

1,2,3
4,5
1,4
5,6

我尝试为解决方案编写一个perl脚本:

while(<STDIN>) {
    if(m/^(\d+),(\d+)/) {
        $dub{$1}{$2} = 1;
        $dub{$2}{$1} = 1;
        $hs{$1} = 1;
        $hs{$2} = 1;
    }
}

$i=0;
foreach $a (keys %dub) {
    $grp[$i]{$a} = 1;
    foreach $b (keys %{$dub{$a}}) {
        $grp[$i]{$b} = 1;
        foreach $c (keys %hs) {
            if($c == $a || $c == $b) { next; }
            $flag = 1;
            foreach $d (keys %{$grp[$i]}) {
                if(!$dub{$d}{$c}) {
                    $flag = 0;
                    last;
                }
            }
            $grp[$i]{$c} = 1 if($flag);
        }
        $i++;
    }
}

for($i=0; $i<=$#grp; $i++) {
    print join(",", (keys %{$grp[$i]}))."\n";
}

但这需要花费大量时间来执行。 以上脚本是否有更好的解决方案,算法或性能调整? LAMP中的任何解决方案都值得赞赏。 感谢

编辑:

想一想: (1,2)定义为“1和2相似” (2,3)定义为“2和3相似” (1,4)定义为“1和4相似” (1,3)定义为“1和3相似”

从这些相似之处我得出结论,组(1,2,3)彼此相似但不是组(1,2,3,4)。 为了形成组(1,2,3,4),数据中应该有其他条目如(2,4)和(3,4)。

最后,我想在给定的坐标集中找到所有组。

3 个答案:

答案 0 :(得分:0)

这对我有用:

use Data::Dump;

my @results;
my ($last_a, $last_b) = (0,0);

while(<DATA>) {
    chomp;
    my ($a, $b) = split /,/;
    if( $last_b == $a ) {
        my $last_item = $results[$#results];
        push @$last_item, $b;
    }
    else {
        push @results, [$a, $b];
    }
    ($last_a,  $last_b) = ($a, $b);
}

dd @results; # ([1, 2, 3], [4, 5], [1, 3], [1, 4], [5, 6])

__DATA__
1,2
2,3
4,5
1,3
1,4
5,6

答案 1 :(得分:0)

您还没有真正描述过我们应该使用的算法。我无法理解为什么你的输入产生“1,2,3”和“1,4”而不仅仅是“1,2,3,4”。

但这是你想要的吗?

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my %data;
while (<DATA>) {
  chomp;
  my ($k, $v) = split /,/;
  push @{ $data{$k} }, $v;
}

foreach (sort keys %data) {
  say "$_,", join ',', @{ $data{$_ } };
}

__DATA__
1,2
2,3
4,5
1,3
1,4
5,6

答案 2 :(得分:0)

根据我的理解,{1,2,3}属于同一组,因为所有人都指向彼此({1,2},{2,3},{1,3}存在)。因此,我们可以将此问题减少到在无向图中找到派系,这是NP完全问题。因此,每种解决方案对大数据的效率都非常低。