{"id":21651646,"url":"https://github.com/hoytech/algorithm-networksort-chooser","last_synced_at":"2025-03-20T03:59:52.810Z","repository":{"id":6961191,"uuid":"8213480","full_name":"hoytech/Algorithm-Networksort-Chooser","owner":"hoytech","description":"Helper utility for Algorithm::Networksort","archived":false,"fork":false,"pushed_at":"2016-02-16T06:26:18.000Z","size":14,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-25T05:42:46.437Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoytech.png","metadata":{"files":{"readme":"README.pod","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-15T05:55:42.000Z","updated_at":"2023-11-20T08:08:13.000Z","dependencies_parsed_at":"2022-09-15T15:52:01.284Z","dependency_job_id":null,"html_url":"https://github.com/hoytech/Algorithm-Networksort-Chooser","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FAlgorithm-Networksort-Chooser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FAlgorithm-Networksort-Chooser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FAlgorithm-Networksort-Chooser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FAlgorithm-Networksort-Chooser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoytech","download_url":"https://codeload.github.com/hoytech/Algorithm-Networksort-Chooser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244547602,"owners_count":20470103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T07:49:07.986Z","updated_at":"2025-03-20T03:59:52.790Z","avatar_url":"https://github.com/hoytech.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"#!/usr/bin/env perl\n\nuse common::sense;\n\nuse Algorithm::Networksort;\nuse Getopt::Long;\n\nuse Algorithm::Networksort::Chooser;\n\n\nmy @opt_spec = (\n  'opt=s',\n  'median',\n  'selection=s',\n  'all',\n  'validate',\n  'show',\n  'raw',\n  'algorithms=s',\n  'swap-mode=s',\n  'help|h|?',\n);\n\nmy $opt = {\n  'opt' =\u003e 'comparators',\n  'swap-mode' =\u003e 'zero-one',\n};\n\nGetOptions($opt, @opt_spec) || die \"GetOptions failed\";\n\nif ($opt-\u003e{help}) {\n  require Pod::Perldoc;\n  @ARGV = ('-F', $0);\n  Pod::Perldoc-\u003erun();\n}\n\n\nmy $network_size = shift || die \"need network size\";\n\n\ndie \"unknown swap-mode: $opt-\u003e{'swap-mode'}\"\n  if $opt-\u003e{'swap-mode'} ne 'zero-one' \u0026\u0026 $opt-\u003e{'swap-mode'} ne 'permutation';\n\ndie \"validate not implemented yet\" if $opt-\u003e{validate};\n\n\n\n#### Generate candidate networks\n\nmy @algos;\n\nif ($opt-\u003e{algorithms}) {\n  @algos = split ',', $opt-\u003e{algorithms};\n} else {\n  @algos = Algorithm::Networksort::nw_algorithms();\n}\n\nmy @candidates;\n\nforeach my $algo (@algos) {\n  die \"unknown algorithm: $algo\"\n    if !Algorithm::Networksort::nw_algorithm_name($algo);\n\n  my @network = Algorithm::Networksort::Chooser::silence_carps(sub {\n    Algorithm::Networksort::nw_comparators($network_size, algorithm =\u003e $algo)\n  });\n\n  if (!@network) {\n    warn \"network $algo returned empty comparator list, skipping\\n\";\n    next;\n  }\n\n  push @candidates, {\n    algo =\u003e $algo,\n    network =\u003e \\@network,\n  };\n}\n\n\n\n\n#### Selection network processing\n\nif ($opt-\u003e{median}) {\n  die \"--selection and --median are incompatible\" if defined $opt-\u003e{selection};\n\n  $opt-\u003e{selection} = int($network_size / 2);\n}\n\n\nif (defined $opt-\u003e{selection}) {\n  my $selection = [ split(',', $opt-\u003e{selection}) ];\n\n  foreach my $ind (@$selection) {\n    die \"badly formed selection index: $ind\" unless $ind =~ /^\\d+$/;\n    die \"selection index $ind is too large for the network size\" if $ind \u003e= $network_size;\n  }\n\n  foreach my $candidate (@candidates) {\n    $candidate-\u003e{network} = Algorithm::Networksort::Chooser::build_selection_network($candidate-\u003e{network}, $selection);\n  }\n}\n\n\n\n\n#### Score the generated networks\n\nforeach my $candidate (@candidates) {\n  my @network = @{ $candidate-\u003e{network} };\n  my @grouped_network = Algorithm::Networksort::nw_group(\\@network, $network_size, grouping=\u003e'parallel');\n\n  $candidate-\u003e{comparators} = (0+@network);\n  $candidate-\u003e{stages} = (0+@grouped_network);\n}\n\n\n\n\n#### Remove 'best' network if it's the same as batcher\n\nmy $batcher = [grep { $_-\u003e{algo} eq 'batcher' } @candidates]-\u003e[0];\nmy $best = [grep { $_-\u003e{algo} eq 'best' } @candidates]-\u003e[0];\n\nif ($batcher-\u003e{comparators} == $best-\u003e{comparators} \u0026\u0026 $batcher-\u003e{stages} == $best-\u003e{stages}) {\n  @candidates = grep { $_-\u003e{algo} ne 'best' } @candidates;\n}\n\n\n\n\n#### Sort by optimisation criteria\n\nmy @sorted_candidates;\n\nif ($opt-\u003e{opt} eq 'comparators') {\n  @sorted_candidates = sort {\n     ($a-\u003e{comparators} \u003c=\u003e $b-\u003e{comparators}) || ($a-\u003e{stages} \u003c=\u003e $b-\u003e{stages})\n  } @candidates;\n} elsif ($opt-\u003e{opt} eq 'stages') {\n  @sorted_candidates = sort {\n     ($a-\u003e{stages} \u003c=\u003e $b-\u003e{stages}) || ($a-\u003e{comparators} \u003c=\u003e $b-\u003e{comparators})\n  } @candidates;\n} elsif ($opt-\u003e{opt} eq 'swaps') {\n  foreach my $candidate (@candidates) {\n    if ($opt-\u003e{'swap-mode'} eq 'zero-one') {\n      $candidate-\u003e{swaps} = Algorithm::Networksort::Chooser::average_swaps_zero_one($network_size, $candidate-\u003e{network});\n    } elsif ($opt-\u003e{'swap-mode'} eq 'permutation') {\n      $candidate-\u003e{swaps} = Algorithm::Networksort::Chooser::average_swaps_permutation($network_size, $candidate-\u003e{network});\n    }\n  }\n\n  @sorted_candidates = sort {\n     ($a-\u003e{swaps} \u003c=\u003e $b-\u003e{swaps}) || ($a-\u003e{comparators} \u003c=\u003e $b-\u003e{comparators}) || ($a-\u003e{stages} \u003c=\u003e $b-\u003e{stages})\n  } @candidates;\n} else {\n  die \"Unknown optimisation criteria: $opt-\u003e{opt}\";\n}\n\n\n\n\n#### Output results\n\n\nif ($opt-\u003e{raw}) {\n  print \"[\";\n  print join(',', map { \"[$_-\u003e[0],$_-\u003e[1]]\" } @{ $sorted_candidates[0]-\u003e{network} });\n  print \"]\\n\";\n  exit;\n}\n\n\nprint \"Network size: $network_size\\n\";\n\nif ($opt-\u003e{median}) {\n  print \"Network type: Median network\\n\";\n} elsif ($opt-\u003e{selection}) {\n  print \"Network type: Selection network: $opt-\u003e{selection}\\n\";\n} else {\n  print \"Network type: Sorting network\\n\";\n}\n\nprint \"\\n\";\n\nprint \"Optimisation criteria: $opt-\u003e{opt}\\n\";\n\nprint \"\\n\";\n\nprint \"Optimal network:\\n\";\n\noutput_network($sorted_candidates[0]);\n\nif ($opt-\u003e{all}) {\n  print \"\\nAdditional candidate networks:\\n\";\n  foreach my $network (@sorted_candidates[1..$#sorted_candidates]) {\n    output_network($network);\n  }\n}\n\n\n\nsub output_network {\n  my $network = shift;\n\n  print \"  Algorithm \\\"$network-\u003e{algo}\\\":\\n\";\n  print \"    Comparators: $network-\u003e{comparators}\\n\";\n  print \"    Stages: $network-\u003e{stages}\\n\";\n  print \"    Avg swaps: $network-\u003e{swaps}\\n\" if exists $network-\u003e{swaps};\n\n  if ($opt-\u003e{show}) {\n    print \"\\n\";\n    print Algorithm::Networksort::nw_graph($network-\u003e{network}, $network_size, graph =\u003e 'text');\n  }\n}\n\n\n\n\n__END__\n\n=encoding utf-8\n\n=head1 NAME\n\nalgorithm-networksort-chooser - Helper utility for Algorithm::Networksort\n\n=head1 SYNOPSIS\n\nThe C\u003calgorithm-networksort-chooser\u003e script helps you find the best sorting network for your particular use-case.\n\n    $ algorithm-networksort-chooser 9  ## find best sorting network for array size 9\n    $ algorithm-networksort-chooser 9 --all  ## show all candiate networks\n    $ algorithm-networksort-chooser 9 --algorithms=batcher,bitonic  ## only consider batcher and bitonic algos\n\n    $ algorithm-networksort-chooser 9 --opt=comparators  ## optimise for comparators (default)\n    $ algorithm-networksort-chooser 9 --opt=stages  ## optimise for stages\n    $ algorithm-networksort-chooser 9 --opt=swaps  ## optimise for average swaps\n\n    $ algorithm-networksort-chooser 9 --median  ## best median network\n    $ algorithm-networksort-chooser 9 --selection=4  ## also best median network\n    $ algorithm-networksort-chooser 9 --selection=0,1,2  ## top-3 elements selection net\n\n    $ algorithm-networksort-chooser 9 --validate  ## run 0-1 validation test\n    $ algorithm-networksort-chooser 9 --show  ## show network as ASCII diagram\n    $ algorithm-networksort-chooser 9 --raw  ## show network as raw comparators\n\n\n\n=head1 DESCRIPTION\n\nThis module uses L\u003cAlgorithm::Networksort\u003e to experiment with sorting networks.\n\nL\u003cIntroduction To Sorting Networks|http://hoytech.github.io/sorting-networks/\u003e\n\nBy default this script examines the output of all implemented algorithms and the currently best known special-cases, and chooses the one that best meets your specified criteria.\n\nThis module allows you to trim sorting networks into median or selection networks.\n\nYou can then choose the optimal net based on comparators (total number of operations) or on stages (number of operations considering parallelism).\n\nNormally the output is something like this:\n\n    $ algorithm-networksort-chooser --median 22\n    Network size: 22\n    Network type: Median network\n\n    Optimisation criteria: stages\n\n    Optimal network:\n      Algorithm \"best\":\n        Comparators: 86\n        Stages: 12\n\nFor the description of the various algorithms and best-known special cases, see L\u003cAlgorithm::Networksort\u003e's documentation and source code.\n\nIn order to use this output in another program, there is a C\u003c--raw\u003e switch. Its output is C\u003ceval\u003eable perl and is valid JSON:\n\n    $ algorithm-networksort-chooser --median 7 --raw\n    [[0,4],[1,5],[2,6],[0,2],[1,3],[4,6],[2,4],[3,5],[0,1],[2,3],[4,5],[1,4],[3,6],[3,4]]\n\nL\u003cAlgorithm::Networksort\u003e's ASCII output can be seen with C\u003c--show\u003e:\n\n    $ algorithm-networksort-chooser --median 7 --show\n    Network size: 7\n    Network type: Median network\n\n    Optimisation criteria: comparators\n\n    Optimal network:\n      Algorithm \"batcher\":\n        Comparators: 14\n        Stages: 6\n\n    o--^--------^-----^-----------------o\n       |        |     |                  \n    o--|--^-----|--^--v--------^--------o\n       |  |     |  |           |         \n    o--|--|--^--v--|--^-----^--|--------o\n       |  |  |     |  |     |  |         \n    o--|--|--|-----v--|--^--v--|--^--^--o\n       |  |  |        |  |     |  |  |   \n    o--v--|--|--^-----v--|--^--v--|--v--o\n          |  |  |        |  |     |      \n    o-----v--|--|--------v--v-----|-----o\n             |  |                 |      \n    o--------v--v-----------------v-----o\n\n\nThe C\u003c--all\u003e switch shows all networks that were considered.\n\nSometimes which algorithm or which best special-case network is surprising. For instance, selecting the top-3 elements in a size-9 array is best done by adapting Hibbard's algorithm, even though there is a special best (by comparators) network for size 9:\n\n    $ algorithm-networksort-chooser 9 --selection=0,1,2 --all\n    Network size: 9\n    Network type: Selection network: 0,1,2\n\n    Optimisation criteria: comparators\n\n    Optimal network:\n      Algorithm \"hibbard\":\n        Comparators: 18\n        Stages: 7\n\n    Additional candidate networks:\n      Algorithm \"batcher\":\n        Comparators: 20\n        Stages: 8\n      Algorithm \"bosenelson\":\n        Comparators: 22\n        Stages: 10\n      Algorithm \"best\":\n        Comparators: 23\n        Stages: 9\n      Algorithm \"bitonic\":\n        Comparators: 24\n        Stages: 8\n      Algorithm \"bubble\":\n        Comparators: 36\n        Stages: 15\n\n\n\n\n=head1 FUTURE IDEAS\n\nAlgorithm::Networksort::Validate::XS\n\n\n\n=head1 SEE ALSO\n\nL\u003cIntroduction To Sorting Networks|http://hoytech.github.io/sorting-networks/\u003e\n\nL\u003cAlgorithm-Networksort-Chooser github repo|https://github.com/hoytech/Algorithm-Networksort-Chooser\u003e\n\nJohn Gamble's L\u003cAlgorithm-Networksort github repo|https://github.com/jgamble/Algorithm-Networksort\u003e\n\n\n\n=head1 AUTHOR\n\nDoug Hoyte, C\u003c\u003c \u003cdoug@hcsw.org\u003e \u003e\u003e\n\n=head1 COPYRIGHT \u0026 LICENSE\n\nCopyright 2013-2016 Doug Hoyte.\n\nThis module is licensed under the same terms as perl itself.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoytech%2Falgorithm-networksort-chooser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoytech%2Falgorithm-networksort-chooser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoytech%2Falgorithm-networksort-chooser/lists"}