X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=appendix-a6.git;a=blobdiff_plain;f=parse;h=13fe2f23395fabb16bb0a9b15d3bc6496f9454ea;hp=7ca1ed6aa70817165ca476ac6323a37f4404506e;hb=454c5cdcf27ce0ac28aa9f62585387139690c779;hpb=708d36a1a95409c926ac4be1a343faa41cf09052;ds=sidebyside diff --git a/parse b/parse index 7ca1ed6..13fe2f2 100755 --- a/parse +++ b/parse @@ -27,6 +27,7 @@ while (<>) { s/\s+$//; next if m/^\s*\#/; next unless m/\S/; + next if m/^\s/; if (m/^([A-Z]+)\s*\=\s*(\S.*)$/) { my ($choname, $desc) = ($1,$2); my $cho = addchoice($choname, Desc => $desc); @@ -57,7 +58,7 @@ our @vab; # Go through the voters and construct V(A,B) -print "\nDefeats matrix\n"; +print "\nPreference matrix\n"; foreach my $iv (@invotes) { my ($votestr,$voter) = @$iv; @@ -147,31 +148,41 @@ foreach my $i (0..$#choices) { drop $i, "majority ratio ($vad * $majr->[1] <= $vda * $majr->[0])"; } -my $defeats = Graph::Directed->new; # A.6(4) +print "\nDefeats A.6(4)\n"; + +my $defeats = Graph::Directed->new; sub chremain () { return grep { !$ch[$_]{Dropped} } (0..$#ch); } foreach my $ia (chremain()) { - $defeats->add_vertex($ia); + $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); + my $diff = $vab - $vba; + print "defeat: $choices[$ia] beats $choices[$ib]", + " ($vab > $vba: $diff)\n"; + $defeats->add_edge($choices[$ia],$choices[$ib]); } } +sub chvab ($$) { + my ($ca,$cb) = @_; + my $v = $vab[ $choices{$ca}{Index} ][ $choices{$cb}{Index} ]; + return scalar @$v; +} + 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; } @@ -194,10 +205,10 @@ for (;;) { foreach my $ia (chremain()) { foreach my $ib (chremain()) { - next if $tdefeats->has_edge($ia,$ib); - next if !$tdefeats->has_edge($ib,$ia); + 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); + $schwartz->delete_vertex($choices[$ia]); last; } } @@ -207,6 +218,7 @@ for (;;) { our @weakest = (); foreach my $edge ($schwartz->edges()) { +# print " considering @$edge\n"; if (!@weakest) { # no weakest edges yet } elsif (weaker($edge, $weakest[0])) { @@ -222,14 +234,15 @@ for (;;) { } last unless @weakest; - - printf "weakest defeats %d > %d", - (scalar @{ $vab[$_->[0]][$_->[1]] }), - (scalar @{ $vab[$_->[1]][$_->[0]] }); + + my $w = $weakest[0]; + printf "weakest defeats %d > %d\n", + chvab($w->[0], $w->[1]), + chvab($w->[1], $w->[0]); foreach my $weakest (@weakest) { - my ($ia,$ib) = @$weakest; - print "weakest defeat $choices[$ia] > $choices[$ib]\n"; - $defeats->delete_edge($ia,$ib); + my ($ca,$cb) = @$weakest; + print "weakest defeat $ca > $cb\n"; + $defeats->delete_edge($ca,$cb); } print "defeats within the Schwartz set, round again\n"; @@ -244,7 +257,7 @@ if ($schwartz->vertices() == 1) { print "WINNER IS ONE OF (CASTING VOTE DECIDES):\n"; } -printf " %-5s %s\n", $choices[$_], $ch[$_]{Desc} +printf " %-5s %s\n", $_, $choices{$_}{Desc} foreach ($schwartz->vertices()); print ".\n";