indexedGraph(const IterablePairs & pairs) { map_nodeMapIndex.reset( new map_NodeMapIndex(g) ); //A-- Compute the number of node we need std::set<IndexT> setNodes; for (typename IterablePairs::const_iterator iter = pairs.begin(); iter != pairs.end(); ++iter) { setNodes.insert(iter->first); setNodes.insert(iter->second); } //B-- Create a node graph for each element of the set for (std::set<IndexT>::const_iterator iter = setNodes.begin(); iter != setNodes.end(); ++iter) { map_size_t_to_node[*iter] = g.addNode(); (*map_nodeMapIndex) [map_size_t_to_node[*iter]] = *iter; } //C-- Add weighted edges from the pairs object for (typename IterablePairs::const_iterator iter = pairs.begin(); iter != pairs.end(); ++iter) { const IndexT i = iter->first; const IndexT j = iter->second; g.addEdge(map_size_t_to_node[i], map_size_t_to_node[j]); } }
float H(const GraphT& G, index_t v, const Vector2& p_l) { const auto C = G.circumcircle(v); const auto region = G.regionAroundVertex(v, 0); std::clog << "H():\n"; std::clog << "q_ijk = "<< C.center() <<'\n'; return C.eval(Vector2C(p_l)); }
static void addInstructionToGraph(CFLAliasAnalysis &Analysis, Instruction &Inst, SmallVectorImpl<Value *> &ReturnedValues, NodeMapT &Map, GraphT &Graph) { const auto findOrInsertNode = [&Map, &Graph](Value *Val) { auto Pair = Map.insert(std::make_pair(Val, GraphT::Node())); auto &Iter = Pair.first; if (Pair.second) { auto NewNode = Graph.addNode(); Iter->second = NewNode; } return Iter->second; }; // We don't want the edges of most "return" instructions, but we *do* want // to know what can be returned. if (isa<ReturnInst>(&Inst)) ReturnedValues.push_back(&Inst); if (!hasUsefulEdges(&Inst)) return; SmallVector<Edge, 8> Edges; argsToEdges(Analysis, &Inst, Edges); // In the case of an unused alloca (or similar), edges may be empty. Note // that it exists so we can potentially answer NoAlias. if (Edges.empty()) { auto MaybeVal = getTargetValue(&Inst); assert(MaybeVal.hasValue()); auto *Target = *MaybeVal; findOrInsertNode(Target); return; } const auto addEdgeToGraph = [&Graph, &findOrInsertNode](const Edge &E) { auto To = findOrInsertNode(E.To); auto From = findOrInsertNode(E.From); auto FlippedWeight = flipWeight(E.Weight); auto Attrs = E.AdditionalAttrs; Graph.addEdge(From, To, std::make_pair(E.Weight, Attrs), std::make_pair(FlippedWeight, Attrs)); }; SmallVector<ConstantExpr *, 4> ConstantExprs; for (const Edge &E : Edges) { addEdgeToGraph(E); if (auto *Constexpr = dyn_cast<ConstantExpr>(E.To)) ConstantExprs.push_back(Constexpr); if (auto *Constexpr = dyn_cast<ConstantExpr>(E.From)) ConstantExprs.push_back(Constexpr); } for (ConstantExpr *CE : ConstantExprs) { Edges.clear(); constexprToEdges(Analysis, *CE, Edges); std::for_each(Edges.begin(), Edges.end(), addEdgeToGraph); } }
void dijkstra(GraphT& g, string start) { auto iter = g.getVertex(start); if (iter == g.end()) { throw CustomException("Can't find minimum spanning tree from non-existent vertex!"); } dijkstra(g, *iter); }
bool exportToGraphvizFormat_Nodal( const GraphT & g, ostream & os) { os << "graph 1 {" << endl; os << "node [shape=circle]" << endl; //Export node label for(typename GraphT::NodeIt n(g); n!= lemon::INVALID; ++n) { os << " n" << g.id(n) << std::endl; } //-- Export arc (as the graph is bi-directional, export arc only one time) map< std::pair<size_t,size_t>, size_t > map_arcs; for(typename GraphT::ArcIt e(g); e!=lemon::INVALID; ++e) { if( map_arcs.end() == map_arcs.find(std::make_pair(size_t (g.id(g.source(e))), size_t (g.id(g.target(e))))) && map_arcs.end() == map_arcs.find(std::make_pair(size_t (g.id(g.target(e))), size_t (g.id(g.source(e)))))) { map_arcs[std::pair<size_t,size_t>(size_t (g.id(g.source(e))), size_t (g.id(g.target(e)))) ] = 1; } } //os << "edge [style=bold]" << endl; for ( map< std::pair<size_t,size_t>, size_t >::const_iterator iter = map_arcs.begin(); iter != map_arcs.end(); ++iter) { os << " n" << iter->first.first << " -- " << " n" << iter->first.second << endl; } os << "}" << endl; return os.good(); }
ArticulationResult<GraphT> find_articulation_vertices(GraphT& g) { g.initializeSearch(); ArticulationResult<GraphT> result(g); auto pEarly = bind(&ArticulationResult<GraphT>::processEarly, ref(result), _1); auto pLate = bind(&ArticulationResult<GraphT>::processLate, ref(result), _1); auto pEdge = bind(&ArticulationResult<GraphT>::processEdge, ref(result), _1, _2); g.dfs("v1", pEarly, pLate, pEdge); return result; }
bool exportToGraphvizFormat_Image( const GraphT & g, const NodeMap & nodeMap, const EdgeMap & edgeMap, ostream & os, bool bWeightedEdge=false) { os << "graph 1 {" << endl; os << "node [shape=none]" << endl; //Export node label for(typename GraphT::NodeIt n(g); n!=lemon::INVALID; ++n) { os << " n" << g.id(n) << "[ label =" << "< "<< endl <<"<table>"<< endl <<"<tr><td>" << "\"" << nodeMap[n] <<"\"" <<"</td></tr>"<< endl <<"<tr><td><img src=\"" << nodeMap[n] <<"\"/></td></tr>"<< endl <<"</table>"<< endl <<">, cluster=1];"<< endl; //os << " n" << g.id(n) // << " [ " // << " image=\"" << nodeMap[n] << "\" cluster=1]; " << endl; } //Export arc value map< std::pair<size_t,size_t>, size_t > map_arcs; for(typename GraphT::ArcIt e(g); e!=lemon::INVALID; ++e) { if( map_arcs.end() == map_arcs.find(std::make_pair(size_t (g.id(g.source(e))), size_t (g.id(g.target(e))))) && map_arcs.end() == map_arcs.find(std::make_pair(size_t (g.id(g.target(e))), size_t (g.id(g.source(e)))))) { map_arcs[std::pair<size_t,size_t>(size_t (g.id(g.source(e))), size_t (g.id(g.target(e)))) ] = edgeMap[e]; } } os << "edge [style=bold]" << endl; for ( map< std::pair<size_t,size_t>, size_t >::const_iterator iter = map_arcs.begin(); iter != map_arcs.end(); ++iter) { if (bWeightedEdge) { os << " n" << iter->first.first << " -- " << " n" << iter->first.second << " [label=\"" << iter->second << "\"]" << endl; } else { os << " n" << iter->first.first << " -- " << " n" << iter->first.second << endl; } } os << "}" << endl; return os.good(); }
// Aside: We may remove graph construction entirely, because it doesn't really // buy us much that we don't already have. I'd like to add interprocedural // analysis prior to this however, in case that somehow requires the graph // produced by this for efficient execution static void buildGraphFrom(CFLAliasAnalysis &Analysis, Function *Fn, SmallVectorImpl<Value *> &ReturnedValues, NodeMapT &Map, GraphT &Graph) { const auto findOrInsertNode = [&Map, &Graph](Value *Val) { auto Pair = Map.insert(std::make_pair(Val, GraphT::Node())); auto &Iter = Pair.first; if (Pair.second) { auto NewNode = Graph.addNode(); Iter->second = NewNode; } return Iter->second; }; SmallVector<Edge, 8> Edges; for (auto &Bb : Fn->getBasicBlockList()) { for (auto &Inst : Bb.getInstList()) { // We don't want the edges of most "return" instructions, but we *do* want // to know what can be returned. if (auto *Ret = dyn_cast<ReturnInst>(&Inst)) ReturnedValues.push_back(Ret); if (!hasUsefulEdges(&Inst)) continue; Edges.clear(); argsToEdges(Analysis, &Inst, Edges); // In the case of an unused alloca (or similar), edges may be empty. Note // that it exists so we can potentially answer NoAlias. if (Edges.empty()) { auto MaybeVal = getTargetValue(&Inst); assert(MaybeVal.hasValue()); auto *Target = *MaybeVal; findOrInsertNode(Target); continue; } for (const Edge &E : Edges) { auto To = findOrInsertNode(E.To); auto From = findOrInsertNode(E.From); auto FlippedWeight = flipWeight(E.Weight); auto Attrs = E.AdditionalAttrs; Graph.addEdge(From, To, std::make_pair(E.Weight, Attrs), std::make_pair(FlippedWeight, Attrs)); } } } }
void FixupArrivingTurnRestriction(const NodeID node_u, const NodeID node_v, const NodeID node_w, const GraphT &graph) { BOOST_ASSERT(node_u != SPECIAL_NODEID); BOOST_ASSERT(node_v != SPECIAL_NODEID); BOOST_ASSERT(node_w != SPECIAL_NODEID); if (!IsViaNode(node_u)) { return; } // find all potential start edges. It is more efficient to get a (small) list // of potential start edges than iterating over all buckets std::vector<NodeID> predecessors; for (const EdgeID current_edge_id : graph.GetAdjacentEdgeRange(node_u)) { const NodeID target = graph.GetTarget(current_edge_id); if (node_v != target) { predecessors.push_back(target); } } for (const NodeID node_x : predecessors) { const auto restriction_iterator = m_restriction_map.find({node_x, node_u}); if (restriction_iterator == m_restriction_map.end()) { continue; } const unsigned index = restriction_iterator->second; auto &bucket = m_restriction_bucket_list.at(index); for (RestrictionTarget &restriction_target : bucket) { if (node_v == restriction_target.target_node) { restriction_target.target_node = node_w; } } } }
bool List_Triplets(const GraphT & g, std::vector< Triplet > & vec_triplets) { // Algorithm // //-- For each node // - list the outgoing not visited edge // - for each tuple of edge // - if their end are connected // Detected cyle of length 3 // Mark first edge as visited typedef typename GraphT::OutArcIt OutArcIt; typedef typename GraphT::NodeIt NodeIterator; typedef typename GraphT::template EdgeMap<bool> BoolEdgeMap; BoolEdgeMap map_edge(g, false); // Visited edge map // For each nodes for (NodeIterator itNode(g); itNode != INVALID; ++itNode) { // For each edges (list the not visited outgoing edges) std::vector<OutArcIt> vec_edges; for (OutArcIt e(g, itNode); e!=INVALID; ++e) { if (!map_edge[e]) // If not visited vec_edges.push_back(e); } // For all tuples look of ends of edges are linked while(vec_edges.size()>1) { OutArcIt itPrev = vec_edges[0]; // For all tuple (0,Inth) for(size_t i=1; i < vec_edges.size(); ++i) { // Check if the extremity is linked typename GraphT::Arc cycleEdge = findArc(g, g.target(itPrev), g.target(vec_edges[i])); if (cycleEdge!= INVALID && !map_edge[cycleEdge]) { // Elementary cycle found (make value follow a monotonic ascending serie) int triplet[3] = { g.id(itNode), g.id(g.target(itPrev)), g.id(g.target(vec_edges[i]))}; std::sort(&triplet[0], &triplet[3]); vec_triplets.push_back(Triplet(triplet[0],triplet[1],triplet[2])); } } // Mark the current ref edge as visited map_edge[itPrev] = true; // remove head to list remaining tuples vec_edges.erase(vec_edges.begin()); } } return (!vec_triplets.empty()); }
indexedGraph(const IterableNodes & nodes, const IterablePairs & pairs) { map_nodeMapIndex.reset( new map_NodeMapIndex(g) ); //A-- Create a node graph for each element of the set for (typename IterableNodes::const_iterator iter = nodes.begin(); iter != nodes.end(); ++iter) { map_size_t_to_node[*iter] = g.addNode(); (*map_nodeMapIndex) [map_size_t_to_node[*iter]] = *iter; } //B-- Add weighted edges from the pairs object for (typename IterablePairs::const_iterator iter = pairs.begin(); iter != pairs.end(); ++iter) { const IndexT i = iter->first; const IndexT j = iter->second; g.addEdge(map_size_t_to_node[i], map_size_t_to_node[j]); } }
inline void showGraph(const GraphT& G){ //rootFrame.Clear(); rootFrame.Clear(); typename GraphT::VertexType denominator = GraphT::resolutionToDenominator(G.getResolution()); for(auto vertex: G){ // we transform vertex to coordinates of its centre IVector x = GraphT::vertexToVector(vertex.first,denominator); plot(rootFrame, x, RED); // simplified plotting //DVector x = capd::vectalg::midObject<DVector>(GraphT::vertexToVector(vertex.first,denominator)); // rootFrame.dot( x[0], x[1], RED); } }
index_t findNearestCircum(const GraphT& G, index_t site, const Vector2& p) { index_t v = NOTHING; float value = std::numeric_limits<float>::max(); G.forEachVertexAroundRegion( site + 1, //TODO: siteToRegion(site) [&G, &p, &v, &value](index_t v2) { auto value2 = H(G, v2, p); if (value2 < value) v = v2; } ); return v; }
template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT graph) { std::vector<Edge> edges; edges.reserve(graph.GetNumberOfEdges()); util::UnbufferedLog log; log << "Getting edges of minimized graph "; util::Percent p(log, graph.GetNumberOfNodes()); const NodeID number_of_nodes = graph.GetNumberOfNodes(); if (graph.GetNumberOfNodes()) { Edge new_edge; for (const auto node : util::irange(0u, number_of_nodes)) { p.PrintStatus(node); for (auto edge : graph.GetAdjacentEdgeRange(node)) { const NodeID target = graph.GetTarget(edge); const ContractorGraph::EdgeData &data = graph.GetEdgeData(edge); new_edge.source = node; new_edge.target = target; BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid"); new_edge.data.weight = data.weight; new_edge.data.duration = data.duration; new_edge.data.shortcut = data.shortcut; new_edge.data.turn_id = data.id; BOOST_ASSERT_MSG(new_edge.data.turn_id != INT_MAX, // 2^31 "edge id invalid"); new_edge.data.forward = data.forward; new_edge.data.backward = data.backward; edges.push_back(new_edge); } } } // sort and remove duplicates tbb::parallel_sort(edges.begin(), edges.end()); auto new_end = std::unique(edges.begin(), edges.end()); edges.resize(new_end - edges.begin()); edges.shrink_to_fit(); return edges; }
void dijkstra(GraphT& g, typename GraphT::Vertex& start) { using Vertex = typename GraphT::Vertex; g.initializeSearch(); unordered_map<Vertex*, bool> intree; int weight; int dist; Vertex* v = &start; v->distance = 0; while (!intree[v]) { intree[v] = true; for (auto& e : v->edges) { auto w = e.w; weight = e.weight; if (w->distance > weight + v->distance) { w->distance = weight + v->distance; w->parent = v; } } dist = MAX_INT; for (auto& x : g) { if (!intree[&x] && (dist > x.distance)) { dist = x.distance; v = &x; } } } }
static FunctionInfo buildSetsFrom(CFLAliasAnalysis &Analysis, Function *Fn) { NodeMapT Map; GraphT Graph; SmallVector<Value *, 4> ReturnedValues; buildGraphFrom(Analysis, Fn, ReturnedValues, Map, Graph); DenseMap<GraphT::Node, Value *> NodeValueMap; NodeValueMap.resize(Map.size()); for (const auto &Pair : Map) NodeValueMap.insert(std::make_pair(Pair.second, Pair.first)); const auto findValueOrDie = [&NodeValueMap](GraphT::Node Node) { auto ValIter = NodeValueMap.find(Node); assert(ValIter != NodeValueMap.end()); return ValIter->second; }; StratifiedSetsBuilder<Value *> Builder; SmallVector<GraphT::Node, 16> Worklist; for (auto &Pair : Map) { Worklist.clear(); auto *Value = Pair.first; Builder.add(Value); auto InitialNode = Pair.second; Worklist.push_back(InitialNode); while (!Worklist.empty()) { auto Node = Worklist.pop_back_val(); auto *CurValue = findValueOrDie(Node); if (isa<Constant>(CurValue) && !isa<GlobalValue>(CurValue)) continue; for (const auto &EdgeTuple : Graph.edgesFor(Node)) { auto Weight = std::get<0>(EdgeTuple); auto Label = Weight.first; auto &OtherNode = std::get<1>(EdgeTuple); auto *OtherValue = findValueOrDie(OtherNode); if (isa<Constant>(OtherValue) && !isa<GlobalValue>(OtherValue)) continue; bool Added; switch (directionOfEdgeType(Label)) { case Level::Above: Added = Builder.addAbove(CurValue, OtherValue); break; case Level::Below: Added = Builder.addBelow(CurValue, OtherValue); break; case Level::Same: Added = Builder.addWith(CurValue, OtherValue); break; } if (Added) { auto Aliasing = Weight.second; if (auto MaybeCurIndex = valueToAttrIndex(CurValue)) Aliasing.set(*MaybeCurIndex); if (auto MaybeOtherIndex = valueToAttrIndex(OtherValue)) Aliasing.set(*MaybeOtherIndex); Builder.noteAttributes(CurValue, Aliasing); Builder.noteAttributes(OtherValue, Aliasing); Worklist.push_back(OtherNode); } } } } // There are times when we end up with parameters not in our graph (i.e. if // it's only used as the condition of a branch). Other bits of code depend on // things that were present during construction being present in the graph. // So, we add all present arguments here. for (auto &Arg : Fn->args()) { Builder.add(&Arg); } return FunctionInfo(Builder.build(), std::move(ReturnedValues)); }