Completed
Push — master ( 922505...49fe4c )
by Boudry
05:20
created

DodgsonQuick::computeDodgson()   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
dl 0
loc 45
ccs 26
cts 26
cp 1
rs 4.909
c 0
b 0
f 0
cc 9
eloc 34
nc 72
nop 0
crap 9
1
<?php
2
/*
3
    Dodgson part of the Condorcet PHP Class
4
5
    By Julien Boudry - MIT LICENSE (Please read LICENSE.txt)
6
    https://github.com/julien-boudry/Condorcet
7
*/
8
declare(strict_types=1);
9
10
namespace Condorcet\Algo\Methods;
11
12
use Condorcet\Algo\Method;
13
use Condorcet\Algo\MethodInterface;
14
use Condorcet\Algo\Tools\PairwiseStats;
15
use Condorcet\Result;
16
17
// 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
18
class DodgsonQuick extends Method implements MethodInterface
19
{
20
    // Method Name
21
    public const METHOD_NAME = ['Dodgson Quick','DodgsonQuick','Dodgson Quick Winner'];
22
23
    protected $_Stats;
24
25 10
    public function getResult () : Result
26
    {
27
        // Cache
28 10
        if ( $this->_Result !== null ) :
29 3
            return $this->_Result;
30
        endif;
31
32 10
        $this->computeDodgson();
33
34 10
        return $this->_Result;
35
    }
36
37 10
    protected function getStats () : array
38
    {
39 10
        $stats = [];
40
41 10
        foreach ($this->_Stats as $candidateKey => $dodgsonQuickValue) :
42 10
             $stats[(string) $this->_selfElection->getCandidateId($candidateKey)] = $dodgsonQuickValue;
43
        endforeach;
44
45 10
        return $stats;
46
    }
47
48
49
/////////// COMPUTE ///////////
50
51
    //:: DODGSON ALGORITHM. :://
52
53 10
    protected function computeDodgson () : void
54
    {
55 10
        $pairwise = $this->_selfElection->getPairwise(false);
56 10
        $HeadToHead = [];
57
58 10
        foreach ($pairwise as $candidateId => $CandidateStats) :
59 10
            foreach ($CandidateStats['lose'] as $opponentId => $CandidateLose) :
60 10
                if (($diff = $CandidateLose - $CandidateStats['win'][$opponentId]) >= 0) :
61 10
                    $HeadToHead[$candidateId][$opponentId] = $diff;
62
                endif;
63
            endforeach;
64
        endforeach;
65
66 10
        $dodgsonQuick = [];
67
68 10
        foreach ($HeadToHead as $candidateId => $CandidateTidemanScores) :
69 10
            $dodgsonQuick[$candidateId] = 0;
70
71 10
            foreach ($CandidateTidemanScores as $opponentId => $oneTidemanScore) :
72 10
                $dodgsonQuick[$candidateId] += ceil($oneTidemanScore / 2);
73
            endforeach;
74
        endforeach;
75 10
        asort($dodgsonQuick);
76
77 10
        $rank = 0;
78 10
        $result = [];
79
80 10
        if($basicCondorcetWinner = $this->_selfElection->getWinner(null)) :
81 2
            $result[++$rank][] = $this->_selfElection->getCandidateKey($basicCondorcetWinner);
82
        endif;
83
84 10
        $lastDodgsonQuickValue = null;
85
86 10
        foreach ($dodgsonQuick as $CandidateId => $dodgsonQuickValue) :
87 10
            if($lastDodgsonQuickValue === $dodgsonQuickValue) :
88 5
                $result[$rank][] = $CandidateId;
89
            else:
90 10
                $result[++$rank][] = $CandidateId;
91 10
                $lastDodgsonQuickValue = $dodgsonQuickValue;
92
            endif;
93
        endforeach;
94
95 10
        $this->_Stats = $dodgsonQuick;
96 10
        $this->_Result = $this->createResult($result);
97 10
    }
98
99
}
100