Completed
Branch master (fa2fc5)
by Boudry
05:50 queued 02:29
created

DodgsonQuick::compute()   D

Complexity

Conditions 9
Paths 72

Size

Total Lines 45
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 34
nc 72
nop 0
dl 0
loc 45
ccs 26
cts 26
cp 1
crap 9
rs 4.909
c 0
b 0
f 0
1
<?php
2
/*
3
    Part of DODGSON QUICK method Module - From the original Condorcet PHP
4
5
    Condorcet PHP - Election manager and results calculator.
6
    Designed for the Condorcet method. Integrating a large number of algorithms extending Condorcet. Expandable for all types of voting systems.
7
8
    By Julien Boudry and contributors - MIT LICENSE (Please read LICENSE.txt)
9
    https://github.com/julien-boudry/Condorcet
10
*/
11
declare(strict_types=1);
12
13
namespace Condorcet\Algo\Methods;
14
15
use Condorcet\Algo\Method;
16
use Condorcet\Algo\MethodInterface;
17
18
use Condorcet\Result;
19
20
// DODGSON Quick is an approximation for Dodgson method | https://www.maa.org/sites/default/files/pdf/cmj_ftp/CMJ/September%202010/3%20Articles/6%2009-229%20Ratliff/Dodgson_CMJ_Final.pdf
21
class DodgsonQuick extends Method implements MethodInterface
22
{
23
    // Method Name
24
    public const METHOD_NAME = ['Dodgson Quick','DodgsonQuick','Dodgson Quick Winner'];
25
26
    protected $_Stats;
27
28 10
    protected function getStats () : array
29
    {
30 10
        $stats = [];
31
32 10
        foreach ($this->_Stats as $candidateKey => $dodgsonQuickValue) :
33 10
             $stats[(string) $this->_selfElection->getCandidateId($candidateKey)] = $dodgsonQuickValue;
34
        endforeach;
35
36 10
        return $stats;
37
    }
38
39
40
/////////// COMPUTE ///////////
41
42
    //:: DODGSON ALGORITHM. :://
43
44 10
    protected function compute () : void
45
    {
46 10
        $pairwise = $this->_selfElection->getPairwise(false);
47 10
        $HeadToHead = [];
48
49 10
        foreach ($pairwise as $candidateId => $CandidateStats) :
50 10
            foreach ($CandidateStats['lose'] as $opponentId => $CandidateLose) :
51 10
                if (($diff = $CandidateLose - $CandidateStats['win'][$opponentId]) >= 0) :
52 10
                    $HeadToHead[$candidateId][$opponentId] = $diff;
53
                endif;
54
            endforeach;
55
        endforeach;
56
57 10
        $dodgsonQuick = [];
58
59 10
        foreach ($HeadToHead as $candidateId => $CandidateTidemanScores) :
60 10
            $dodgsonQuick[$candidateId] = 0;
61
62 10
            foreach ($CandidateTidemanScores as $opponentId => $oneTidemanScore) :
63 10
                $dodgsonQuick[$candidateId] += ceil($oneTidemanScore / 2);
64
            endforeach;
65
        endforeach;
66 10
        asort($dodgsonQuick);
67
68 10
        $rank = 0;
69 10
        $result = [];
70
71 10
        if($basicCondorcetWinner = $this->_selfElection->getWinner(null)) :
72 2
            $result[++$rank][] = $this->_selfElection->getCandidateKey($basicCondorcetWinner);
73
        endif;
74
75 10
        $lastDodgsonQuickValue = null;
76
77 10
        foreach ($dodgsonQuick as $CandidateId => $dodgsonQuickValue) :
78 10
            if($lastDodgsonQuickValue === $dodgsonQuickValue) :
79 5
                $result[$rank][] = $CandidateId;
80
            else:
81 10
                $result[++$rank][] = $CandidateId;
82 10
                $lastDodgsonQuickValue = $dodgsonQuickValue;
83
            endif;
84
        endforeach;
85
86 10
        $this->_Stats = $dodgsonQuick;
87 10
        $this->_Result = $this->createResult($result);
88 10
    }
89
}
90