Passed
Branch master (73ca69)
by Boudry
03:33
created

Schulze_Core::makeStrongestPaths()   C

Complexity

Conditions 11
Paths 30

Size

Total Lines 28
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 11

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 16
cts 16
cp 1
rs 5.2653
c 0
b 0
f 0
cc 11
eloc 25
nc 30
nop 0
crap 11

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
    Schulze 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\CondorcetException;
15
use Condorcet\Result;
16
17
// Schulze is a Condorcet Algorithm | http://en.wikipedia.org/wiki/Schulze_method
18
abstract class Schulze_Core extends Method implements MethodInterface
19
{
20
    // Schulze
21
    protected $_StrongestPaths;
22
23
24
/////////// PUBLIC ///////////
25
26
    abstract protected function schulzeVariant (int &$i,int &$j);
27
28 4
    public function getResult () : Result
29
    {
30
        // Cache
31 4
        if ( $this->_Result !== null ) :
32 3
            return $this->_Result;
33
        endif;
34
35
            //////
36
37
        // Format array
38 4
        $this->prepareStrongestPath();
39
40
        // Strongest Paths calculation
41 4
        $this->makeStrongestPaths();
42
43
        // Ranking calculation
44 4
        $this->makeRanking();
45
46
47
        // Return
48 4
        return $this->_Result;
49
    }
50
51
52
    // Get the Schulze ranking
53 4
    protected function getStats () : array
54
    {
55 4
        $explicit = [];
56
57 4
        foreach ($this->_StrongestPaths as $candidate_key => $candidate_value) :
58 4
            $candidate_key = $this->_selfElection->getCandidateId($candidate_key, true);
59
60 4
            foreach ($candidate_value as $challenger_key => $challenger_value) :
61 4
                $explicit[$candidate_key][$this->_selfElection->getCandidateId($challenger_key, true)] = $challenger_value;
62
            endforeach;
63
        endforeach;
64
65 4
        return $explicit;
66
    }
67
68
69
70
/////////// COMPUTE ///////////
71
72
73
    //:: SCHULZE ALGORITHM. :://
74
75
76
    // Calculate the strongest Paths for Schulze Method
77 4
    protected function prepareStrongestPath () : void
78
    {
79 4
        $this->_StrongestPaths = [];
80
81 4
        foreach ( $this->_selfElection->getCandidatesList() as $candidate_key => $candidate_id ) :
82 4
            $this->_StrongestPaths[$candidate_key] = [];
83
84
            // Format array for the strongest path
85 4
            foreach ( $this->_selfElection->getCandidatesList() as $candidate_key_r => $candidate_id_r ) :
86 4
                if ($candidate_key_r != $candidate_key) :
87 4
                    $this->_StrongestPaths[$candidate_key][$candidate_key_r] = 0;
88
                endif;
89
            endforeach;
90
        endforeach;
91 4
    }
92
93
94
    // Calculate the Strongest Paths
95 4
    protected function makeStrongestPaths () : void
96
    {
97 4
        foreach ($this->_selfElection->getCandidatesList() as $i => $i_value) :
98 4
            foreach ($this->_selfElection->getCandidatesList() as $j => $j_value) :
99 4
                if ($i !== $j) :
100 4
                    if ( $this->_selfElection->getPairwise(false)[$i]['win'][$j] > $this->_selfElection->getPairwise(false)[$j]['win'][$i] ) :
101 4
                        $this->_StrongestPaths[$i][$j] = $this->schulzeVariant($i,$j);                      
102
                    else :
103 4
                        $this->_StrongestPaths[$i][$j] = 0;
104
                    endif;
105
                endif;
106
            endforeach;
107
        endforeach;
108
109 4
        foreach ($this->_selfElection->getCandidatesList() as $i => $i_value) :
110 4
            foreach ($this->_selfElection->getCandidatesList() as $j => $j_value) :
111 4
                if ($i !== $j) :
112 4
                    foreach ($this->_selfElection->getCandidatesList() as $k => $k_value) :
113 4
                        if ($i !== $k && $j !== $k) :
114 4
                            $this->_StrongestPaths[$j][$k] = 
115 4
                                max( $this->_StrongestPaths[$j][$k], 
116 4
                                     min($this->_StrongestPaths[$j][$i], $this->_StrongestPaths[$i][$k]) );
117
                        endif;
118
                    endforeach;
119
                endif;
120
            endforeach;
121
        endforeach;
122 4
    }
123
124
125
    // Calculate && Format human readable ranking
126 4
    protected function makeRanking () : void
127
    {       
128 4
        $result = [];
129
130
        // Calculate ranking
131 4
        $done = array ();
132 4
        $rank = 1;
133
134 4
        while (count($done) < $this->_selfElection->countCandidates()) :
135 4
            $to_done = [];
136
137 4
            foreach ( $this->_StrongestPaths as $candidate_key => $challengers_key ) :
138 4
                if ( in_array($candidate_key, $done, true) ) :
139 4
                    continue;
140
                endif;
141
142 4
                $winner = true;
143
144 4
                foreach ($challengers_key as $beaten_key => $beaten_value) :
145 4
                    if ( in_array($beaten_key, $done, true) ) :
146 4
                        continue;
147
                    endif;
148
149 4
                    if ( $beaten_value < $this->_StrongestPaths[$beaten_key][$candidate_key] ) :
150 4
                        $winner = false;
151
                    endif;
152
                endforeach;
153
154 4
                if ($winner) :
155 4
                    $result[$rank][] = $candidate_key;
156
157 4
                    $to_done[] = $candidate_key;
158
                endif;
159
            endforeach;
160
161 4
            $done = array_merge($done, $to_done);
162
163 4
            $rank++;
164
        endwhile;
165
166 4
        $this->_Result = $this->createResult($result);
167 4
    }
168
169
}
170