Algorithm-Networksort-Chooser

 view release on metacpan or  search on metacpan

bin/algorithm-networksort-chooser  view on Meta::CPAN

);

my $opt = {
  'opt' => 'comparators',
  'swap-mode' => 'zero-one',
};

GetOptions($opt, @opt_spec) || die "GetOptions failed";

if ($opt->{help}) {
  require Pod::Perldoc;
  @ARGV = ('-F', $0);
  Pod::Perldoc->run();
}


my $network_size = shift || die "need network size";


die "unknown swap-mode: $opt->{'swap-mode'}"
  if $opt->{'swap-mode'} ne 'zero-one' && $opt->{'swap-mode'} ne 'permutation';

die "validate not implemented yet" if $opt->{validate};



#### Generate candidate networks

my @algos;

if ($opt->{algorithms}) {
  @algos = split ',', $opt->{algorithms};
} else {
  @algos = Algorithm::Networksort::nw_algorithms();
}

my @candidates;

foreach my $algo (@algos) {
  die "unknown algorithm: $algo"
    if !Algorithm::Networksort::nw_algorithm_name($algo);

  my @network = Algorithm::Networksort::Chooser::silence_carps(sub {
    Algorithm::Networksort::nw_comparators($network_size, algorithm => $algo)
  });

  if (!@network) {
    warn "network $algo returned empty comparator list, skipping\n";
    next;
  }

  push @candidates, {
    algo => $algo,
    network => \@network,
  };
}




#### Selection network processing

if ($opt->{median}) {
  die "--selection and --median are incompatible" if defined $opt->{selection};

  $opt->{selection} = int($network_size / 2);
}


if (defined $opt->{selection}) {
  my $selection = [ split(',', $opt->{selection}) ];

  foreach my $ind (@$selection) {
    die "badly formed selection index: $ind" unless $ind =~ /^\d+$/;
    die "selection index $ind is too large for the network size" if $ind >= $network_size;
  }

  foreach my $candidate (@candidates) {
    $candidate->{network} = Algorithm::Networksort::Chooser::build_selection_network($candidate->{network}, $selection);
  }
}




#### Score the generated networks

foreach my $candidate (@candidates) {
  my @network = @{ $candidate->{network} };
  my @grouped_network = Algorithm::Networksort::nw_group(\@network, $network_size, grouping=>'parallel');

  $candidate->{comparators} = (0+@network);
  $candidate->{stages} = (0+@grouped_network);
}




#### Remove 'best' network if it's the same as batcher

my $batcher = [grep { $_->{algo} eq 'batcher' } @candidates]->[0];
my $best = [grep { $_->{algo} eq 'best' } @candidates]->[0];

if ($batcher->{comparators} == $best->{comparators} && $batcher->{stages} == $best->{stages}) {
  @candidates = grep { $_->{algo} ne 'best' } @candidates;
}




#### Sort by optimisation criteria

my @sorted_candidates;

if ($opt->{opt} eq 'comparators') {
  @sorted_candidates = sort {
     ($a->{comparators} <=> $b->{comparators}) || ($a->{stages} <=> $b->{stages})
  } @candidates;
} elsif ($opt->{opt} eq 'stages') {
  @sorted_candidates = sort {
     ($a->{stages} <=> $b->{stages}) || ($a->{comparators} <=> $b->{comparators})



( run in 1.129 second using v1.01-cache-2.11-cpan-e1769b4cff6 )