43 int assignmentSolverID_ = 0;
44 bool squared_ =
false;
45 bool computeMapping_ =
false;
47 template <
class dataType>
48 inline dataType editCost_Persistence(
int n1,
56 dataType b1 = tree2->
getValue<dataType>(n2);
57 dataType d1 = tree2->
getValue<dataType>(p2);
58 d = (d1 > b1) ? (d1 - b1) : (b1 - d1);
60 dataType b1 = tree1->
getValue<dataType>(n1);
61 dataType d1 = tree1->
getValue<dataType>(p1);
62 d = (d1 > b1) ? (d1 - b1) : (b1 - d1);
64 dataType b1 = tree1->
getValue<dataType>(n1);
65 dataType d1 = tree1->
getValue<dataType>(p1);
66 dataType b2 = tree2->
getValue<dataType>(n2);
67 dataType d2 = tree2->
getValue<dataType>(p2);
68 dataType dist1 = (d1 > b1) ? (d1 - b1) : (b1 - d1);
69 dataType dist2 = (d2 > b2) ? (d2 - b2) : (b2 - d2);
70 d = (dist1 > dist2) ? (dist1 - dist2) : (dist2 - dist1);
72 return squared_ ? d * d : d;
75 template <
class dataType>
76 void traceMapping_path(
83 std::vector<std::vector<int>> &predecessors1,
84 std::vector<std::vector<int>> &predecessors2,
88 std::vector<std::pair<std::pair<ftm::idNode, ftm::idNode>,
89 std::pair<ftm::idNode, ftm::idNode>>> &mapping) {
93 std::vector<ftm::idNode> children1;
95 std::vector<ftm::idNode> children2;
97 int parent1 = predecessors1[curr1][predecessors1[curr1].size() - l1];
98 int parent2 = predecessors2[curr2][predecessors2[curr2].size() - l2];
102 size_t const dim1 = 1;
103 size_t const dim2 = (nn1 + 1) * dim1;
104 size_t const dim3 = (depth1 + 1) * dim2;
105 size_t const dim4 = (nn2 + 1) * dim3;
112 mapping.emplace_back(
113 std::make_pair(curr1, parent1), std::make_pair(curr2, parent2));
120 for(
auto child2_mb : children2) {
122 = memT[curr1 + l1 * dim2 + child2_mb * dim3 + (l2 + 1) * dim4];
123 for(
auto child2 : children2) {
124 if(child2 == child2_mb) {
127 d_ += memT[nn1 + 0 * dim2 + child2 * dim3 + 1 * dim4];
129 if(memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4] == d_) {
130 traceMapping_path(tree1, tree2, curr1, l1, child2_mb, l2 + 1,
131 predecessors1, predecessors2, depth1, depth2,
141 dataType d = std::numeric_limits<dataType>::max();
142 for(
auto child1_mb : children1) {
144 = memT[child1_mb + (l1 + 1) * dim2 + curr2 * dim3 + l2 * dim4];
145 for(
auto child1 : children1) {
146 if(child1 == child1_mb) {
149 d_ += memT[child1 + 1 * dim2 + nn2 * dim3 + 0 * dim4];
152 if(memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4] == d_) {
153 traceMapping_path(tree1, tree2, child1_mb, l1 + 1, curr2, l2,
154 predecessors1, predecessors2, depth1, depth2,
170 int child11 = children1[0];
171 int child12 = children1[1];
172 int child21 = children2[0];
173 int child22 = children2[1];
174 if(memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4]
175 == memT[child11 + 1 * dim2 + child21 * dim3 + 1 * dim4]
176 + memT[child12 + 1 * dim2 + child22 * dim3 + 1 * dim4]
177 + editCost_Persistence<dataType>(
178 curr1, parent1, curr2, parent2, tree1, tree2)) {
179 mapping.emplace_back(
180 std::make_pair(curr1, parent1), std::make_pair(curr2, parent2));
181 traceMapping_path(tree1, tree2, child11, 1, child21, 1,
182 predecessors1, predecessors2, depth1, depth2,
184 traceMapping_path(tree1, tree2, child12, 1, child22, 1,
185 predecessors1, predecessors2, depth1, depth2,
188 if(memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4]
189 == memT[child11 + 1 * dim2 + child22 * dim3 + 1 * dim4]
190 + memT[child12 + 1 * dim2 + child21 * dim3 + 1 * dim4]
191 + editCost_Persistence<dataType>(
192 curr1, parent1, curr2, parent2, tree1, tree2)) {
193 mapping.emplace_back(
194 std::make_pair(curr1, parent1), std::make_pair(curr2, parent2));
195 traceMapping_path(tree1, tree2, child11, 1, child22, 1,
196 predecessors1, predecessors2, depth1, depth2,
198 traceMapping_path(tree1, tree2, child12, 1, child21, 1,
199 predecessors1, predecessors2, depth1, depth2,
204 auto f = [&](
int r,
int c) {
209 int const l1_ = c1 == nn1 ? 0 : 1;
210 int const l2_ = c2 == nn2 ? 0 : 1;
211 return memT[c1 + l1_ * dim2 + c2 * dim3 + l2_ * dim4];
216 auto costMatrix = std::vector<std::vector<dataType>>(
217 size, std::vector<dataType>(size, 0));
218 std::vector<MatchingType> matching;
219 for(
int r = 0; r < size; r++) {
220 for(
int c = 0; c < size; c++) {
221 costMatrix[r][c] = f(r, c);
229 switch(assignmentSolverID_) {
232 assignmentSolver = &solverExhaustive;
236 assignmentSolver = &solverMunkres;
241 assignmentSolver = &solverAuction;
243 assignmentSolver->
setInput(costMatrix);
245 assignmentSolver->
run(matching);
246 dataType d_ = editCost_Persistence<dataType>(
247 curr1, parent1, curr2, parent2, tree1, tree2);
248 for(
auto m : matching)
249 d_ += std::get<2>(m);
250 if(memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4] == d_) {
251 mapping.emplace_back(
252 std::make_pair(curr1, parent1), std::make_pair(curr2, parent2));
253 for(
auto m : matching) {
255 ? children1[std::get<0>(m)]
258 ? children2[std::get<1>(m)]
260 if(n1 >= 0 && n2 >= 0)
261 traceMapping_path(tree1, tree2, n1, 1, n2, 1, predecessors1,
262 predecessors2, depth1, depth2, memT, mapping);
271 for(
auto child1_mb : children1) {
273 = memT[child1_mb + (l1 + 1) * dim2 + curr2 * dim3 + l2 * dim4];
274 for(
auto child1 : children1) {
275 if(child1 == child1_mb) {
278 d_ += memT[child1 + 1 * dim2 + nn2 * dim3 + 0 * dim4];
280 if(memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4] == d_) {
281 traceMapping_path(tree1, tree2, child1_mb, l1 + 1, curr2, l2,
282 predecessors1, predecessors2, depth1, depth2,
291 for(
auto child2_mb : children2) {
293 = memT[curr1 + l1 * dim2 + child2_mb * dim3 + (l2 + 1) * dim4];
294 for(
auto child2 : children2) {
295 if(child2 == child2_mb) {
298 d_ += memT[nn1 + 0 * dim2 + child2 * dim3 + 1 * dim4];
300 if(memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4] == d_) {
301 traceMapping_path(tree1, tree2, curr1, l1, child2_mb, l2 + 1,
302 predecessors1, predecessors2, depth1, depth2,
313 "MergeTreeDistance");
323 assignmentSolverID_ = assignmentSolver;
334 template <
class dataType>
341 int const rootID1 = tree1->
getRoot();
342 int const rootID2 = tree2->
getRoot();
348 std::stack<int> stack;
351 while(!stack.empty()) {
352 int const nIdx = stack.top();
354 preorder1[count] = nIdx;
356 depth1 = std::max((
int)predecessors1[nIdx].size(), depth1);
357 std::vector<ftm::idNode> children;
359 for(
int const cIdx : children) {
361 predecessors1[cIdx].reserve(predecessors1[nIdx].size() + 1);
362 predecessors1[cIdx].insert(predecessors1[cIdx].
end(),
363 predecessors1[nIdx].begin(),
364 predecessors1[nIdx].end());
365 predecessors1[cIdx].push_back(nIdx);
370 while(!stack.empty()) {
371 int const nIdx = stack.top();
373 preorder2[count] = nIdx;
375 depth2 = std::max((
int)predecessors2[nIdx].size(), depth2);
376 std::vector<ftm::idNode> children;
378 for(
int const cIdx : children) {
380 predecessors2[cIdx].reserve(predecessors2[nIdx].size() + 1);
381 predecessors2[cIdx].insert(predecessors2[cIdx].
end(),
382 predecessors2[nIdx].begin(),
383 predecessors2[nIdx].end());
384 predecessors2[cIdx].push_back(nIdx);
390 size_t const dim1 = 1;
391 size_t const dim2 = (nn1 + 1) * dim1;
392 size_t const dim3 = (depth1 + 1) * dim2;
393 size_t const dim4 = (nn2 + 1) * dim3;
395 std::vector<dataType> memT((nn1 + 1) * (depth1 + 1) * (nn2 + 1)
398 memT[nn1 + 0 * dim2 + nn2 * dim3 + 0 * dim4] = 0;
399 for(
size_t i = 0; i < nn1; i++) {
400 int curr1 = preorder1[i];
401 std::vector<ftm::idNode> children1;
403 for(
size_t l = 1; l <= predecessors1[preorder1[i]].size(); l++) {
404 int parent1 = predecessors1[preorder1[i]]
405 [predecessors1[preorder1[i]].size() - l];
409 memT[curr1 + l * dim2 + nn2 * dim3 + 0 * dim4]
410 = editCost_Persistence<dataType>(
411 curr1, parent1, -1, -1, tree1, tree2);
412 for(
auto child1 : children1) {
413 memT[curr1 + l * dim2 + nn2 * dim3 + 0 * dim4]
414 += memT[child1 + 1 * dim2 + nn2 * dim3 + 0 * dim4];
418 for(
size_t j = 0; j < nn2; j++) {
419 int curr2 = preorder2[j];
420 std::vector<ftm::idNode> children2;
422 for(
size_t l = 1; l <= predecessors2[preorder2[j]].size(); l++) {
423 int parent2 = predecessors2[preorder2[j]]
424 [predecessors2[preorder2[j]].size() - l];
428 memT[nn1 + 0 * dim2 + curr2 * dim3 + l * dim4]
429 = editCost_Persistence<dataType>(
430 -1, -1, curr2, parent2, tree1, tree2);
431 for(
auto child2 : children2) {
432 memT[nn1 + 0 * dim2 + curr2 * dim3 + l * dim4]
433 += memT[nn1 + 0 * dim2 + child2 * dim3 + 1 * dim4];
438 for(
size_t i = 0; i < nn1; i++) {
439 int curr1 = preorder1[i];
440 std::vector<ftm::idNode> children1;
442 for(
size_t j = 0; j < nn2; j++) {
443 int curr2 = preorder2[j];
444 std::vector<ftm::idNode> children2;
446 for(
size_t l1 = 1; l1 <= predecessors1[preorder1[i]].size(); l1++) {
448 = predecessors1[preorder1[i]]
449 [predecessors1[preorder1[i]].size() - l1];
450 for(
size_t l2 = 1; l2 <= predecessors2[preorder2[j]].size(); l2++) {
452 = predecessors2[preorder2[j]]
453 [predecessors2[preorder2[j]].size() - l2];
463 memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4]
464 = editCost_Persistence<dataType>(
465 curr1, parent1, curr2, parent2, tree1, tree2);
471 dataType d = std::numeric_limits<dataType>::max();
472 for(
auto child2_mb : children2) {
473 dataType d_ = memT[curr1 + l1 * dim2 + child2_mb * dim3
475 for(
auto child2 : children2) {
476 if(child2 == child2_mb) {
479 d_ += memT[nn1 + 0 * dim2 + child2 * dim3 + 1 * dim4];
483 memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4] = d;
489 dataType d = std::numeric_limits<dataType>::max();
490 for(
auto child1_mb : children1) {
491 dataType d_ = memT[child1_mb + (l1 + 1) * dim2 + curr2 * dim3
493 for(
auto child1 : children1) {
494 if(child1 == child1_mb) {
497 d_ += memT[child1 + 1 * dim2 + nn2 * dim3 + 0 * dim4];
501 memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4] = d;
507 dataType d = std::numeric_limits<dataType>::max();
514 int const child11 = children1[0];
515 int const child12 = children1[1];
516 int const child21 = children2[0];
517 int const child22 = children2[1];
518 d = std::min<dataType>(
519 d, memT[child11 + 1 * dim2 + child21 * dim3 + 1 * dim4]
520 + memT[child12 + 1 * dim2 + child22 * dim3 + 1 * dim4]
521 + editCost_Persistence<dataType>(
522 curr1, parent1, curr2, parent2, tree1, tree2));
523 d = std::min<dataType>(
524 d, memT[child11 + 1 * dim2 + child22 * dim3 + 1 * dim4]
525 + memT[child12 + 1 * dim2 + child21 * dim3 + 1 * dim4]
526 + editCost_Persistence<dataType>(
527 curr1, parent1, curr2, parent2, tree1, tree2));
529 auto f = [&](
int r,
int c) {
536 int const l1_ = c1 == nn1 ? 0 : 1;
537 int const l2_ = c2 == nn2 ? 0 : 1;
538 return memT[c1 + l1_ * dim2 + c2 * dim3 + l2_ * dim4];
543 auto costMatrix = std::vector<std::vector<dataType>>(
544 size, std::vector<dataType>(size, 0));
545 std::vector<MatchingType> matching;
546 for(
int r = 0; r < size; r++) {
547 for(
int c = 0; c < size; c++) {
548 costMatrix[r][c] = f(r, c);
556 switch(assignmentSolverID_) {
559 assignmentSolver = &solverExhaustive;
563 assignmentSolver = &solverMunkres;
568 assignmentSolver = &solverAuction;
570 assignmentSolver->
setInput(costMatrix);
572 assignmentSolver->
run(matching);
573 dataType d_ = editCost_Persistence<dataType>(
574 curr1, parent1, curr2, parent2, tree1, tree2);
575 for(
auto m : matching)
576 d_ += std::get<2>(m);
583 for(
auto child1_mb : children1) {
584 dataType d_ = memT[child1_mb + (l1 + 1) * dim2 + curr2 * dim3
586 for(
auto child1 : children1) {
587 if(child1 == child1_mb) {
590 d_ += memT[child1 + 1 * dim2 + nn2 * dim3 + 0 * dim4];
598 for(
auto child2_mb : children2) {
599 dataType d_ = memT[curr1 + l1 * dim2 + child2_mb * dim3
601 for(
auto child2 : children2) {
602 if(child2 == child2_mb) {
605 d_ += memT[nn1 + 0 * dim2 + child2 * dim3 + 1 * dim4];
609 memT[curr1 + l1 * dim2 + curr2 * dim3 + l2 * dim4] = d;
616 std::vector<ftm::idNode> children1;
618 std::vector<ftm::idNode> children2;
622 = memT[children1[0] + 1 * dim2 + children2[0] * dim3 + 1 * dim4];
624 return squared_ ? std::sqrt(res) : res;