Anti-Harassment Tools/SecurePoll Improvements/Test Results/7 5 1000

Comments
I think this case has been discussed by the team.

SecurePoll elects candidates 1, 2, 3 and 7.

OpenSTV elects candidates 1, 2, 4, 6 and 7 (or A, B, D, F and G as they appear in the output).

SecurePoll differs from OpenSTV because of how we deal with eliminating tied voters.

Election setup

 * Candidates: 7
 * Seats: 5
 * Votes: 1000

Actual
Output from SecurePoll : array(3) { ["elected"]=> array(4) { [0]=>   int(2) [1]=>   int(1) [2]=>   int(3) [3]=>   int(7) } ["eliminated"]=> array(3) { [0]=>   int(4) [1]=>   int(5) [2]=>   int(6) } ["rounds"]=> array(4) { [0]=>   array(8) { ["round"]=> int(1) ["surplus"]=> int(0) ["rankings"]=> array(7) { [1]=>       array(3) { ["votes"]=> int(0) ["earned"]=> int(166) ["total"]=> int(166) }       [2]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(168) ["total"]=> int(168) }       [3]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(133) ["total"]=> int(133) }       [4]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(133) ["total"]=> int(133) }       [5]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(133) ["total"]=> int(133) }       [6]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(133) ["total"]=> int(133) }       [7]=>        array(3) { ["votes"]=> int(0) ["earned"]=> int(134) ["total"]=> int(134) }     }      ["totalVotes"]=> int(1000) ["keepFactors"]=> array(7) { [1]=>       int(1) [2]=>       int(1) [3]=>       int(1) [4]=>       int(1) [5]=>       int(1) [6]=>       int(1) [7]=>       int(1) }     ["quota"]=> int(167) ["elected"]=> array(0) { }     ["eliminated"]=> array(0) { }   }    [1]=>    array(8) { ["round"]=> int(2) ["elected"]=> array(1) { [0]=>       int(2) }     ["eliminated"]=> array(0) { }     ["surplus"]=> int(1) ["keepFactors"]=> array(7) { [1]=>       int(1) [2]=>       int(1) [3]=>       int(1) [4]=>       int(1) [5]=>       int(1) [6]=>       int(1) [7]=>       int(1) }     ["quota"]=> int(167) ["rankings"]=> array(7) { [1]=>       array(3) { ["votes"]=> int(166) ["earned"]=> int(0) ["total"]=> int(166) }       [2]=>        array(3) { ["votes"]=> int(168) ["earned"]=> int(0) ["total"]=> int(168) }       [3]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(0) ["total"]=> int(133) }       [4]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(0) ["total"]=> int(133) }       [5]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(0) ["total"]=> int(133) }       [6]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(0) ["total"]=> int(133) }       [7]=>        array(3) { ["votes"]=> int(134) ["earned"]=> int(0) ["total"]=> int(134) }     }      ["totalVotes"]=> int(1000) }   [2]=>    array(8) { ["round"]=> int(3) ["elected"]=> array(0) { }     ["eliminated"]=> array(3) { [0]=>       int(4) [1]=>       int(5) [2]=>       int(6) }     ["surplus"]=> float(0) ["keepFactors"]=> array(7) { [1]=>       int(1) [2]=>       float(0.99404761904762) [3]=>       int(1) [4]=>       int(1) [5]=>       int(1) [6]=>       int(1) [7]=>       int(1) }     ["quota"]=> int(167) ["rankings"]=> array(7) { [1]=>       array(3) { ["votes"]=> int(166) ["earned"]=> float(0.5) ["total"]=> float(166.5) }       [2]=>        array(3) { ["votes"]=> int(168) ["earned"]=> float(-1) ["total"]=> float(167) }       [3]=>        array(3) { ["votes"]=> int(133) ["earned"]=> float(0.5) ["total"]=> float(133.5) }       [4]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(0) ["total"]=> int(133) }       [5]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(0) ["total"]=> int(133) }       [6]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(0) ["total"]=> int(133) }       [7]=>        array(3) { ["votes"]=> int(134) ["earned"]=> int(0) ["total"]=> int(134) }     }      ["totalVotes"]=> float(1000) }   [3]=>    array(8) { ["round"]=> int(4) ["elected"]=> array(3) { [0]=>       int(1) [2]=>       int(3) [3]=>       int(7) }     ["eliminated"]=> array(0) { }     ["surplus"]=> float(242) ["keepFactors"]=> array(7) { [1]=>       int(1) [2]=>       float(0.99404761904762) [3]=>       int(1) [4]=>       int(0) [5]=>       int(0) [6]=>       int(0) [7]=>       int(1) }     ["quota"]=> int(123) ["rankings"]=> array(7) { [1]=>       array(3) { ["votes"]=> float(166.5) ["earned"]=> float(-1.7763568394003E-15) ["total"]=> float(166.5) }       [2]=>        array(3) { ["votes"]=> float(167) ["earned"]=> float(0) ["total"]=> float(167) }       [3]=>        array(3) { ["votes"]=> float(133.5) ["earned"]=> float(0) ["total"]=> float(133.5) }       [4]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(-133) ["total"]=> int(0) }       [5]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(-133) ["total"]=> int(0) }       [6]=>        array(3) { ["votes"]=> int(133) ["earned"]=> int(-133) ["total"]=> int(0) }       [7]=>        array(3) { ["votes"]=> int(134) ["earned"]=> int(133) ["total"]=> int(267) }     }      ["totalVotes"]=> float(734) } } }

