bool HammingLoss::isBestEffort(Crag::CragEdge e, const Crag& crag, const BestEffort& bestEffort) { if (!_balance) return bestEffort.selected(e); // if balanced, non-leaf edges are not considered part of best-effort if (!crag.isLeafEdge(e)) return false; std::vector<Crag::CragNode> uPath = getPath(e.u(), crag); std::vector<Crag::CragNode> vPath = getPath(e.v(), crag); // are the paths of u and v merging somewhere? for (Crag::CragNode u : uPath) for (Crag::CragNode v : vPath) { if (u == v && bestEffort.selected(u)) return true; for (Crag::CragEdge e : crag.adjEdges(u)) if (crag.oppositeNode(u, e) == v && bestEffort.selected(e)) return true; } return false; }
HammingLoss::HammingLoss( const Crag& crag, const BestEffort& bestEffort, int balance) : Loss(crag), _balance((balance == 2 && optionBalanceHammingLoss) || (balance == 1)) { constant = 0; for (Crag::CragNode n : crag.nodes()) if (isBestEffort(n, crag, bestEffort)) { if (_balance) UTIL_ASSERT(crag.isLeafNode(n));; node[n] = -1; constant++; } else { if (!_balance || crag.isLeafNode(n)) node[n] = 1; } for (Crag::CragEdge e : crag.edges()) if (isBestEffort(e, crag, bestEffort)) { if (_balance) UTIL_ASSERT(crag.isLeafEdge(e));; edge[e] = -1; constant++; } else { if (!_balance || crag.isLeafEdge(e)) edge[e] = 1; } if (_balance) propagateLeafLoss(crag); }