-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBronKerbosch-Implementations.php
87 lines (62 loc) · 3.38 KB
/
BronKerbosch-Implementations.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?php
function bronKerbosch($potentialClique, $candidateVerts, $alreadyFoundVerts, $adjacencyList, &$resultCliques) {
if (!$candidateVerts && !$alreadyFoundVerts) {
//found maximal clique
$resultCliques[] = $potentialClique;
return;
}
$cliques = array();
foreach ($candidateVerts as $candidateVert) {
//get the neighbors of $candidateVert (the verts it has an edge to)
$neighborVerts = $adjacencyList[$candidateVert];
$newCandidates = array_intersect_key($candidateVerts, $neighborVerts);
$newAlreadyFoundVerts = array_intersect_key($alreadyFoundVerts, $neighborVerts);
//temporarily add the new vert to r
$potentialClique[$candidateVert] = $candidateVert;
bronKerbosch($potentialClique, $newCandidates, $newAlreadyFoundVerts, $adjacencyList, $resultCliques);
//remove the temp vert from r
unset($potentialClique[$candidateVert]);
//take the vert our of candidates, and put it into already found(alreadyProcessed sounds like a better name)
unset($candidateVerts[$candidateVert]);
$alreadyFoundVerts[$candidateVert] = $candidateVert;
}
return $cliques;
}
function bronKerboschWithPivoting($potentialClique, $candidateVerts, $alreadyFoundVerts, $adjacencyList, &$resultCliques, $pivotChoosingFunction) {
//if both sets are empty
if (!$candidateVerts && !$alreadyFoundVerts) {
//found maximal clique
$resultCliques[] = $potentialClique;
return;
}
$pivotVert = $pivotChoosingFunction($candidateVerts + $alreadyFoundVerts);
$pivotNeighborVerts = $adjacencyList[$pivotVert];
//array_diff_key means set minus or "except the stuff in $pivotNeighborVerts"
foreach (array_diff_key($candidateVerts, $pivotNeighborVerts) as $candidateVert) {
//get the neighbors of $candidateVert (the verts it has an edge to)
$neighborVerts = $adjacencyList[$candidateVert];
//temporarily add the new vert to r
// like R U {v} in psuedo code
$potentialClique[$candidateVert] = $candidateVert;
// like P ^ N(v) in psuedocode
$newCandidates = array_intersect_key($candidateVerts, $neighborVerts);
// like X ^ N(V) in pesudo
$newAlreadyFoundVerts = array_intersect_key($alreadyFoundVerts, $neighborVerts);
bronKerboschWithPivoting($potentialClique, $newCandidates, $newAlreadyFoundVerts, $adjacencyList, $resultCliques, $pivotChoosingFunction);
//remove the temp vert from r
unset($potentialClique[$candidateVert]);
//take the vert our of candidates, and put it into already found(alreadyProcessed sounds like a better name)
//like P := P \ {v} in pseudo
unset($candidateVerts[$candidateVert]);
//like X := X U {V} in pseudo
$alreadyFoundVerts[$candidateVert] = $candidateVert;
}
}
function bronKerboschWithVertexOrdering($potentialClique, $candidateVerts, $alreadyFoundVerts, $adjacencyList, &$resultCliques, $pivotChoosingFunction) {
//sort by vertex degree, ascending
//this is a "degeneracy ordering"
uasort($candidateVerts, function($a, $b){
return count($a) - count($b);
});
bronKerboschWithPivoting($potentialClique, $candidateVerts, $alreadyFoundVerts, $adjacencyList, $resultCliques, $pivotChoosingFunction);
}