chiark
/
gitweb
/
~ian
/
appendix-a6.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
be8af59
)
stv: fix tiebreaks
author
Ian Jackson
<ijackson@chiark.greenend.org.uk>
Mon, 1 Aug 2016 16:45:39 +0000
(17:45 +0100)
committer
Ian Jackson
<ijackson@chiark.greenend.org.uk>
Mon, 1 Aug 2016 16:45:39 +0000
(17:45 +0100)
stv
patch
|
blob
|
history
diff --git
a/stv
b/stv
index 3942b6b175f488c6dbbedfd6338ded2560eb450c..03f16d8d0e418d2488e30a4011f1e92b9a6342b0 100755
(executable)
--- a/
stv
+++ b/
stv
@@
-95,18
+95,36
@@
sub equalpiles ($@) {
sub historically_prefer ($@) {
my ($signum, @choices) = @_;
sub historically_prefer ($@) {
my ($signum, @choices) = @_;
+ # $signum==+1 means choose candidates with more early preferences
return $choices[0] if @choices < 2;
my $compare = sub {
foreach my $sr (@stagerecord) {
return $choices[0] if @choices < 2;
my $compare = sub {
foreach my $sr (@stagerecord) {
- my $d =
$sr->{ $a->{Cand} } <=> $sr->{ $b->{Cand} }
;
- return $d * $signum if $d;
+ my $d =
($sr->{ $a->{Cand} }//0) <=> ($sr->{ $b->{Cand} }//0)
;
+ return
-
$d * $signum if $d;
}
return 0;
};
@choices = sort $compare @choices;
}
return 0;
};
@choices = sort $compare @choices;
+
+ print DEBUG "historically_prefer\n",
+ Data::Dumper->Dump([\@choices, \@stagerecord],
+ [qw(_@choices _@stagerecord)]);
+
+ foreach my $s (@choices) {
+ my $c = $s->{Cand};
+ printf " %6s %10s |", 'tiebrk', $c;
+ foreach my $sr (@stagerecord) {
+ my $p = pr($sr->{$c} // 0);
+ $p =~ s/\.0+\b//g;
+ $p =~ s/ //g;
+ print "$p|";
+ }
+ print "\n";
+ }
+
$a = $choices[0];
my $numequal = 1;
for (;;) {
$a = $choices[0];
my $numequal = 1;
for (;;) {
@@
-161,7
+179,7
@@
for (;;) {
}
my @sorted;
my $things_update = sub {
}
my @sorted;
my $things_update = sub {
- foreach my $s (
@surpluses,
values %sorted) {
+ foreach my $s (values %sorted) {
$s->{Total} = sum0 map { $_->{Weight} } @{ $s->{Votes } };
}
@sorted = nsort_by { -$_->{Total} } values %sorted;
$s->{Total} = sum0 map { $_->{Weight} } @{ $s->{Votes } };
}
@sorted = nsort_by { -$_->{Total} } values %sorted;
@@
-205,6
+223,7
@@
for (;;) {
my $topvoters = $s->{Total};
my $surplus = $topvoters - $quota;
last unless $surplus >= 0;
my $topvoters = $s->{Total};
my $surplus = $topvoters - $quota;
last unless $surplus >= 0;
+ last unless $placesremain;
my @elect = equalpiles 'elect?', @sorted;
my @elect = equalpiles 'elect?', @sorted;
@@
-226,6
+245,7
@@
for (;;) {
push @newsurpluses, $s;
delete $sorted{ $s->{Cand} };
delete $continuing{ $s->{Cand} };
push @newsurpluses, $s;
delete $sorted{ $s->{Cand} };
delete $continuing{ $s->{Cand} };
+ $placesremain--;
}
$things_update->();
}
$things_update->();
@@
-245,15
+265,18
@@
for (;;) {
grep { !!voteliveprefs $_ }
@$votes;
grep { !!voteliveprefs $_ }
@$votes;
+ my $derate = 1/1;
printf "%7s %10s %s\n", 'xfrable', $s->{Cand}, pr $transferrable;
if ($transferrable > $surplus) {
printf "%7s %10s %s\n", 'xfrable', $s->{Cand}, pr $transferrable;
if ($transferrable > $surplus) {
-
my
$derate = $transferrable / $surplus;
+ $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;
}
}
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;
}
}
+ $s->{Total} = $transferrable / $derate;
+
push @surpluses, $s;
$things_update->();
push @surpluses, $s;
$things_update->();