/* * computes the sizes of all subtrees of a tree with root r */ void SchnyderLayout::subtreeSizes( EdgeArray<int>& rValues, int i, node r, NodeArray<int>& size) { int sum = 0; for(adjEntry adj : r->adjEdges) { if (adj->theEdge()->source() == r && rValues[adj->theEdge()] == i) { node w = adj->twinNode(); subtreeSizes(rValues, i, w, size); sum += size[w]; } } size[r] = sum + 1; }
static TVector<TVector<size_t>> CalcSubtreeSizesForTree(const TObliviousTrees& forest, size_t treeIdx) { const int maxDepth = forest.TreeSizes[treeIdx]; TVector<TVector<size_t>> subtreeSizes(maxDepth + 1); subtreeSizes[maxDepth].resize(size_t(1) << maxDepth); for (size_t leafIdx = 0; leafIdx < (size_t(1) << maxDepth); ++leafIdx) { subtreeSizes[maxDepth][leafIdx] = size_t(forest.LeafWeights[treeIdx][leafIdx] + 0.5); } for (int depth = maxDepth - 1; depth >= 0; --depth) { const size_t nodeCount = size_t(1) << depth; subtreeSizes[depth].resize(nodeCount); for (size_t nodeIdx = 0; nodeIdx < nodeCount; ++nodeIdx) { subtreeSizes[depth][nodeIdx] = subtreeSizes[depth + 1][nodeIdx] + subtreeSizes[depth + 1][nodeIdx ^ (1 << depth)]; } } return subtreeSizes; }
void SchnyderLayout::schnyderEmbedding( GraphCopy& GC, GridLayout &gridLayout, adjEntry adjExternal) { NodeArray<int> &xcoord = gridLayout.x(); NodeArray<int> &ycoord = gridLayout.y(); node v; List<node> L; // (un)contraction order GraphCopy T = GraphCopy(GC); // the realizer tree (reverse direction of edges!!!) EdgeArray<int> rValues(T); // the realizer values // choose outer face a,b,c adjEntry adja; if (adjExternal != 0) { edge eG = adjExternal->theEdge(); edge eGC = GC.copy(eG); adja = (adjExternal == eG->adjSource()) ? eGC->adjSource() : eGC->adjTarget(); } else { adja = GC.firstEdge()->adjSource(); } adjEntry adjb = adja->faceCyclePred(); adjEntry adjc = adjb->faceCyclePred(); node a = adja->theNode(); node b = adjb->theNode(); node c = adjc->theNode(); node a_in_T = T.copy(GC.original(a)); node b_in_T = T.copy(GC.original(b)); node c_in_T = T.copy(GC.original(c)); contract(GC, a, b, c, L); realizer(GC, L, a, b, c, rValues, T); NodeArray<int> t1(T); NodeArray<int> t2(T); NodeArray<int> val(T, 1); NodeArray<int> P1(T); NodeArray<int> P3(T); NodeArray<int> v1(T); NodeArray<int> v2(T); subtreeSizes(rValues, 1, a_in_T, t1); subtreeSizes(rValues, 2, b_in_T, t2); prefixSum(rValues, 1, a_in_T, val, P1); prefixSum(rValues, 3, c_in_T, val, P3); // now Pi = depth of all nodes in Tree T(i) (depth[root] = 1) prefixSum(rValues, 2, b_in_T, t1, v1); // special treatment for a v1[a_in_T] = t1[a_in_T]; /* * v1[v] now is the sum of the * "count of nodes in t1" minus the "subtree size for node x" * for every node x on a path from b to v in t2 */ prefixSum(rValues, 3, c_in_T, t1, val); // special treatment for a val[a_in_T] = t1[a_in_T]; /* * val[v] now is the sum of the * "count of nodes in t1" minus the "subtree size for node x" * for every node x on a path from c to v in t3 */ // r1[v]=v1[v]+val[v]-t1[v] is the number of nodes in region 1 from v forall_nodes(v, T) { // calc v1' v1[v] += val[v] - t1[v] - P3[v]; }