X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=appendix-a6.git;a=blobdiff_plain;f=parse;h=a1ce9c587747aa906135ea656f98b04ccb3257fe;hp=c04d33b0083cea24f5495e5b35d9e2318083fe1e;hb=0651d6b71fb087495c174faac376b5c9c60c0bfc;hpb=0627d3e30d981724e0f97939b551d59a8e167d79 diff --git a/parse b/parse index c04d33b..a1ce9c5 100755 --- a/parse +++ b/parse @@ -57,6 +57,8 @@ our @vab; # Go through the voters and construct V(A,B) +print "\nDefeats matrix\n"; + foreach my $iv (@invotes) { my ($votestr,$voter) = @$iv; eval { @@ -122,7 +124,7 @@ sub drop ($$) { $ch[$i]{Dropped} = $why; } -print "# quorum A.6(2)\n"; +print "\nQuorum A.6(2) (quorum is $quorum)\n"; foreach my $i (0..$#choices) { next if $ch[$i]{Dropped}; @@ -132,7 +134,7 @@ foreach my $i (0..$#choices) { drop $i, "quorum ($v < $quorum)"; } -print "# maj. ratio A.6(3)\n"; +print "\nMajority ratio A.6(3)\n"; foreach my $i (0..$#choices) { next if $ch[$i]{Dropped}; @@ -147,24 +149,34 @@ foreach my $i (0..$#choices) { my $defeats = Graph::Directed->new; # A.6(4) -foreach my $ia (0..$#ch) { - foreach my $ib (0..$#ch) { - my $vab = $vab[$ia][$ib]; - my $vba = $vab[$ib][$ia]; +sub chremain () { + return grep { !$ch[$_]{Dropped} } (0..$#ch); +} + +foreach my $ia (chremain()) { + $defeats->add_vertex($choices[$ia]); + foreach my $ib (chremain()) { + my $vab = scalar @{ $vab[$ia][$ib] }; + my $vba = scalar @{ $vab[$ib][$ia] }; next unless $vab > $vba; print "defeat: $choices[$ia] beats $choices[$ib] ($vab > $vba)\n"; - $defeats->add_vertex($ia,$ib); + $defeats->add_vertex($choices[$ia],$choices[$ib]); } } +sub chvab ($$) { + my ($ca,$cb) = @_; + return $vab[ $choices{$ca}{Index} ][ $choices{$cb}{Index} ]; +} + sub weaker ($$) { # A.6(7)(1) my ($def1,$def2) = @_; - my ($ia,$ix) = @$def1; - my ($ib,$iy) = @$def1; - return 1 if $vab[$ia][$ix] < $vab[$ib][$iy]; - return 1 if $vab[$ia][$ix] == $vab[$ib][$iy] - && $vab[$ix][$ia] > $vab[$iy][$ib]; + my ($ca,$cx) = @$def1; + my ($cb,$cy) = @$def1; + return 1 if chvab($ca, $cx) < chvab($cb, $cy); + return 1 if chvab($ca, $cx) == chvab($cb, $cy) + && chvab($cx, $ca) > chvab($cy, $cb); return 0; } @@ -173,29 +185,33 @@ our $schwartz; for (;;) { # loop from A6(5) - print "# transitive closure A.6(5)\n"; + print "defeats graph: $defeats\n"; + + print "\nTransitive closure A.6(5)\n"; my $tdefeats = $defeats->transitive_closure(); - print "# schwartz set A.6(6)\n"; + print "closure graph: $tdefeats\n"; + + print "\nSchwartz set A.6(6)\n"; $schwartz = $defeats->copy(); - foreach my $ia (0..$#ch) { - foreach my $ib (0..$#ch) { - next if $tdefeats->has_edge($ia,$b); - next if !$tdefeats->has_edge($b,$ia); + foreach my $ia (chremain()) { + foreach my $ib (chremain()) { + next if $tdefeats->has_edge($choices[$ia],$choices[$ib]); + next if !$tdefeats->has_edge($choices[$ib],$choices[$ia]); print "not in Schwartz set: $choices[$ia] because $choices[$ib]\n"; $schwartz->delete_vertex($ia); last; } } - print "# dropping weakest defeats A.6(7)\n"; + print "\nDropping weakest defeats A.6(7)\n"; our @weakest = (); - foreach my $edge (@{ $schwartz->edges() }) { + foreach my $edge ($schwartz->edges()) { if (!@weakest) { # no weakest edges yet } elsif (weaker($edge, $weakest[0])) { @@ -213,21 +229,28 @@ for (;;) { last unless @weakest; printf "weakest defeats %d > %d", - (scalar @{ $vab[$_->[0]][$_->[1]]) }, - (scalar @{ $vab[$_->[1]][$_->[0]]) }; + (scalar @{ $vab[$_->[0]][$_->[1]] }), + (scalar @{ $vab[$_->[1]][$_->[0]] }); foreach my $weakest (@weakest) { my ($ia,$ib) = @$weakest; print "weakest defeat $choices[$ia] > $choices[$ib]\n"; - $defeats->delete_edge($ia,$ib); + $defeats->delete_edge($choices[$ia],$choices[$ib]); } - print "# defeats within the Schwartz set, round again\n"; + print "defeats within the Schwartz set, round again\n"; } -print "# no defeats within the Schwartz set\n"; -print "FINAL SCHWARTZ SET:\n"; +print "no defeats within the Schwartz set\n"; +print "final schwartz set:\n\n"; + +if ($schwartz->vertices() == 1) { + print "WINNER IS:\n"; +} else { + print "WINNER IS ONE OF (CASTING VOTE DECIDES):\n"; +} -print $choices[$_] foreach (@{ $schwartz->nodes() }); +printf " %-5s %s\n", $_, $choices{$_}{Desc} + foreach ($schwartz->vertices()); print ".\n";