This repository was archived by the owner on Dec 10, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathembedding_validator.cpp
More file actions
103 lines (86 loc) · 3.11 KB
/
Copy pathembedding_validator.cpp
File metadata and controls
103 lines (86 loc) · 3.11 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "embedding_validator.hpp"
#include <common/utils.hpp>
#include <common/embedding_state.hpp>
using namespace majorminer;
bool EmbeddingValidator::isDisjoint() const
{
UnorderedSet<fuint32_t> nodesOccupied{};
const auto& embedding = m_state.getMapping();
for (const auto& mapped : embedding)
{
if (nodesOccupied.contains(mapped.second))
{
DEBUG(OUT_S << "Not an injective mapping." << std::endl;)
DEBUG(printOverlappings();)
return false;
}
nodesOccupied.insert(mapped.second);
}
return true;
}
void EmbeddingValidator::printOverlappings() const
{
fuint32_pair_t stats = calculateOverlappingStats(m_state);
std::cout << "Overlapping statistics:" << std::endl
<< "Distinct overlaps: " << stats.first << std::endl
<< "Total overlapping: " << stats.second << std::endl;
}
bool EmbeddingValidator::nodesConnected() const
{
const auto& embedding = m_state.getMapping();
const auto& sourceGraph = *m_state.getSourceGraph();
UnorderedMultiMap<fuint32_t, fuint32_t> adjacencies{};
for (const auto& e : sourceGraph)
{
adjacencies.insert(orderedPair(e));
}
UnorderedMap<fuint32_t, std::atomic<bool>> adjacentNodes{};
auto groupIt = adjacencies.begin();
while(groupIt != adjacencies.end())
{
adjacentNodes.clear();
auto adjRange = adjacencies.equal_range(groupIt->first);
for (auto it = adjRange.first; it != adjRange.second; ++it)
{
adjacentNodes.insert(std::make_pair(it->second, false));
}
auto mappedRange = embedding.equal_range(groupIt->first);
// for each node in adjacentNodes search for adjacency to mappedNodes
tbb::parallel_for_each(mappedRange.first, mappedRange.second,
[&](fuint32_pair_t targetNodeP) {
m_state.iterateReverseMapping(targetNodeP.second, [&](fuint32_t reverse){
if (adjacentNodes.contains(reverse)) adjacentNodes[reverse] = true;
});
m_state.iterateTargetAdjacentReverseMapping(targetNodeP.second, [&](fuint32_t revSourceNode){
if (adjacentNodes.contains(revSourceNode)) adjacentNodes[revSourceNode] = true;
});
});
for (const auto& adjNode : adjacentNodes)
{
if (!adjNode.second)
{
DEBUG(OUT_S << "Not all edges embedded! Node " << adjNode.first << " is missing at least one edge." << std::endl;)
DEBUG(printMissingEdges(adjNode.first));
return false;
}
}
groupIt = adjRange.second;
}
return true;
}
void EmbeddingValidator::printMissingEdges(fuint32_t node) const
{
nodeset_t missingAdjacent{};
m_state.iterateSourceGraphAdjacent(node, [&missingAdjacent](fuint32_t adjacentSource)
{ missingAdjacent.insert(adjacentSource); });
if (missingAdjacent.empty()) return;
m_state.iterateSourceMappingAdjacent<false>(node, [&](fuint32_t adjacent, fuint32_t){
m_state.iterateReverseMapping(adjacent, [&](fuint32_t reverse){
missingAdjacent.unsafe_erase(reverse);
});
return false;
});
OUT_S << "Node " << node << " is missing edges to nodes { ";
for (auto missing : missingAdjacent) OUT_S << missing << " ";
OUT_S << "}" << std::endl;
}