82 std::vector<std::vector<ftm::idNode>> &parents,
83 std::vector<std::vector<ftm::idNode>> &children,
84 std::vector<float> &scalarsVector,
85 std::vector<std::vector<ftm::idNode>> &childrenFinal,
88 unsigned int noNodes = scalarsVector.size() / 2;
89 childrenFinal.resize(noNodes);
90 int mtLevel = ceil(log(noNodes * 2) / log(2)) + 1;
91 int bdtLevel = mtLevel - 1;
95 std::vector<int> nodeLevels(noNodes, -1);
96 std::queue<ftm::idNode> queueLevels;
97 std::vector<int> noChildDone(noNodes, 0);
98 for(
unsigned int i = 0; i < children.size(); ++i) {
99 if(children[i].size() == 0) {
100 queueLevels.emplace(i);
104 while(!queueLevels.empty()) {
107 for(
auto &parent : parents[node]) {
108 ++noChildDone[parent];
109 nodeLevels[parent] = std::max(nodeLevels[parent], nodeLevels[node] + 1);
110 if(noChildDone[parent] >= (
int)children[parent].size())
111 queueLevels.emplace(parent);
116 auto sortChildren = [&parents, &scalarsVector, &noNodes, &threadNumber](
117 ftm::idNode nodeOrigin, std::vector<bool> &nodeDone,
118 std::vector<std::vector<ftm::idNode>> &childrenT) {
119 double refPers = scalarsVector[1] - scalarsVector[0];
120 auto getRemaining = [&nodeDone](std::vector<ftm::idNode> &vec) {
121 unsigned int remaining = 0;
123 remaining += (not nodeDone[e]);
126 std::vector<unsigned int> parentsRemaining(noNodes, 0),
127 childrenRemaining(noNodes, 0);
128 for(
auto &child : childrenT[nodeOrigin]) {
129 parentsRemaining[child] = getRemaining(parents[child]);
130 childrenRemaining[child] = getRemaining(childrenT[child]);
134 threadNumber, childrenT[nodeOrigin].
begin(), childrenT[nodeOrigin].
end(),
136 double persI = scalarsVector[nodeI * 2 + 1] - scalarsVector[nodeI * 2];
137 double persJ = scalarsVector[nodeJ * 2 + 1] - scalarsVector[nodeJ * 2];
138 return parentsRemaining[nodeI] + childrenRemaining[nodeI]
139 - persI / refPers * noNodes
140 < parentsRemaining[nodeJ] + childrenRemaining[nodeJ]
141 - persJ / refPers * noNodes;
146 const auto findStructGivenDim =
147 [&children, &noNodes, &nodeLevels](
148 ftm::idNode _nodeOrigin,
int _dimToFound,
bool _searchMaxDim,
149 std::vector<bool> &_nodeDone, std::vector<bool> &_dimFound,
150 std::vector<std::vector<ftm::idNode>> &_childrenFinalOut) {
152 auto findStructGivenDimImpl =
153 [&children, &noNodes, &nodeLevels](
154 ftm::idNode nodeOrigin,
int dimToFound,
bool searchMaxDim,
155 std::vector<bool> &nodeDone, std::vector<bool> &dimFound,
156 std::vector<std::vector<ftm::idNode>> &childrenFinalOut,
157 auto &findStructGivenDimRef)
mutable {
158 childrenFinalOut.resize(noNodes);
160 int dim = (searchMaxDim ? dimToFound - 1 : 0);
163 auto searchMaxDimReset = [&i, &dim, &nodeDone]() {
166 unsigned int noDone = 0;
167 for(
auto done : nodeDone)
170 return noDone == nodeDone.size() - 1;
172 while(i < children[nodeOrigin].size()) {
173 auto child = children[nodeOrigin][i];
175 if(nodeDone[child]) {
178 if(searchMaxDim and i == children[nodeOrigin].size() - 1) {
179 if(searchMaxDimReset())
187 childrenFinalOut[nodeOrigin].emplace_back(child);
188 nodeDone[child] =
true;
190 if(dimToFound <= 1 or searchMaxDim)
195 std::vector<std::vector<ftm::idNode>> childrenFinalDim;
196 std::vector<bool> nodeDoneDim;
197 std::vector<bool> dimFoundDim(dim);
199 if(nodeLevels[child] > dim) {
200 nodeDoneDim = nodeDone;
201 found = findStructGivenDimRef(child, dim,
false, nodeDoneDim,
202 dimFoundDim, childrenFinalDim,
203 findStructGivenDimRef);
206 dimFound[dim] =
true;
207 childrenFinalOut[nodeOrigin].emplace_back(child);
208 for(
unsigned int j = 0; j < childrenFinalDim.size(); ++j)
209 for(
auto &e : childrenFinalDim[j])
210 childrenFinalOut[j].emplace_back(e);
211 nodeDone[child] =
true;
212 for(
unsigned int j = 0; j < nodeDoneDim.size(); ++j)
213 nodeDone[j] = nodeDone[j] || nodeDoneDim[j];
215 if(dim == dimToFound - 1 and not searchMaxDim)
219 if(searchMaxDimReset())
225 }
else if(searchMaxDim and i == children[nodeOrigin].size() - 1) {
228 if(searchMaxDimReset())
237 return findStructGivenDimImpl(_nodeOrigin, _dimToFound, _searchMaxDim,
238 _nodeDone, _dimFound, _childrenFinalOut,
239 findStructGivenDimImpl);
241 std::vector<bool> dimFound(noDim - 1,
false);
242 std::vector<bool> nodeDone(noNodes,
false);
243 for(
unsigned int i = 0; i < children.size(); ++i)
244 sortChildren(i, nodeDone, children);
247 findStructGivenDim(startNode, noDim,
true, nodeDone, dimFound, childrenFinal);
250 const auto createStructGivenDim =
251 [&children, &noNodes, &findStructGivenDim, &nodeLevels](
252 int _nodeOrigin,
int _dimToCreate, std::vector<bool> &_nodeDone,
253 ftm::idNode &_structOrigin, std::vector<float> &_scalarsVectorOut,
254 std::vector<std::vector<ftm::idNode>> &_childrenFinalOut) {
256 auto createStructGivenDimImpl =
257 [&children, &noNodes, &findStructGivenDim, &nodeLevels](
258 int nodeOrigin,
int dimToCreate, std::vector<bool> &nodeDoneImpl,
259 ftm::idNode &structOrigin, std::vector<float> &scalarsVectorOut,
260 std::vector<std::vector<ftm::idNode>> &childrenFinalOut,
261 auto &createStructGivenDimRef)
mutable {
266 int dimToFound = dimToCreate - 1;
267 std::vector<std::vector<std::vector<ftm::idNode>>> childrenFinalT(2);
268 std::array<ftm::idNode, 2> structOrigins;
269 for(
unsigned int n = 0; n < 2; ++n) {
271 for(
unsigned int i = 0; i < children[nodeOrigin].size(); ++i) {
272 auto child = children[nodeOrigin][i];
273 if(nodeDoneImpl[child])
275 if(dimToFound != 0) {
276 if(nodeLevels[child] > dimToFound) {
277 std::vector<bool> dimFoundT(dimToFound,
false);
278 childrenFinalT[n].clear();
279 childrenFinalT[n].resize(noNodes);
280 std::vector<bool> nodeDoneImplFind = nodeDoneImpl;
281 found = findStructGivenDim(child, dimToFound,
false,
282 nodeDoneImplFind, dimFoundT,
288 structOrigins[n] = child;
289 nodeDoneImpl[child] =
true;
290 for(
unsigned int j = 0; j < childrenFinalT[n].size(); ++j) {
291 for(
auto &e : childrenFinalT[n][j]) {
292 childrenFinalOut[j].emplace_back(e);
293 nodeDoneImpl[e] =
true;
300 if(dimToFound <= 0) {
301 structOrigins[n] = std::numeric_limits<ftm::idNode>::max();
304 childrenFinalT[n].clear();
305 childrenFinalT[n].resize(noNodes);
306 createStructGivenDimRef(
307 nodeOrigin, dimToFound, nodeDoneImpl, structOrigins[n],
308 scalarsVectorOut, childrenFinalT[n], createStructGivenDimRef);
309 for(
unsigned int j = 0; j < childrenFinalT[n].size(); ++j) {
310 for(
auto &e : childrenFinalT[n][j]) {
311 if(e == structOrigins[n])
313 childrenFinalOut[j].emplace_back(e);
319 if(structOrigins[0] == std::numeric_limits<ftm::idNode>::max()
320 and structOrigins[1] == std::numeric_limits<ftm::idNode>::max()) {
321 structOrigin = std::numeric_limits<ftm::idNode>::max();
324 bool firstIsParent =
true;
325 if(structOrigins[0] == std::numeric_limits<ftm::idNode>::max())
326 firstIsParent =
false;
327 else if(structOrigins[1] == std::numeric_limits<ftm::idNode>::max())
328 firstIsParent =
true;
329 else if(scalarsVectorOut[structOrigins[1] * 2 + 1]
330 - scalarsVectorOut[structOrigins[1] * 2]
331 > scalarsVectorOut[structOrigins[0] * 2 + 1]
332 - scalarsVectorOut[structOrigins[0] * 2])
333 firstIsParent =
false;
334 structOrigin = (firstIsParent ? structOrigins[0] : structOrigins[1]);
336 = (firstIsParent ? structOrigins[1] : structOrigins[0]);
337 childrenFinalOut[nodeOrigin].emplace_back(structOrigin);
338 if(modOrigin != std::numeric_limits<ftm::idNode>::max()) {
339 childrenFinalOut[structOrigin].emplace_back(modOrigin);
340 std::queue<std::array<ftm::idNode, 2>> queue;
341 queue.emplace(std::array<ftm::idNode, 2>{modOrigin, structOrigin});
342 while(!queue.empty()) {
343 auto &nodeAndParent = queue.front();
349 for(
auto &child : childrenFinalOut[node])
350 queue.emplace(std::array<ftm::idNode, 2>{child, node});
355 return createStructGivenDimImpl(
356 _nodeOrigin, _dimToCreate, _nodeDone, _structOrigin, _scalarsVectorOut,
357 _childrenFinalOut, createStructGivenDimImpl);
359 for(
unsigned int i = 0; i < children.size(); ++i)
360 sortChildren(i, nodeDone, children);
362 for(
unsigned int i = 0; i < dimFound.size(); ++i) {
366 createStructGivenDim(
367 startNode, i, nodeDone, structOrigin, scalarsVector, childrenFinal);