Esempio n. 1
0
/** Calculate shortest path lengths in @a g from the nearest node to @a point.
 * @param[in,out] g Input graph
 * @param[in] point Point to find the nearest node to.
 * @post Graph has modified node values indicating the minimum path length
 *           to the nearest node to @a point
 * @post Graph nodes that are unreachable to the nearest node to @a point have
 *           the value() -1.
 * @return The maximum path length found.
 *
 * Finds the nearest node to @a point and treats that as the root node for a
 * breadth first search.
 * This sets node's value() to the length of the shortest path to
 * the root node. The root's value() is 0. Nodes unreachable from
 * the root have value() -1.
 */
int shortest_path_lengths(Graph<int>& g, const Point& point) {
  // TYPE DEFINIATIONS
  typedef Graph<int> GraphType;
  typedef GraphType::node_type Node;
  typedef std::pair <Node,int> Pair;

  // apply find closest node
  auto root = std::min_element(g.node_begin(), g.node_end(), MyComparator(point));

  // initiate queue for BFS
  std::queue<Pair> bfs;

  // initialize default distance from point and push node and distance value in queue
  int distance = 1;
  bfs.push(Pair(*root, distance));

  // initialize pair variables for the queue
  Pair node_distance;
  Pair next;

  // Dequeue and add adjacent nodes not yet searched to the queue while updating distance
  while(!bfs.empty()){
    node_distance = bfs.front();
    for (auto it = node_distance.first.edge_begin(); it != node_distance.first.edge_end(); ++it){
      if ((*it).node1() != node_distance.first)
        next.first = (*it).node1();
      else
        next.first = (*it).node2();

      if (next.first.value() == 0){
        distance = node_distance.second;
        next.first.value() = distance;
        next.second = ++distance;
        bfs.push(next);
      }
    }
    bfs.pop();
  }

  // change the value of nodes not found to -1 and update root node value to 0
  for (auto it = g.node_begin(); it != g.node_end(); ++it){
    if ((*it).value() == 0)
      (*it).value() = -1;
  }
  (*root).value() = 0;

  return distance;
}
/** Calculate shortest path lengths in @a g from the nearest node to @a point.
 * @param[in,out] g Input graph
 * @param[in] point Point to find the nearest node to.
 * @post Graph has modified node values indicating the minimum path length
 *           to the nearest node to @a point
 * @post Graph nodes that are unreachable to the nearest node to @a point have
 *           the value() -1.
 * @return The maximum path length found.
 *
 * Finds the nearest node to @a point and treats that as the root node for a
 * breadth first search.
 * This sets node's value() to the length of the shortest path to
 * the root node. The root's value() is 0. Nodes unreachable from
 * the root have value() -1.
 */
int shortest_path_lengths(Graph<int, int>& g, const Point& point) {
  MyComparator mc = MyComparator(point);

  // Find the closest node to the given Point as root.
  Graph<int, int>::node_iterator nifirst = g.node_begin();
  Graph<int, int>::node_iterator nilast = g.node_end();
  Graph<int, int>::node_iterator niroot = std::min_element(nifirst, nilast, mc);
  Graph<int, int>::node_type root = *niroot;

  // Set all the nodes' default values to -1 and the root's value to 0.
  for(; nifirst != nilast; ++nifirst){
    (*nifirst).value() = -1;
  }
  root.value() = 0;

  // Set the current longest distance from root.
  int max = 0;

  /** The queue is to store the nodes needed to be evaluated.
   *  For each node n in the queue, we iterate the adjent nodes and set their values,
   *  push them into the queue and then pop n. In this process, update max.
   */
  std::queue<Graph<int, int>::node_type> waiting;
  waiting.push(root);
  while(!waiting.empty()){
    Graph<int, int>::node_type r = waiting.front();
    int cur = r.value();
    Graph<int, int>::incident_iterator rbegin = r.edge_begin();
    Graph<int, int>::incident_iterator rend = r.edge_end();
    for(; rbegin != rend; ++rbegin){
      if((*rbegin).node2().value() == -1){
        (*rbegin).node2().value() = cur + 1;
        if((*rbegin).node2().value() > max) max = (*rbegin).node2().value();
        waiting.push((*rbegin).node2());
      }
      if((*rbegin).node2().value() > cur + 1){
        (*rbegin).node2().value() = cur + 1;
        if((*rbegin).node2().value() > max) max = (*rbegin).node2().value();
      }
    }
    waiting.pop();
  }
  return max;
}