Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
	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;
}