Completed
Push — master ( c01904...dcbc34 )
by Boudry
02:56
created

Pairwise::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
/*
3
    Condorcet PHP Class, with Schulze Methods and others !
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
11
namespace Condorcet\Algo;
12
13
use Condorcet\CondorcetVersion;
14
use Condorcet\Election;
15
use Condorcet\Timer\Chrono as Timer_Chrono;
16
17
class Pairwise implements \ArrayAccess, \Iterator
18
{
19
    use CondorcetVersion;
20
21
    // Implement ArrayAccess
22
    public function offsetSet($offset, $value) : void {}
23
24
    public function offsetExists($offset) : bool {
25
        return isset($this->_Pairwise[$offset]);
26
    }
27
28
    public function offsetUnset($offset) : void {}
29
30 33
    public function offsetGet($offset) : ?array {
31 33
        return $this->_Pairwise[$offset] ?? null;
32
    }
33
34
35
    // Implement Iterator
36
    private $valid = true;
37
38 77
    public function rewind() : void {
39 77
        reset($this->_Pairwise);
40 77
        $this->valid = true;
41 77
    }
42
43 77
    public function current() : array {
44 77
        return $this->_Pairwise[$this->key()];
45
    }
46
47 77
    public function key() : ?int {
48 77
        return key($this->_Pairwise);
49
    }
50
51 77
    public function next() : void {
52 77
        if (next($this->_Pairwise) === false) :
53 63
            $this->valid = false;
54
        endif;
55 77
    }
56
57 77
    public function valid() : bool {
58 77
        return $this->valid;
59
    }   
60
61
62
    // Pairwise
63
64
    protected $_Election;
65
    protected $_Pairwise = [];
66
67 80
    public function __construct (Election &$link)
68
    {
69 80
        $this->setElection($link);
70 80
        $this->doPairwise();
71 80
    }
72
73 1
    public function __clone ()
74
    {
75 1
        $this->_Election = null;
76 1
    }
77
78 80
    public function setElection (Election $election)
79
    {
80 80
        $this->_Election = $election;
81 80
    }
82
83 4
    public function getExplicitPairwise () : array
84
    {
85 4
        $explicit_pairwise = [];
86
87 4
        foreach ($this->_Pairwise as $candidate_key => $candidate_value) :
88
89 4
            $candidate_name = $this->_Election->getCandidateId($candidate_key, true);
90
            
91 4
            foreach ($candidate_value as $mode => $mode_value) :
92
93 4
                foreach ($mode_value as $candidate_list_key => $candidate_list_value) :
94 4
                    $explicit_pairwise[$candidate_name][$mode][$this->_Election->getCandidateId($candidate_list_key, true)] = $candidate_list_value;
95
                endforeach;
96
97
            endforeach;
98
99
        endforeach;
100
101 4
        return $explicit_pairwise;
102
    }
103
104 80
    protected function doPairwise () : void
105
    {
106
        // Chrono
107 80
        new Timer_Chrono ( $this->_Election->getTimerManager(), 'Do Pairwise' );
108
109 80
        foreach ( $this->_Election->getCandidatesList(false) as $candidate_key => $candidate_id ) :
110
111 80
            $this->_Pairwise[$candidate_key] = [ 'win' => [], 'null' => [], 'lose' => [] ];
112
113 80
            foreach ( $this->_Election->getCandidatesList(false) as $candidate_key_r => $candidate_id_r ) :
114
115 80
                if ($candidate_key_r !== $candidate_key) :
116 80
                    $this->_Pairwise[$candidate_key]['win'][$candidate_key_r]   = 0;
117 80
                    $this->_Pairwise[$candidate_key]['null'][$candidate_key_r]  = 0;
118 80
                    $this->_Pairwise[$candidate_key]['lose'][$candidate_key_r]  = 0;
119
                endif;
120
121
            endforeach;
122
123
        endforeach;
124
125
        // Win && Null
126 80
        foreach ( $this->_Election->getVotesManager() as $vote_id => $oneVote ) :
127 80
            $vote_ranking = $oneVote->getContextualRanking($this->_Election);
128
129 80
            $voteWeight = ($this->_Election->isVoteWeightIsAllowed()) ? $oneVote->getWeight() : 1;
130
131 80
            $vote_candidate_list = (function (array $r) : array { $list = [];
132 80
                    foreach ($r as $rank) :
133 80
                        foreach ($rank as $oneCandidate) :
134 80
                            $list[] = $oneCandidate;
135
                        endforeach;
136
                    endforeach;
137
138 80
                    return $list;})($vote_ranking);
139
140 80
            $done_Candidates = [];
141
142 80
            foreach ($vote_ranking as $candidates_in_rank) :
143
144 80
                $candidates_in_rank_keys = [];
145
146 80
                foreach ($candidates_in_rank as $candidate) :
147 80
                    $candidates_in_rank_keys[] = $this->_Election->getCandidateKey($candidate);
148
                endforeach;
149
150 80
                foreach ($candidates_in_rank as $candidate) :
151
152 80
                    $candidate_key = $this->_Election->getCandidateKey($candidate);
153
154
                    // Process
155 80
                    foreach ( $vote_candidate_list as $g_Candidate ) :
156
157 80
                        $g_candidate_key = $this->_Election->getCandidateKey($g_Candidate);
158
159 80
                        if ($candidate_key === $g_candidate_key) :
160 80
                            continue;
161
                        endif;
162
163
                        // Win & Lose
164 80
                        if (    !in_array($g_candidate_key, $done_Candidates, true) && 
165 80
                                !in_array($g_candidate_key, $candidates_in_rank_keys, true) ) :
166
167 80
                            $this->_Pairwise[$candidate_key]['win'][$g_candidate_key] += $voteWeight;
168 80
                            $this->_Pairwise[$g_candidate_key]['lose'][$candidate_key] += $voteWeight;
169
170 80
                            $done_Candidates[] = $candidate_key;
171
172
                        // Null
173 80
                        elseif (in_array($g_candidate_key, $candidates_in_rank_keys, true)) :
174 80
                            $this->_Pairwise[$candidate_key]['null'][$g_candidate_key] += $voteWeight;
175
                        endif;
176
177
                    endforeach;
178
179
                endforeach;
180
181
            endforeach;
182
183
        endforeach;
184 80
    }
185
186
}