/** 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; }