line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
658
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
32
|
|
2
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
38
|
|
3
|
1
|
|
|
1
|
|
43
|
use 5.022; |
|
1
|
|
|
|
|
4
|
|
4
|
1
|
|
|
1
|
|
5
|
use feature qw /postderef signatures/; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
153
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package Vote::Count::Method::IRV; |
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
8
|
use namespace::autoclean; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
10
|
|
9
|
1
|
|
|
1
|
|
81
|
use Moose; |
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
8
|
|
10
|
|
|
|
|
|
|
extends 'Vote::Count'; |
11
|
|
|
|
|
|
|
# Brings the main Vote::Count Object in along with |
12
|
|
|
|
|
|
|
# Topcount and other methods. |
13
|
|
|
|
|
|
|
# with 'Vote::Count'; |
14
|
|
|
|
|
|
|
# with 'Vote::Count::Matrix'; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our $VERSION='0.007'; |
17
|
|
|
|
|
|
|
|
18
|
1
|
|
|
1
|
|
6446
|
no warnings 'experimental'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
19
|
1
|
|
|
1
|
|
6
|
use List::Util qw( min max ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
92
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# use Vote::Count::RankCount; |
22
|
|
|
|
|
|
|
# use Try::Tiny; |
23
|
1
|
|
|
1
|
|
7
|
use TextTableTiny 'generate_markdown_table'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
49
|
|
24
|
1
|
|
|
1
|
|
14
|
use Data::Printer; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
17
|
|
25
|
1
|
|
|
1
|
|
49
|
use Data::Dumper; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
473
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# use YAML::XS; |
28
|
|
|
|
|
|
|
|
29
|
3
|
|
|
3
|
0
|
8737
|
sub RunIRV ( $self, $active = undef ) { |
|
3
|
|
|
|
|
10
|
|
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
6
|
|
30
|
3
|
50
|
|
|
|
15
|
unless ( defined $active ) { |
31
|
3
|
|
|
|
|
138
|
$active = $self->BallotSet->{'choices'}; |
32
|
|
|
|
|
|
|
} |
33
|
3
|
|
|
|
|
7
|
my $roundctr = 0; |
34
|
3
|
|
|
|
|
6
|
my $maxround = scalar( keys %{$active} ); |
|
3
|
|
|
|
|
11
|
|
35
|
|
|
|
|
|
|
$self->logt( "Instant Runoff Voting", |
36
|
3
|
|
|
|
|
9
|
'Choices: ', join( ', ', ( sort keys %{$active} ) ) ); |
|
3
|
|
|
|
|
49
|
|
37
|
|
|
|
|
|
|
# forever loop normally ends with return from $majority |
38
|
|
|
|
|
|
|
# a tie should be detected and also generate a |
39
|
|
|
|
|
|
|
# return from the else loop. |
40
|
|
|
|
|
|
|
# if something goes wrong roundcountr/maxround |
41
|
|
|
|
|
|
|
# will generate exception. |
42
|
|
|
|
|
|
|
IRVLOOP: |
43
|
3
|
|
|
|
|
8
|
until ( 0 ) { |
44
|
16
|
|
|
|
|
23
|
$roundctr++; |
45
|
16
|
50
|
|
|
|
36
|
die "IRVLOOP infinite stopped at $roundctr" if $roundctr > $maxround; |
46
|
16
|
|
|
|
|
46
|
my $round = $self->TopCount($active); |
47
|
16
|
|
|
|
|
56
|
$self->logv( '---', "IRV Round $roundctr", $round->RankTable() ); |
48
|
16
|
|
|
|
|
77
|
my $majority = $self->EvaluateTopCountMajority( $round ); |
49
|
16
|
100
|
|
|
|
34
|
if ( defined $majority->{'winner'} ) { |
50
|
2
|
|
|
|
|
17
|
return $majority; |
51
|
|
|
|
|
|
|
} else { |
52
|
14
|
|
|
|
|
39
|
my @bottom = sort $round->ArrayBottom()->@*; |
53
|
14
|
100
|
|
|
|
23
|
if ( scalar(@bottom) == scalar( keys %{$active} ) ) { |
|
14
|
|
|
|
|
31
|
|
54
|
|
|
|
|
|
|
# if there is a tie at the end, the finalists should |
55
|
|
|
|
|
|
|
# be both top and bottom and the active set. |
56
|
1
|
|
|
|
|
6
|
$self->logt( "Tied: " . join( ', ', @bottom ) ); |
57
|
1
|
|
|
|
|
15
|
return { tie => 1, tied => \@bottom, winner => 0 }; |
58
|
|
|
|
|
|
|
} |
59
|
13
|
|
|
|
|
50
|
$self->logv( "Eliminating: " . join( ', ', @bottom ) ); |
60
|
13
|
|
|
|
|
28
|
for my $b (@bottom) { |
61
|
22
|
|
|
|
|
99
|
delete $active->{$b}; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
1; |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
#buildpod |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=pod |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=head1 IRV |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
Some things to know about IRV. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head2 Warning |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
IRV is the best algorithm for resolving a small Condorcet Tie, but |
81
|
|
|
|
|
|
|
a poor algorithm for an election. But it is really simple. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=cut |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
#buildpod |