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

Pairwise::formatNewpairwise()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

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