static bool Graph_divide(Graph& graph, size_t loops, PositionList* position_tbl) { typedef std::set< size_t > NodeList; NodeList nodes; // nodes for (Graph::const_iterator i = graph.begin(); i != graph.end(); ++i) { nodes.insert(i->first); } while (!nodes.empty()) { // BFS Graph component; std::deque< size_t > Q = boost::assign::list_of(*nodes.begin()); while (!Q.empty()) { size_t xi = Q.front(); Q.pop_front(); if (nodes.find(xi) == nodes.end()) { continue; } nodes.erase(xi); Graph::const_iterator i = graph.find(xi); if (i != graph.end()) { for (Children::const_iterator j = i->second.children.begin(); j != i->second.children.end(); ++j) { Graph_addEdge(component, xi, j->first, j->second); Q.push_back(j->first); } for (Parents::const_iterator j = i->second.parents.begin(); j != i->second.parents.end(); ++j) { Q.push_back(*j); } } } LOG4CXX_TRACE(logger, boost::format("component:%d/%d") % component.size() % graph.size()); if (!Graph_solve(component, loops, position_tbl)) { LOG4CXX_ERROR(logger, "solve component failed"); return false; } } return true; }
Node * extractBestNode() { // TODO use a better datastructure if(nodes.empty()) { return NULL; } NodeList::iterator best = nodes.begin(); float cost = std::numeric_limits<float>::max(); for(NodeList::iterator i = nodes.begin(); i != nodes.end(); ++i) { if((*i)->getCost() < cost) { cost = (*i)->getCost(); best = i; } } Node * node = *best; nodes.erase(best); return node; }
Edges *MaxAcyclicSubgraph::find_subgraph() { Edges *Ea = new Edges; stack< NodeList::iterator > toRemove; NodeList *copy = copy_graph(); Node *node = NULL; COLA_ASSERT(!copy->empty()); COLA_ASSERT(!edges->empty()); #ifdef COPY_ADJ_DEBUG cout << "COPY OF MATRIX: " << endl; printNodes(copy); #endif // while the graph is not empty while (!copy->empty()) { COLA_ASSERT(toRemove.empty()); // do we have any sinks for (NodeList::iterator ni = copy->begin(); ni != copy->end(); ni++) { // is is a sink if there are no outgoing edges node = *ni; if (node->outgoing.empty()) { #ifdef RUN_DEBUG cout << "vertex(" << node->id << ") is a SINK" << endl; #endif // append it's incoming edges to Ea for (unsigned j = 0; j < node->incoming.size(); j++) { #ifdef RUN_DEBUG cout << "Appending to Ea: Edge(" << node->incoming[j].first << ", " << node->incoming[j].second << ")" << endl; #endif Ea->push_back(node->incoming[j]); // find the edge from a vertex where the edge is outgoing Node *out = NULL; for (unsigned q = 0; q < copy->size(); q++) { if ((*copy)[q]->id == node->incoming[j].first) { out = (*copy)[q]; } } COLA_ASSERT(out != NULL); #ifdef RUN_DEBUG cout << "Searching through OUTGOING list for vertex(" << out->id << ")" << endl; #endif Edges::iterator oi; for (oi = out->outgoing.begin(); oi != out->outgoing.end(); oi++) { cola::Edge e = *oi; #ifdef RUN_DEBUG cout << "Looking at Edge(" << e.first << ", " << e.second << ")" << endl; #endif if (e == node->incoming[j]) { break; } } #ifdef RUN_DEBUG cout << "Erasing Edge(" << (*oi).first << ", " << (*oi).second << ") from OUTGOING list of vertex(" << out->id << ")" << endl; #endif out->outgoing.erase(oi); } // say that we want to remove this vertex from the graph. toRemove.push(ni); } } // remove all necessary vertices while (!toRemove.empty()) { copy->erase(toRemove.top()); toRemove.pop(); } COLA_ASSERT(toRemove.empty()); #ifdef EA_DEBUG cout << "EA: "; for (unsigned i = 0; i < Ea->size(); i++) { cout << "(" << (*Ea)[i].first << ", " << (*Ea)[i].second << ") "; } cout << endl; #endif #ifdef RUN_DEBUG cout << "COPY OF MATRIX (after SINKS removed): " << endl; printNodes(copy); #endif // do we have any isolated vertices for (NodeList::iterator ni = copy->begin(); ni != copy->end(); ni++) { // is is an isolated vertice if there are no incoming or outgoing edges node = *ni; if (node->incoming.empty() && node->outgoing.empty()) { #ifdef RUN_DEBUG cout << "vertex(" << node->id << ") is ISOLATED" << endl; #endif // say that we want to remove this vertex from the graph. toRemove.push(ni); } } // remove all necessary vertices while (!toRemove.empty()) { copy->erase(toRemove.top()); toRemove.pop(); } COLA_ASSERT(toRemove.empty()); #ifdef EA_DEBUG cout << "EA: "; for (unsigned i = 0; i < Ea->size(); i++) { cout << "(" << (*Ea)[i].first << ", " << (*Ea)[i].second << ") "; } cout << endl; #endif #ifdef RUN_DEBUG cout << "COPY OF MATRIX (after isolated vertices removed): " << endl; printNodes(copy); #endif // do we have any sources for (NodeList::iterator ni = copy->begin(); ni != copy->end(); ni++) { // is is a sink if there are no incoming edges node = *ni; if (node->incoming.empty()) { #ifdef RUN_DEBUG cout << "vertex(" << node->id << ") is a SOURCE" << endl; #endif // append it's outgoing edges to Ea for (unsigned j = 0; j < node->outgoing.size(); j++) { #ifdef RUN_DEBUG cout << "Appending to Ea: Edge(" << node->outgoing[j].first << ", " << node->outgoing[j].second << ")" << endl; #endif Ea->push_back(node->outgoing[j]); // find the edge from a vertex where the edge is incoming Node *in = NULL; for (unsigned q = 0; q < copy->size(); q++) { if ((*copy)[q]->id == node->outgoing[j].second) { in = (*copy)[q]; } } COLA_ASSERT(in != NULL); #ifdef RUN_DEBUG cout << "Searching through INCOMING list for vertex(" << in->id << ")" << endl; #endif Edges::iterator ii; for (ii = in->incoming.begin(); ii != in->incoming.end(); ii++) { cola::Edge e = *ii; #ifdef RUN_DEBUG cout << "Looking at Edge(" << e.first << ", " << e.second << ")" << endl; #endif if (e == node->outgoing[j]) { break; } } #ifdef RUN_DEBUG cout << "Erasing Edge(" << (*ii).first << ", " << (*ii).second << ") from INCOMING list of vertex(" << in->id << ")" << endl; #endif in->incoming.erase(ii); } // say that we want to remove this vertex from the graph. toRemove.push(ni); } } // remove all necessary vertices while (!toRemove.empty()) { copy->erase(toRemove.top()); toRemove.pop(); } COLA_ASSERT(toRemove.empty()); #ifdef EA_DEBUG cout << "EA: "; for (unsigned i = 0; i < Ea->size(); i++) { cout << "(" << (*Ea)[i].first << ", " << (*Ea)[i].second << ") "; } cout << endl; #endif #ifdef RUN_DEBUG cout << "COPY OF MATRIX (after SOURCES removed): " << endl; printNodes(copy); #endif // if the graph is not empty if (!copy->empty()) { // find the vertex with the highest degree of "source" int degree = -1000; NodeList::iterator theNode; for (NodeList::iterator ni = copy->begin(); ni != copy->end(); ni++) { node = *ni; int t = node->outgoing.size() - node->incoming.size(); if (t > degree) { #ifdef RUN_DEBUG cout << "Sourceiest node: " << node->id << "(d:" << degree << ", t:" << t << ")" << endl; #endif degree = t; theNode = ni; } } // add this node's outgoing edges to Ea node = *theNode; for (unsigned j = 0; j < node->outgoing.size(); j++) { #ifdef RUN_DEBUG cout << "Appending to Ea: Edge(" << node->outgoing[j].first << ", " << node->outgoing[j].second << ")" << endl; #endif Ea->push_back(node->outgoing[j]); // find the edge from a vertex where the edge is incoming Node *in = NULL; for (unsigned q = 0; q < copy->size(); q++) { if ((*copy)[q]->id == node->outgoing[j].second) { in = (*copy)[q]; } } COLA_ASSERT(in != NULL); #ifdef RUN_DEBUG cout << "Searching through INCOMING list for vertex(" << in->id << ")" << endl; #endif Edges::iterator ii; for (ii = in->incoming.begin(); ii != in->incoming.end(); ii++) { cola::Edge e = *ii; #ifdef RUN_DEBUG cout << "Looking at Edge(" << e.first << ", " << e.second << ")" << endl; #endif if (e == node->outgoing[j]) { break; } } #ifdef RUN_DEBUG cout << "Erasing Edge(" << (*ii).first << ", " << (*ii).second << ") from INCOMING list of vertex(" << in->id << ")" << endl; #endif in->incoming.erase(ii); } // for all of the incoming edges this node possesses, delete then from other node's outgoing edge list for (unsigned j = 0; j < node->incoming.size(); j++) { // find the edge from a vertex where the edge is outgoing Node *out = NULL; for (unsigned q = 0; q < copy->size(); q++) { if ((*copy)[q]->id == node->incoming[j].first) { out = (*copy)[q]; } } COLA_ASSERT(out != NULL); #ifdef RUN_DEBUG cout << "Searching through OUTGOING list for vertex(" << out->id << ")" << endl; #endif Edges::iterator oi; for (oi = out->outgoing.begin(); oi != out->outgoing.end(); oi++) { cola::Edge e = *oi; #ifdef RUN_DEBUG cout << "Looking at Edge(" << e.first << ", " << e.second << ")" << endl; #endif if (e == node->incoming[j]) { break; } } #ifdef RUN_DEBUG cout << "Erasing Edge(" << (*oi).first << ", " << (*oi).second << ") from OUTGOING list of vertex(" << out->id << ")" << endl; #endif out->outgoing.erase(oi); } // delete this vertex copy->erase(theNode); } #ifdef EA_DEBUG cout << "EA: "; for (unsigned i = 0; i < Ea->size(); i++) { cout << "(" << (*Ea)[i].first << ", " << (*Ea)[i].second << ") "; } cout << endl; #endif #ifdef RUN_DEBUG cout << "COPY OF MATRIX (after SOURCIEST node removed): " << endl; printNodes(copy); #endif } // delete the copy if (copy != NULL) { for (unsigned i = 0; i < copy->size(); i++) { if ((*copy)[i] != NULL) { delete (*copy)[i]; } } delete copy; } #ifdef EA_DEBUG cout << "Returning EA: "; for (unsigned i = 0; i < Ea->size(); i++) { cout << "(" << (*Ea)[i].first << ", " << (*Ea)[i].second << ") "; } cout << endl; #endif return Ea; }