Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | // Copyright 2019-2022 Cambridge Quantum Computing | |||
2 | // | |||
3 | // Licensed under the Apache License, Version 2.0 (the "License"); | |||
4 | // you may not use this file except in compliance with the License. | |||
5 | // You may obtain a copy of the License at | |||
6 | // | |||
7 | // http://www.apache.org/licenses/LICENSE-2.0 | |||
8 | // | |||
9 | // Unless required by applicable law or agreed to in writing, software | |||
10 | // distributed under the License is distributed on an "AS IS" BASIS, | |||
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
12 | // See the License for the specific language governing permissions and | |||
13 | // limitations under the License. | |||
14 | ||||
15 | #include "LargeCliquesResult.hpp" | |||
16 | ||||
17 | #include "AdjacencyData.hpp" | |||
18 | ||||
19 | using std::set; | |||
20 | using std::size_t; | |||
21 | using std::vector; | |||
22 | ||||
23 | namespace tket { | |||
24 | namespace graphs { | |||
25 | ||||
26 | 303427 | LargeCliquesResult::LargeCliquesResult( | ||
27 | const AdjacencyData& adjacency_data, | |||
28 | 303427 | const set<size_t>& vertices_in_component, size_t internal_size_limit) { | ||
29 | // ...and, before swapping, everything in here will have size one greater than | |||
30 | // "result". | |||
31 | 303427 | vector<set<size_t>> extended_result; | ||
32 | ||||
33 | // At each stage, every set will have the same size, containing a clique of | |||
34 | // that size. | |||
35 |
1/2✓ Branch 2 taken 303427 times.
✗ Branch 3 not taken.
|
303427 | cliques.reserve(vertices_in_component.size()); | |
36 |
2/2✓ Branch 4 taken 486531 times.
✓ Branch 5 taken 303427 times.
|
2/2✓ Decision 'true' taken 486531 times.
✓ Decision 'false' taken 303427 times.
|
789958 | for (size_t i : vertices_in_component) { |
37 |
2/4✓ Branch 2 taken 486531 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 486531 times.
✗ Branch 6 not taken.
|
486531 | cliques.emplace_back(set{i}); | |
38 | } | |||
39 | 303427 | bool hit_internal_limit = false; | ||
40 | ||||
41 | // A little trick: the vertex indices can always be stored in order: v1 < v2 < | |||
42 | // ... Therefore, within each vertex set, if we only allow adding vertices | |||
43 | // with LARGER index than the largest already stored, we will automatically | |||
44 | // discard duplicates. | |||
45 |
1/2✓ Branch 1 taken 338026 times.
✗ Branch 2 not taken.
|
1/2✓ Decision 'true' taken 338026 times.
✗ Decision 'false' not taken.
|
338026 | for (size_t counter = 0; counter <= vertices_in_component.size(); ++counter) { |
46 | // Extend the existing results. | |||
47 |
2/2✓ Branch 5 taken 998755 times.
✓ Branch 6 taken 337714 times.
|
2/2✓ Decision 'true' taken 998755 times.
✓ Decision 'false' taken 337714 times.
|
1336469 | for (const auto& clique : cliques) { |
48 | // Guaranteed to be nonempty. | |||
49 | 998755 | const size_t largest_index = *clique.crbegin(); | ||
50 | ||||
51 |
2/2✓ Branch 1 taken 312 times.
✓ Branch 2 taken 998443 times.
|
2/2✓ Decision 'true' taken 312 times.
✓ Decision 'false' taken 998443 times.
|
998755 | if (extended_result.size() >= internal_size_limit) { |
52 | 312 | hit_internal_limit = true; | ||
53 | 312 | break; | ||
54 | } | |||
55 | // We only have to check the neighbours of ONE vertex to form a larger | |||
56 | // clique. | |||
57 |
1/2✓ Branch 1 taken 998443 times.
✗ Branch 2 not taken.
|
998443 | const auto& neighbours = adjacency_data.get_neighbours(largest_index); | |
58 |
2/2✓ Branch 5 taken 3634800 times.
✓ Branch 6 taken 998131 times.
|
2/2✓ Decision 'true' taken 3634800 times.
✓ Decision 'false' taken 998131 times.
|
4632931 | for (size_t new_v : neighbours) { |
59 |
2/2✓ Branch 0 taken 2591538 times.
✓ Branch 1 taken 1043262 times.
|
2/2✓ Decision 'true' taken 2591538 times.
✓ Decision 'false' taken 1043262 times.
|
3634800 | if (new_v <= largest_index) { |
60 | 2591538 | continue; | ||
61 | } | |||
62 | // We have a new vertex; does it adjoin EVERY existing vertex? | |||
63 | 1043262 | bool joins_every_vertex = true; | ||
64 |
2/2✓ Branch 5 taken 1535516 times.
✓ Branch 6 taken 524435 times.
|
2/2✓ Decision 'true' taken 1535516 times.
✓ Decision 'false' taken 524435 times.
|
2059951 | for (size_t existing_v : clique) { |
65 |
4/6✓ Branch 1 taken 1535516 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1535516 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 518827 times.
✓ Branch 7 taken 1016689 times.
|
2/2✓ Decision 'true' taken 518827 times.
✓ Decision 'false' taken 1016689 times.
|
1535516 | if (adjacency_data.get_neighbours(existing_v).count(new_v) == 0) { |
66 | 518827 | joins_every_vertex = false; | ||
67 | 518827 | break; | ||
68 | } | |||
69 | } | |||
70 |
2/2✓ Branch 0 taken 524435 times.
✓ Branch 1 taken 518827 times.
|
2/2✓ Decision 'true' taken 524435 times.
✓ Decision 'false' taken 518827 times.
|
1043262 | if (joins_every_vertex) { |
71 |
1/2✓ Branch 1 taken 524435 times.
✗ Branch 2 not taken.
|
524435 | extended_result.emplace_back(clique); | |
72 |
1/2✓ Branch 2 taken 524435 times.
✗ Branch 3 not taken.
|
524435 | extended_result.back().insert(new_v); | |
73 |
2/2✓ Branch 1 taken 312 times.
✓ Branch 2 taken 524123 times.
|
2/2✓ Decision 'true' taken 312 times.
✓ Decision 'false' taken 524123 times.
|
524435 | if (extended_result.size() >= internal_size_limit) { |
74 | 312 | hit_internal_limit = true; | ||
75 | 312 | break; | ||
76 | } | |||
77 | } | |||
78 | } | |||
79 | } | |||
80 |
2/2✓ Branch 1 taken 303427 times.
✓ Branch 2 taken 34599 times.
|
2/2✓ Decision 'true' taken 303427 times.
✓ Decision 'false' taken 34599 times.
|
338026 | if (extended_result.empty()) { |
81 | // No extensions | |||
82 | 303427 | cliques_are_definitely_max_size = !hit_internal_limit; | ||
83 | 303427 | return; | ||
84 | } | |||
85 |
1/2✓ Branch 1 taken 34599 times.
✗ Branch 2 not taken.
|
34599 | cliques = extended_result; | |
86 | // TODO: improve memory reallocation etc. by reusing rather than clearing | |||
87 | // (or, could be sneaky and do this within a single vector, jiggle with | |||
88 | // indices). | |||
89 | 34599 | extended_result.clear(); | ||
90 | } | |||
91 | ✗ | cliques_are_definitely_max_size = false; | ||
92 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 303427 times.
|
303427 | } | |
93 | ||||
94 | } // namespace graphs | |||
95 | } // namespace tket | |||
96 |