void BasicBlock::deepDump(const Procedure& proc, PrintStream& out) const { out.print("BB", *this, ": ; frequency = ", m_frequency, "\n"); if (predecessors().size()) out.print(" Predecessors: ", pointerListDump(predecessors()), "\n"); for (Value* value : *this) out.print(" ", B3::deepDump(proc, value), "\n"); }
// This is the marker algorithm from "Simple and Efficient Construction of // Static Single Assignment Form" // The simple, non-marker algorithm places phi nodes at any join // Here, we place markers, and only place phi nodes if they end up necessary. // They are only necessary if they break a cycle (IE we recursively visit // ourselves again), or we discover, while getting the value of the operands, // that there are two or more definitions needing to be merged. // This still will leave non-minimal form in the case of irreducible control // flow, where phi nodes may be in cycles with themselves, but unnecessary. MemoryAccess *MemorySSAUpdater::getPreviousDefRecursive(BasicBlock *BB) { // Single predecessor case, just recurse, we can only have one definition. if (BasicBlock *Pred = BB->getSinglePredecessor()) { return getPreviousDefFromEnd(Pred); } else if (VisitedBlocks.count(BB)) { // We hit our node again, meaning we had a cycle, we must insert a phi // node to break it so we have an operand. The only case this will // insert useless phis is if we have irreducible control flow. return MSSA->createMemoryPhi(BB); } else if (VisitedBlocks.insert(BB).second) { // Mark us visited so we can detect a cycle SmallVector<MemoryAccess *, 8> PhiOps; // Recurse to get the values in our predecessors for placement of a // potential phi node. This will insert phi nodes if we cycle in order to // break the cycle and have an operand. for (auto *Pred : predecessors(BB)) PhiOps.push_back(getPreviousDefFromEnd(Pred)); // Now try to simplify the ops to avoid placing a phi. // This may return null if we never created a phi yet, that's okay MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MSSA->getMemoryAccess(BB)); bool PHIExistsButNeedsUpdate = false; // See if the existing phi operands match what we need. // Unlike normal SSA, we only allow one phi node per block, so we can't just // create a new one. if (Phi && Phi->getNumOperands() != 0) if (!std::equal(Phi->op_begin(), Phi->op_end(), PhiOps.begin())) { PHIExistsButNeedsUpdate = true; } // See if we can avoid the phi by simplifying it. auto *Result = tryRemoveTrivialPhi(Phi, PhiOps); // If we couldn't simplify, we may have to create a phi if (Result == Phi) { if (!Phi) Phi = MSSA->createMemoryPhi(BB); // These will have been filled in by the recursive read we did above. if (PHIExistsButNeedsUpdate) { std::copy(PhiOps.begin(), PhiOps.end(), Phi->op_begin()); std::copy(pred_begin(BB), pred_end(BB), Phi->block_begin()); } else { unsigned i = 0; for (auto *Pred : predecessors(BB)) Phi->addIncoming(PhiOps[i++], Pred); } Result = Phi; } if (MemoryPhi *MP = dyn_cast<MemoryPhi>(Result)) InsertedPHIs.push_back(MP); // Set ourselves up for the next variable by resetting visited state. VisitedBlocks.erase(BB); return Result; } llvm_unreachable("Should have hit one of the three cases above"); }
bool Search(U_INT src, U_INT trg, T& PathRes, U_INT& Cost) { typedef boost::graph_traits<GraphT>::vertex_descriptor vertex_descriptor; std::vector<vertex_descriptor> predecessors(num_vertices(hGraph)); if (src>=num_vertices(hGraph) || trg>=num_vertices(hGraph)) return false; vertex_descriptor source_vertex = vertex(src, hGraph); vertex_descriptor target_vertex = vertex(trg, hGraph); std::vector<U_INT> distances(num_vertices(hGraph)); typedef std::vector<boost::default_color_type> colormap_t; colormap_t colors(num_vertices(hGraph)); try { boost::astar_search( hGraph, source_vertex, distance_heuristic<GraphT>(hGraph, target_vertex), boost::predecessor_map(&predecessors[0]). weight_map(get(( &xEdge::cost ), hGraph)). distance_map(&distances[0]). color_map(&colors[0]). visitor(astar_goal_visitor<vertex_descriptor>(target_vertex))); } catch (found_goal fg) { Cost=distances[target_vertex]; PathRes.clear(); PathRes.push_front(target_vertex); size_t max=num_vertices(hGraph); while (target_vertex != source_vertex) { if (target_vertex == predecessors[target_vertex]) return false; target_vertex = predecessors[target_vertex]; PathRes.push_front(target_vertex); if (!max--) return false; } return true; } return false; }
void BasicBlock::deepDump(const Procedure& proc, PrintStream& out) const { out.print("BB", *this, ": ; frequency = ", m_frequency, "\n"); if (predecessors().size()) out.print(" Predecessors: ", pointerListDump(predecessors()), "\n"); for (Value* value : *this) out.print(" ", B3::deepDump(proc, value), "\n"); if (!successors().isEmpty()) { out.print(" Successors: "); if (size()) last()->dumpSuccessors(this, out); else out.print(listDump(successors())); out.print("\n"); } }
result_distances bellman_ford_shortest_paths(v_index s) { v_index N = num_verts(); std::vector<double> distance(N, (std::numeric_limits<double>::max)()); std::vector<vertex_descriptor> predecessors(N); result_distances to_return; typename boost::property_map<adjacency_list, boost::edge_weight_t>::type weight = get(boost::edge_weight, (*graph)); for (v_index i = 0; i < N; ++i) predecessors[i] = (*vertices)[i]; distance[s] = 0; bool r = boost::bellman_ford_shortest_paths (*graph, N, boost::weight_map(weight).distance_map(boost::make_iterator_property_map(distance.begin(), index)).predecessor_map(boost::make_iterator_property_map(predecessors.begin(), index))); if (!r) { return to_return; } to_return.distances = distance; for (int i = 0; i < N; i++) { to_return.predecessors.push_back(index[predecessors[i]]); } return to_return; }
/* Assuming the file exists and is an acyclic graph, print the vertices in a topological order * Use the algorithm that finds no-predecessor vertices and deletes their successor edges. * ALERT: modifies the graph by deleting edges. * * Solves topocycleExercise.c */ void toposort2(GraphInfo gi) { Graph g = gi->graph; int numV = numVerts(g); short done[numV]; // 1 if vertex already printed, otherwise 0 for (int i = 0; i < numV; i++) done[i] = 0; for (int numPrinted = 0; numPrinted < numV; numPrinted++) { /* set noPred to a vertex with no predecessors and not already done */ int noPred; int* ps; // predecessor list for (int v = 0; v < numV; v++) { if (!done[v]) { ps = predecessors(g, v); if (ps[0] == -1 ) { // list is empty? noPred = v; break; } } } /* print noPred and mark as done */ printf("%s ", gi->vertnames[noPred]); done[noPred] = 1; /* get successors of noPred and delete them */ int* snoPred = successors(gi->graph, noPred); for (int i = 0; snoPred[i] != -1; i++) delEdge(gi->graph, noPred, snoPred[i]); } /* cleanup */ printf("\n"); }
// Computes the immediate dominator of the current block. Assumes that all of // its predecessors have already computed their dominators. This is achieved // by visiting the nodes in topological order. void BasicBlock::computeDominator() { BasicBlock *Candidate = nullptr; // Walk backwards from each predecessor to find the common dominator node. for (auto &Pred : predecessors()) { // Skip back-edges if (Pred->BlockID >= BlockID) continue; // If we don't yet have a candidate for dominator yet, take this one. if (Candidate == nullptr) { Candidate = Pred.get(); continue; } // Walk the alternate and current candidate back to find a common ancestor. auto *Alternate = Pred.get(); while (Alternate != Candidate) { if (!Alternate || !Candidate) { // TODO: warn on invalid CFG. Candidate = nullptr; break; } if (Candidate->BlockID > Alternate->BlockID) Candidate = Candidate->DominatorNode.Parent; else Alternate = Alternate->DominatorNode.Parent; } } DominatorNode.Parent = Candidate; DominatorNode.SizeOfSubTree = 1; }
// This function works only on undirected graphs with no parallel edge. std::vector<v_index> prim_min_spanning_tree() { std::vector<v_index> to_return; std::vector<vertex_descriptor> predecessors(num_verts()); prim_minimum_spanning_tree(*graph, boost::make_iterator_property_map(predecessors.begin(), index)); for (unsigned int i = 0; i < predecessors.size(); i++) { if (index[predecessors[i]] != i) { to_return.push_back(i); to_return.push_back(index[predecessors[i]]); } } return to_return; }
std::vector<std::size_t> GetData(Elephants &elephants) { auto indices = ElephantsIndices(elephants); std::sort(elephants.begin(), elephants.end(), [](const Elephant &a, const Elephant &b) -> bool { /*if (a.weight == b.weight) { return a.iq < b.iq; }*/ return a.weight < b.weight; }); auto len = elephants.size(); std::vector<std::size_t> lis; lis.reserve(len); std::vector<std::size_t> m; m.reserve(len + 1); m.emplace_back(0); std::vector<std::size_t> predecessors(len); for (std::size_t i = 0; i < len; ++i) { auto find_it = std::lower_bound(m.begin() + 1, m.end(), elephants[i], [&elephants](const std::size_t &i_m, const Elephant &elephant) -> bool { return elephants[i_m - 1].weight < elephant.weight; }); auto i_m = std::distance(m.begin(), find_it); if (find_it == m.end()) { m.emplace_back(i + 1); } else { *find_it = i + 1; } predecessors[i] = m[i_m - 1]; } for (auto i = m[m.size() - 1]; i > 0; i = predecessors[i - 1]) { std::cout << elephants[i - 1].Hash() << "\t" << indices[elephants[i - 1].Hash()] + 1 << std::endl; lis.emplace_back(indices[elephants[i - 1].Hash()] + 1); } std::reverse(lis.begin(), lis.end()); return lis; }
result_distances dijkstra_shortest_paths(v_index s) { v_index N = num_verts(); result_distances to_return; std::vector<double> distances(N, (std::numeric_limits<double>::max)()); std::vector<vertex_descriptor> predecessors(N); try { boost::dijkstra_shortest_paths(*graph, (*vertices)[s], distance_map(boost::make_iterator_property_map(distances.begin(), index)) .predecessor_map(boost::make_iterator_property_map(predecessors.begin(), index))); } catch (boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::negative_edge> > e) { return to_return; } to_return.distances = distances; for (int i = 0; i < N; i++) { to_return.predecessors.push_back(index[predecessors[i]]); } return to_return; }
// Sorts blocks in post-topological order, by following predecessors. // Each block will be written into the Blocks array in order, and PostBlockID // will be set to the index in the array. Sorting should start from the exit // block, and ID should be the total number of blocks. int BasicBlock::postTopologicalSort(BasicBlock** Blocks, int ID) { if (PostBlockID != InvalidBlockID) return ID; PostBlockID = 0; // mark as being visited // First sort the dominator, if it exists. // This gives us a topological order where post-dominators always come last. if (DominatorNode.Parent) ID = DominatorNode.Parent->postTopologicalSort(Blocks, ID); for (auto &B : predecessors()) { if (B.get()) ID = B->postTopologicalSort(Blocks, ID); } // set ID and update block array in place. // We may lose pointers to unreachable blocks. assert(ID > 0); PostBlockID = --ID; Blocks[PostBlockID] = this; return ID; }
int main(int, char *[]) { typedef float Weight; typedef boost::property<boost::edge_weight_t, Weight> WeightProperty; typedef boost::property<boost::vertex_name_t, std::string> NameProperty; typedef boost::adjacency_list < boost::listS, boost::vecS, boost::directedS, NameProperty, WeightProperty > Graph; typedef boost::graph_traits < Graph >::vertex_descriptor Vertex; typedef boost::property_map < Graph, boost::vertex_index_t >::type IndexMap; typedef boost::property_map < Graph, boost::vertex_name_t >::type NameMap; typedef boost::iterator_property_map < Vertex*, IndexMap, Vertex, Vertex& > PredecessorMap; typedef boost::iterator_property_map < Weight*, IndexMap, Weight, Weight& > DistanceMap; // Create a graph Graph g; // Add named vertices Vertex v0 = add_vertex(std::string("v0"), g); Vertex v1 = add_vertex(std::string("v1"), g); Vertex v2 = add_vertex(std::string("v2"), g); Vertex v3 = add_vertex(std::string("v3"), g); // Add weighted edges Weight weight0 = 5; Weight weight1 = 3; Weight weight2 = 2; Weight weight3 = 4; add_edge(v0, v1, weight0, g); add_edge(v1, v3, weight1, g); add_edge(v0, v2, weight2, g); add_edge(v2, v3, weight3, g); // At this point the graph is /* v0 . / \ 2 / \ / . v2 5/ \ / \ 4 / \ v1----------- v3 3 */ // Create things for Dijkstra std::vector<Vertex> predecessors(num_vertices(g)); // To store parents std::vector<Weight> distances(num_vertices(g)); // To store distances /* works ////////////// IndexMap indexMap = get(boost::vertex_index, g); PredecessorMap predecessorMap(&predecessors[0], indexMap); DistanceMap distanceMap(&distances[0], indexMap); // Compute shortest paths from v0 to all vertices, and store the output in predecessors and distances boost::dijkstra_shortest_paths(g, v0, boost::predecessor_map(predecessorMap).distance_map(distanceMap)); ////////////// */ ////////////// IndexMap indexMap = get(boost::vertex_index, g); DistanceMap distanceMap(&distances[0], indexMap); PredecessorMap predecessorMap(&predecessors[0], indexMap); boost::predecessor_map(predecessorMap).distance_map(distanceMap); // Compute shortest paths from v0 to all vertices, and store the output in predecessors and distances boost::dijkstra_shortest_paths(g, v0, boost::predecessor_map(predecessorMap)); ////////////// // Output results std::cout << "distances and parents:" << std::endl; NameMap nameMap = get(boost::vertex_name, g); BGL_FORALL_VERTICES(v, g, Graph) { std::cout << "distance(" << nameMap[v0] << ", " << nameMap[v] << ") = " << distanceMap[v] << ", "; std::cout << "predecessor(" << nameMap[v] << ") = " << nameMap[predecessorMap[v]] << std::endl; }
/** * @brief Search the graph for a minimun path between originVertex and targetVertex. Returns the path * * @param originVertex ... * @param targetVertex ... * @param vertexPath std::vector of Vertex with the path * @return bool */ bool PlannerPRM::searchGraph(const Vertex &originVertex, const Vertex &targetVertex, std::vector<Vertex> &vertexPath) { qDebug() << __FUNCTION__ << "Searching the graph between " << graph[originVertex].pose << "and " << graph[targetVertex].pose; // Create things for Dijkstra std::vector<Vertex> predecessors(boost::num_vertices(graph)); // To store parents std::vector<float> distances(boost::num_vertices(graph)); // To store distances //Create a vertex_index property map, since VertexList is listS typedef std::map<Vertex, size_t>IndexMap; IndexMap indexMap; boost::associative_property_map<IndexMap> propmapIndex(indexMap); //indexing the vertices int i=0; BGL_FORALL_VERTICES(v, graph, Graph) boost::put(propmapIndex, v, i++); auto predecessorMap = boost::make_iterator_property_map(&predecessors[0], propmapIndex); auto distanceMap = boost::make_iterator_property_map(&distances[0], propmapIndex); boost::dijkstra_shortest_paths(graph, originVertex, boost::weight_map(boost::get(&EdgePayload::dist, graph)) .vertex_index_map(propmapIndex) .predecessor_map(predecessorMap) .distance_map(distanceMap)); ////////////////////////// // Extract a shortest path ////////////////////////// PathType path; Vertex v = targetVertex; ////////////////////////// // Start by setting 'u' to the destintaion node's predecessor |||// Keep tracking the path until we get to the source ///////////////////////// for( Vertex u = predecessorMap[v]; u != v; v = u, u = predecessorMap[v]) // Set the current vertex to the current predecessor, and the predecessor to one level up { std::pair<Graph::edge_descriptor, bool> edgePair = boost::edge(u, v, graph); Graph::edge_descriptor edge = edgePair.first; path.push_back( edge ); } qDebug() << __FUNCTION__ << " Path found with length: " << path.size() << "steps and length " << distanceMap[targetVertex]; ; Vertex lastVertex; if(path.size() > 0) { vertexPath.clear(); for(PathType::reverse_iterator pathIterator = path.rbegin(); pathIterator != path.rend(); ++pathIterator) { vertexPath.push_back(boost::source(*pathIterator, graph)); lastVertex = boost::target(*pathIterator, graph); } vertexPath.push_back(lastVertex); return true; } else { qDebug() << "Path no found between nodes"; return false; } }
int main() { Triangulation triangulation; boost::filesystem::path input_pathname = "C:/Carleton/CGAL-4.4/demo/Polyhedron/data/elephant.off"; // create_cubes(triangulation, 2, 2, 1 ); read_off( triangulation, input_pathname.string() ); // read_off(triangulation, "C:/Carleton/Meshes/holmes_off/geometry/octahedron.off"); // read_off(triangulation, "C:/Carleton/CGAL-4.4/demo/Polyhedron/data/cube.off"); // read_off(triangulation, "C:/Carleton/CGAL-4.4/demo/Polyhedron/data/ellipsoid.off"); #if 0 for (auto cell = triangulation.finite_cells_begin(); cell != triangulation.finite_cells_end(); ++cell) { for (int i = 0; i < 4; ++i) { Point p = cell->vertex(i)->point(); assert(-10.0 < p.x() && p.x() < +10.0); assert(-10.0 < p.y() && p.y() < +10.0); assert(-10.0 < p.z() && p.z() < +10.0); } } #endif set_cell_and_vertex_ids(triangulation); set_random_weights(triangulation); propagate_weights(triangulation); std::cout << "Number of finite vertices : " << triangulation.number_of_vertices() << std::endl; std::cout << "Number of finite edges : " << triangulation.number_of_finite_edges() << std::endl; std::cout << "Number of finite facets : " << triangulation.number_of_finite_facets() << std::endl; std::cout << "Number of finite cells : " << triangulation.number_of_finite_cells() << std::endl; std::string filename = input_pathname.filename().stem().string() + "_tet.vtk"; write_vtk( triangulation, filename ); if (triangulation.number_of_finite_cells() < 100) { dump_triangulation(triangulation); } Graph graph; create_steiner_points(graph,triangulation); // the distances are temporary, so we choose an external property for that std::vector<double> distances(num_vertices(graph)); std::vector<GraphNode_descriptor> predecessors(num_vertices(graph)); boost::dijkstra_shortest_paths( graph, *vertices(graph).first, boost::weight_map(get(&GraphEdge::weight, graph)). distance_map(boost::make_iterator_property_map(distances.begin(), get(boost::vertex_index, graph))). predecessor_map(boost::make_iterator_property_map(predecessors.begin(), get(boost::vertex_index, graph))) ); filename = input_pathname.filename().stem().string() + "_wsp.vtk"; write_shortest_path_vtk( graph, predecessors, distances, filename ); // write_graph_dot("graph.dot", graph); std::cout << "This is the end..." << std::endl; return EXIT_SUCCESS; }
void BasicBlock::dumpHeader(PrintStream& out) const { out.print("BB", *this, ": ; frequency = ", m_frequency, "\n"); if (predecessors().size()) out.print(" Predecessors: ", pointerListDump(predecessors()), "\n"); }