X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=stv;h=ba89fce1bfd4dcd359d86f80fe0555820db25cd8;hb=2c0d1b163477f5472ca5f2495f5f436d5205889f;hp=fbd7b41050b18f535931223c8b7e0d8534c9f095;hpb=0328306e06758d9fb43cec21611d044eda1acf09;p=appendix-a6.git diff --git a/stv b/stv index fbd7b41..ba89fce 100755 --- a/stv +++ b/stv @@ -84,7 +84,7 @@ sub equalpiles ($@) { return () unless @sorted; my $s = $sorted[0]; my $eqtotal = $s->{Total}; - my $count = 0; + my $count = 0/1; while ($count < @sorted && $sorted[$count]{Total} == $eqtotal) { printf "%7s %10s %s\n", $how, $sorted[$count]{Cand}, pr $sorted[$count]{Total}; @@ -140,7 +140,7 @@ for (;;) { my $placesremain = $places - @elected; unless ($placesremain > 0) { - printf "Complete.\n"; + printf "Complete: @elected\n"; last; } @@ -155,7 +155,7 @@ for (;;) { } foreach my $firstpref (sort keys %sorted) { foreach my $vote (@{ $sorted{$firstpref}{Votes} }) { - votelog $vote, "counted $vote->{Weight} for $firstpref"; + votelog $vote, "counted for $firstpref ".pr $vote->{Weight}; } } my @sorted; @@ -171,7 +171,7 @@ for (;;) { push @stagerecord, { map { ($_->{Cand}, $_->{Total}) } @sorted }; - my $totalvalid = 0; + my $totalvalid = 0/1; my $countvalid = sub { my ($l, $what) = @_; foreach my $s (@$l) { @@ -194,6 +194,8 @@ for (;;) { my $need_to_transfer_surplus = 1; + my @newsurpluses; + # Look for people to elect. # We elect as many as we can, rather than recomputing the (lower) quota # (ERS rules 5.4.9) @@ -206,17 +208,43 @@ for (;;) { printf "%7s %10s ***************\n", 'ELECTED', $s->{Cand}; push @elected, $s->{Cand}; - my $derate = $topvoters / $surplus; - printf "%7s %10s %s\n", 'derate', $s->{Cand}, pr $derate; - foreach my $vote (@{ $s->{Votes} }) { - votelog $vote, "elected $s->{Cand}, derated $derate"; - $vote->{Weight} /= $derate; + votelog $vote, "elected $s->{Cand}"; } - push @surpluses, $s; + + $s->{Surplus} = $surplus; + push @newsurpluses, $s; delete $sorted{ $s->{Cand} }; delete $continuing{ $s->{Cand} }; + $things_update->(); + } + + foreach my $s (@newsurpluses) { + # calculate the transfer value of each surplus + # we do this simultaneously, but based on the number of + # continuing candidates (excluding all the ones elected already) + # ERS rule 5.3.3 + + my $votes = $s->{Votes}; + my $surplus = $s->{Surplus}; + my $transferrable = + sum0 + map { $_->{Weight} } + grep { !!voteliveprefs $_ } + @$votes; + + printf "%7s %10s %s\n", 'xfrable', $s->{Cand}, pr $transferrable; + if ($transferrable > $surplus) { + my $derate = $transferrable / $surplus; + printf "%7s %10s %s\n", 'derate', $s->{Cand}, pr $derate; + foreach my $vote (@{ $s->{Votes} }) { + votelog $vote, "part of surplus, derated ". pr $derate; + $vote->{Weight} /= $derate; + } + } + push @surpluses, $s; + $things_update->(); printf "%7s %10s %s\n", 'surplus', $s->{Cand}, pr $s->{Total}; @@ -231,7 +259,7 @@ for (;;) { # Look for people to eliminate # We eliminate before trying to transfer surpluses # ERS 5.2.5 - my $elimvotebefore = 0; + my $elimvotebefore = 0/1; for (;;) { last unless @sorted;