root / voting_power.pl
History | View | Annotate | Download (4.2 kB)
1 |
# Copyright (c) 2010, Panos Louridas, GRNET S.A. |
---|---|
2 |
# |
3 |
# All rights reserved. |
4 |
# |
5 |
# Redistribution and use in source and binary forms, with or without |
6 |
# modification, are permitted provided that the following conditions are met: |
7 |
# |
8 |
# * Redistributions of source code must retain the above copyright notice, this |
9 |
# list of conditions and the following disclaimer. |
10 |
# |
11 |
# * Redistributions in binary form must reproduce the above copyright notice, |
12 |
# this list of conditions and the following disclaimer in the documentation |
13 |
# and/or other materials provided with the distribution. |
14 |
# |
15 |
# * Neither the name of GRNET S.A, nor the names of its contributors may be |
16 |
# used to endorse or promote products derived from this software without |
17 |
# specific prior written permission. |
18 |
# |
19 |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
20 |
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
22 |
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
23 |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
24 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
25 |
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
26 |
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
27 |
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 |
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 |
|
30 |
use strict; |
31 |
|
32 |
use Getopt::Long; |
33 |
|
34 |
my $quorum = 1; |
35 |
my $threshold = -1; |
36 |
my $help = 0; |
37 |
my $num_samples = 100000; |
38 |
my $percentages = 0; |
39 |
my $verbose = 0; |
40 |
|
41 |
GetOptions("quorum=i" => \$quorum, |
42 |
"threshold=i" => \$threshold, |
43 |
"samples=i" =>\$num_samples, |
44 |
"percent" => \$percentages, |
45 |
"verbose" => \$verbose, |
46 |
"help" => \$help); |
47 |
|
48 |
if ($help) { |
49 |
print <<HELP; |
50 |
Usage: perl egi.voting.pl [OPTION] file |
51 |
Options are: |
52 |
-q, --quorum |
53 |
Set the quorum (number of voters required to reach decision) |
54 |
-s, --samples |
55 |
Set the number of samples |
56 |
-t, --threshold |
57 |
Set the threshold (amount of votes required to pass) |
58 |
-p, --percent |
59 |
Output results as percentages |
60 |
-v, --verbose |
61 |
Outputs group information (very large output) |
62 |
-h, --help |
63 |
Print this help screen |
64 |
file |
65 |
File containing the voter weights |
66 |
HELP |
67 |
exit; |
68 |
} |
69 |
|
70 |
my %votes; |
71 |
my %block_votes; |
72 |
my $sum_votes = 0; |
73 |
|
74 |
while (<>) { |
75 |
my ($voter, $voter_votes, $block_members) = split(/:/); |
76 |
$votes{$voter} = $voter_votes + 0; |
77 |
$sum_votes += $voter_votes; |
78 |
$block_votes{$voter} = $block_members ? $block_members + 0 : 1; |
79 |
} |
80 |
|
81 |
my @voters = keys(%votes); |
82 |
|
83 |
$threshold = $sum_votes / 2 if $threshold = -1; |
84 |
|
85 |
srand; |
86 |
|
87 |
print "quorum voters: $quorum votes threshold: $threshold samples: $num_samples\n"; |
88 |
|
89 |
foreach my $voter (sort @voters) { |
90 |
my $voter_votes = $votes{$voter}; |
91 |
my @voter_pool = keys(%votes); |
92 |
my $critical = 0; |
93 |
for (my $i = 0; $i < $num_samples; $i++) { |
94 |
my $member = 0; |
95 |
my $selection_size = 0; |
96 |
my @group; |
97 |
my $group_votes = 0; |
98 |
for my $candidate (@voter_pool) { |
99 |
if (rand(1) < 0.5) { |
100 |
push(@group, $candidate); |
101 |
$member = 1 if $candidate eq $voter; |
102 |
$selection_size += $block_votes{$candidate}; |
103 |
$group_votes += $votes{$candidate}; |
104 |
} |
105 |
} |
106 |
if ($member |
107 |
&& ($group_votes >= $threshold) |
108 |
&& (($group_votes - $voter_votes) < $threshold) |
109 |
&& ($selection_size >= $quorum)) { |
110 |
$critical++; |
111 |
print "+ $selection_size @group $group_votes\n" if $verbose; |
112 |
} elsif (!$member |
113 |
&& ($group_votes < $threshold) |
114 |
&& (($group_votes + $voter_votes) >= $threshold) |
115 |
&& (($selection_size + 1) >= $quorum)) { |
116 |
$critical++; |
117 |
print "- $selection_size @group $group_votes\n" if $verbose; |
118 |
} elsif ($verbose) { |
119 |
print "% $selection_size @group $group_votes\n"; |
120 |
} |
121 |
} |
122 |
my $penrose = $critical / $num_samples; |
123 |
$penrose *= 100 if $percentages; |
124 |
print("$voter:$penrose\n"); |
125 |
} |