Elected

 * 1) "B"
 * 2) "A"
 * 3) "C"
 * 4) "G"
 * 5) This seat could not be filled because no candidates fulfill the criteria. The last eliminated candidates were: "D", "E", "F"

Eliminated

 * "D"
 * "E"
 * "F"

Rounds table
(Results from 01:16, 28 July 2021)

Expected
Output from OpenSTV: Loading ballots from file 7_5_1000.blt. Ballot file contains 7 candidates and 1000 ballots. No candidates have withdrawn. Ballot file contains 1000 non-empty ballots.

Counting votes for Title using Meek STV. 7 candidates running for 5 seats.

R|A            |B             |C             |D             |E |--+--+--+--+-- |F             |G             |Exhausted     |Surplus       |Threshold

=
================================================================ 1|   166.000000|    168.000000|    133.000000|    133.000000|    133.000000  |    133.000000|    134.000000|      0.000000|      1.333333|    166.666667  |--  | Count of first choices. Candidate B has reached the threshold and is | elected.

=
================================================================ 2|   166.666624|    166.666752|    133.666624|    133.000000|    133.000000  |    133.000000|    134.000000|      0.000000|      0.000085|    166.666667  |--  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: B, 0.992064.

=
================================================================ 3|   166.666624|    166.666752|    133.666624|    133.000000|    133.000000  |    133.000000|    134.000000|      0.000000|      0.000085|    166.666667  |--  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: B, 0.992064.

=
================================================================ 4|   166.666624|    166.666752|    133.666624|    133.000000|                |    266.000000|    134.000000|      0.000000|     99.333418|    166.666667  |--  | Count after eliminating E and transferring votes. Candidates tied within | precision of computations. Candidates D, E, and F were tied when choosing | candidates to eliminate. Candidate E was chosen by breaking the tie | randomly. Candidate F has reached the threshold and is elected.

=
================================================================ 5|   166.666624|    166.666752|    133.666624|    133.000000|                |    166.666822|    183.666589|     49.666589|     50.111179|    158.388902  |--  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: B, 0.992064 and F, 0.626567. Candidates A | and G have reached the threshold and are elected.

=
================================================================ 6|   162.322247|    158.389056|    137.805472|    151.442152|                |    158.388902|    161.958246|     69.693925|     20.854399|    155.051013  |--  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: A, 0.950334; B, 0.942792; F, 0.595447; and | G, 0.862372.

=
================================================================ 7|   156.566112|    155.051064|    139.474468|    156.370404|                |    155.051134|    156.428955|     81.057863|     13.682554|    153.157023  |--  | Count after transferring surplus votes. Keep factors of candidates who | have exceeded the threshold: A, 0.907764; B, 0.922923; F, 0.582899; and | G, 0.825594. Candidate D has reached the threshold and is elected.

Winners are A, B, D, F, and G.

Files
array ( 1 =>   array ( 'count' => 166, 'rank' => array (     1 => '1',    ), ), '2_1' =>   array ( 'count' => 84, 'rank' => array (     1 => '2',      2 => '1',    ), ), '2_3' =>   array ( 'count' => 84, 'rank' => array (     1 => '2',      2 => '3',    ), ), '3_4' =>   array ( 'count' => 133, 'rank' => array (     1 => '3',      2 => '4',    ), ), '4_5' =>   array ( 'count' => 133, 'rank' => array (     1 => '4',      2 => '5',    ), ), '5_6' =>   array ( 'count' => 133, 'rank' => array (     1 => '5',      2 => '6',    ), ), '6_7' =>   array ( 'count' => 133, 'rank' => array (     1 => '6',      2 => '7',    ), ), '7_4' =>   array ( 'count' => 134, 'rank' => array (     1 => '7',      2 => '4',    ), ), )
 * blt: https://github.com/dominic998/SecurePoll-Test-Data/blob/main/test_data/7_5_1000.blt
 * php:

Environment

 * Where you tested: local docker using phpunit
 * Version of SecurePoll: commit 271145d5f3cae3b0a1b76d0f5dfeb609615d60b7 (patch 16 from https://gerrit.wikimedia.org/r/c/mediawiki/extensions/SecurePoll/+/704454/)