bool StateGraph::isValid(const SubDigraph& T, Arc a) { Node w = T.target(a); assert(T.status(T.source(a))); assert(!T.status(a)); assert(!T.status(w)); T.enable(a); T.enable(w); bool res = isValid(T); T.disable(a); T.disable(w); return res; }
Node TarjanHD::hd(const Digraph& g, const DoubleArcMap& w, SubDigraph& subG, NodeNodeMap& mapToOrgG, NodeNodeMap& G2T, const ArcList& sortedArcs, int i) { assert(i >= 0); int m = static_cast<int>(sortedArcs.size()); assert(m == lemon::countArcs(subG)); int r = m - i; if (r == 0 || r == 1) { // add to _T a subtree rooted at node r, // labeled with w(e_m) and having n children labeled with // the vertices of subG Node root = _T.addNode(); _label[root] = w[sortedArcs.back()]; _T2OrgG[root] = lemon::INVALID; for (SubNodeIt v(subG); v != lemon::INVALID; ++v) { Node vv = G2T[v]; if (vv == lemon::INVALID) { vv = _T.addNode(); _label[vv] = -1; if (mapToOrgG[v] != lemon::INVALID) { _orgG2T[mapToOrgG[v]] = vv; _T2OrgG[vv] = mapToOrgG[v]; } } _T.addArc(vv, root); } return root; } else { int j = (i + m) % 2 == 0 ? (i + m) / 2 : (i + m) / 2 + 1; // remove arcs j+1 .. m ArcListIt arcEndIt, arcIt = sortedArcs.begin(); for (int k = 1; k <= m; ++k) { if (k == j + 1) { arcEndIt = arcIt; } if (k > j) { subG.disable(*arcIt); } ++arcIt; } // compute SCCs IntNodeMap comp(g, -1); int numSCC = lemon::stronglyConnectedComponents(subG, comp); if (numSCC == 1) { ArcList newSortedArcs(sortedArcs.begin(), arcEndIt); // _subG is strongly connected return hd(g, w, subG, mapToOrgG, G2T, newSortedArcs, i); } else { // determine strongly connected components NodeHasher<Digraph> hasher(g); NodeSetVector components(numSCC, NodeSet(42, hasher)); for (SubNodeIt v(subG); v != lemon::INVALID; ++v) { components[comp[v]].insert(v); } NodeVector roots(numSCC, lemon::INVALID); double w_i = i > 0 ? w[getArcByRank(sortedArcs, i)] : -std::numeric_limits<double>::max(); for (int k = 0; k < numSCC; ++k) { const NodeSet& component = components[k]; if (component.size() > 1) { // construct new sorted arc list for component: O(m) time ArcList newSortedArcs; for (ArcListIt arcIt = sortedArcs.begin(); arcIt != arcEndIt; ++arcIt) { Node u = g.source(*arcIt); Node v = g.target(*arcIt); bool u_in_comp = component.find(u) != component.end(); bool v_in_comp = component.find(v) != component.end(); if (u_in_comp && v_in_comp) { newSortedArcs.push_back(*arcIt); } } // remove nodes not in component from the graph for (NodeIt v(g); v != lemon::INVALID; ++v) { subG.status(v, component.find(v) != component.end()); } // find new_i, i.e. largest k such that w(e'_k) <= w(e_i) // if i == 0 or i > 0 but no such k exists => new_i := 0 int new_i = get_i(newSortedArcs, w, w_i); // recurse on strongly connected component roots[k] = hd(g, w, subG, mapToOrgG, G2T, newSortedArcs, new_i); } // enable all nodes again for (int k = 0; k < numSCC; ++k) { const NodeSet& component = components[k]; for (NodeSetIt nodeIt = component.begin(); nodeIt != component.end(); ++nodeIt) { subG.enable(*nodeIt); } } } // construct the condensed graph: // each strongly connected component is collapsed into a single node, and // from the resulting sets of multiple arcs retain only those with minimum weight Digraph c; DoubleArcMap ww(c); NodeNodeMap mapCToOrgG(c); NodeNodeMap C2T(c); ArcList newSortedArcs; int new_i = constructCondensedGraph(g, w, mapToOrgG, G2T, sortedArcs, comp, components, roots, j, c, ww, mapCToOrgG, C2T, newSortedArcs); BoolArcMap newArcFilter(c, true); BoolNodeMap newNodeFilter(c, true); SubDigraph subC(c, newNodeFilter, newArcFilter); Node root = hd(c, ww, subC, mapCToOrgG, C2T, newSortedArcs, new_i); return root; } } return lemon::INVALID; }
void StateGraph::grow(const IntPairSet& L, const StlBoolMatrix& LL, bool includeMutationEdge, SubDigraph& G, SubDigraph& T, ArcList& F, StlIntMatrix& V, Arc& mutationEdge) { if (isValid(L, LL, T, V) && mutationEdge != lemon::INVALID) { // report finalize(L, LL, T, V); // writeDOT(T, std::cout); } else { if (isValid(L, LL, T, V)) { // report finalize(L, LL, T, V); // writeDOT(T, std::cout); } ArcList FF; while (!F.empty()) { assert(!F.empty()); Arc uv = F.back(); F.pop_back(); Node u = G.source(uv); Node v = G.target(uv); int x_v = _x[v]; int y_v = _y[v]; // mutation edge => V[x_v][y_v] == 0 assert(mutationEdge == lemon::INVALID || V[x_v][y_v] == 0); assert(V[x_v][y_v] <= 1); // update V ++V[x_v][y_v]; if (_type[uv] == MUTATION) { mutationEdge = uv; } assert(T.status(u)); assert(!T.status(v)); assert(!T.status(uv)); // add uv to T T.enable(v); T.enable(uv); ArcList newF = F; // remove arcs from F for (ArcListNonConstIt it = newF.begin(); it != newF.end();) { Arc st = *it; Node s = T.source(st); Node t = T.target(st); int x_t = _x[t]; int y_t = _y[t]; if (v == t || (v != s && x_v == x_t && y_v == y_t) || (mutationEdge == uv && V[x_t][y_t] == 1)) { assert(T.status(s)); it = newF.erase(it); } else { ++it; } } // push each arc vw where w not in V(T) onto F for (SubOutArcIt vw(G, v); vw != lemon::INVALID; ++vw) { Node w = G.target(vw); if (T.status(w)) continue; int x_w = _x[w]; int y_w = _y[w]; if ((includeMutationEdge && mutationEdge == lemon::INVALID && x_v == x_w && y_v == y_w) || V[x_w][y_w] == 0) { newF.push_back(vw); } } // writeDOT(T, newF, std::cout); grow(L, LL, includeMutationEdge, G, T, newF, V, mutationEdge); G.disable(uv); if (uv == mutationEdge) { assert(includeMutationEdge); mutationEdge = lemon::INVALID; } T.disable(uv); T.disable(v); --V[x_v][y_v]; FF.push_back(uv); } for (ArcListRevIt it = FF.rbegin(); it != FF.rend(); ++it) { Arc a = *it; assert(!G.status(a)); F.push_back(*it); G.enable(a); } } }