rowvec dmse(rowvec &desire, rowvec &out, int size){ rowvec dcost(size); for(int i=0; i<size; ++i){ dcost(i) = out(i) - desire(i); } return dcost; }
/** Divide a path at a node. * @param i is a node in some path; the operation splits the path into three * parts, the original portion of the path that precedes i, i itself, and * the portion of the original path that follows i * @return the a pair consisting of the two new path segments */ PathSet::PathPair PathSet::split(index i) { PathPair pair(0,0); splay(i); if (left(i) == 0) pair.p1 = 0; else { pair.p1 = left(i); p(pair.p1) = 0; left(i) = 0; dmin(pair.p1) += dmin(i); } if (right(i) == 0) pair.p2 = 0; else { pair.p2 = right(i); p(pair.p2) = 0; right(i) = 0; dmin(pair.p2) += dmin(i); } dmin(i) += dcost(i); dcost(i) = 0; return pair; }
/** Find the the last node on a path that has minimum cost. * @param q is the canonical element of some path * @return a pair containing the last node on the path that has minimum * cost and its cost */ PathSet::PathCostPair PathSet::findpathcost(path q) { while (1) { if (right(q) != 0 && dmin(right(q)) == 0) q = right(q); else if (dcost(q) > 0) q = left(q); else break; } q = splay(q); PathCostPair cp(q,dmin(q)); return cp; }
/** Perform a rotation in a search tree representing a path. * @param x is a node in some path; the operation performs a rotation * at the parent of x, moving x up into its parent's position. */ void PathSet::rotate(index x) { index y = p(x); if (y == 0) return; index a, b, c; if (x == left(y)) { a = left(x); b = right(x); c = right(y); } else { a = right(x); b = left(x); c = left(y); } // do the rotation p(x) = p(y); if (y == left(p(y))) left(p(x)) = x; else if (y == right(p(y))) right(p(x)) = x; if (x == left(y)) { left(y) = right(x); if (left(y) != 0) p(left(y)) = y; right(x) = y; } else { right(y) = left(x); if (right(y) != 0) p(right(y)) = y; left(x) = y; } p(y) = x; // update dmin, dcost values dmin(a) += dmin(x); dmin(b) += dmin(x); dcost(x) = dcost(x) + dmin(x); cost dmx = dmin(x); dmin(x) = dmin(y); dmin(y) = dcost(y); if (b != 0) dmin(y) = min(dmin(y),dmin(b)+dmx); if (c != 0) dmin(y) = min(dmin(y),dmin(c)); dcost(y) = dcost(y) - dmin(y); dmin(b) -= dmin(y); dmin(c) -= dmin(y); pvals[x] = pvals[y]; // ensures that root node always has path value }
/** Join two paths at a node. * @param r is the canonical element of some path * @param i is an isolated node (equivalently, it is in a length 1 path) * @param q is the canonical element of some path * @return the new path formed by combining r,i and q (so r is the first * part of the resultant path, then i, then q); this new path replaces * the original paths */ path PathSet::join(path r, index i, path q) { cost dmin_i = dmin(i); left(i) = r; right(i) = q; if (r == 0 && q == 0) { ; // do nothing } else if (r == 0) { dmin(i) = min(dmin(i),dmin(q)); dmin(q) -= dmin(i); p(q) = i; } else if (q == 0) { dmin(i) = min(dmin(i),dmin(r)); dmin(r) -= dmin(i); p(r) = i; } else { dmin(i) = min(dmin(r),min(dmin(i),dmin(q))); dmin(r) -= dmin(i); dmin(q) -= dmin(i); p(r) = p(q) = i; } dcost(i) = dmin_i - dmin(i); return i; }
/** Initialize data structure, creating single node trees. */ void PathSet::clear() { for (index i = 0; i <= n(); i++) { left(i) = right(i) = p(i) = dcost(i) = dmin(i) = 0; } }
/** Determine the cost of a node without restructuring tree. * This method is used mainly to construct a string representation of * a path. * @param i is a node in some path * @return the cost of node i */ cost PathSet::nodeCost(index i) const { cost s; s = dcost(i); while (i != 0) { s += dmin(i); i = p(i); } return s; }