void write_graphviz( std::string const& filename, std::vector<int> const& model, Karrot::Database const& database) { std::ofstream dot_file(filename); dot_file << "digraph G {\n"; for (std::size_t i = 0; i < model.size(); ++i) { auto& entry = database[model[i]]; dot_file << " " << i << " [" << "label=\"" << entry.name << ' ' << entry.version << "\", " << "URL=\"" << entry.id << "\"" << "];" << std::endl; ; for (std::size_t k = 0; k < model.size(); ++k) { for (auto& spec : database[model[k]].depends) { if (satisfies(entry, spec)) { dot_file << " " << k << " -> " << i << ";\n"; } } } } dot_file << "}\n"; }
int main(int, char *[]) { typedef adjacency_list < listS, vecS, directedS, no_property, property < edge_weight_t, int > > graph_t; typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor; typedef std::pair<int, int> Edge; const int num_nodes = 5; enum nodes { A, B, C, D, E }; char name[] = "ABCDE"; Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E), Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) }; int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 }; int num_arcs = sizeof(edge_array) / sizeof(Edge); graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes); property_map<graph_t, edge_weight_t>::type weightmap = get(edge_weight, g); std::vector<vertex_descriptor> p(num_vertices(g)); std::vector<int> d(num_vertices(g)); vertex_descriptor s = vertex(A, g); dijkstra_shortest_paths(g, s, predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, g))). distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, g)))); std::cout << "distances and parents:" << std::endl; graph_traits < graph_t >::vertex_iterator vi, vend; for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) { std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", "; std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std:: endl; } std::cout << std::endl; std::ofstream dot_file("results/dijkstra-eg.dot"); dot_file << "digraph D {\n" << " rankdir=LR\n" << " size=\"4,3\"\n" << " ratio=\"fill\"\n" << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n"; graph_traits < graph_t >::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { graph_traits < graph_t >::edge_descriptor e = *ei; graph_traits < graph_t >::vertex_descriptor u = source(e, g), v = target(e, g); dot_file << name[u] << " -> " << name[v] << "[label=\"" << get(weightmap, e) << "\""; if (p[v] == u) dot_file << ", color=\"black\""; else dot_file << ", color=\"grey\""; dot_file << "]"; } dot_file << "}"; system("pause"); return EXIT_SUCCESS; }
//walks the symbol table searching for classes and creating thier dependency graph void TypeChecker::checkDependency(){ Scope* scope = this->symbolsParser->getRootScope(); searchScope(scope); dg->checkDependency(); // creates the graph and checks it for circular dependency dg->reportCircles(); dg->printGraph(); std::ofstream dot_file("dependency_graph.dot"); dg->generate_dot_file(dot_file); dot_file.close(); }
void BuildNJTree::print(std::string filename) { std::ofstream dot_file(filename.c_str()); dot_file << "digraph D {\n" << " ratio=\"fill\"\n" << " size=\"3,3\"\n" << " edge[arrowhead=\"vee\"]\n" << " node[shape=\"circle\"]\n"; EdgeIterator ei, ei_end; for (tie(ei, ei_end) = edges(graph); ei != ei_end; ++ei) { dot_file << get(name, source(*ei, graph)) << " -> " << get(name, target(*ei, graph)) << "; \n"; } dot_file << "}"; }
int main() { /* #Graph The following class hierarchy exists: BidirectionalGraph -------- Incience ---------+ | Adjacency --------+ | VertexAndEdgeList ----+---- VertexList -------+---- Graph | | +---- EdgeList ---------+ | AdjacenyMatrix ---+ */ { /* #properties Properties are values associated to edges and vertices. */ { /* There are a few predefined properties which you should use whenever possible as they are already used in many algorithms, but you can also define your own properties. Predefined properties include: - `edge_weight_t`. Used for most algorithms that have a single value associated to each edge such as Dijikstra. - `vertex_name_t` */ { typedef boost::property<boost::vertex_name_t, std::string> VertexProperties; typedef boost::property<boost::edge_weight_t, int> EdgeProperties; } /* Multiple properties can be specified either by: - using a custom class as the property type. TODO is there any limitation to this? - chaining multile properties */ { } /* The absense of a property is speficied by boost::no_property. */ { typedef boost::no_property VertexProperties; } } typedef boost::property<boost::vertex_name_t, std::string> VertexProperties; typedef boost::property<boost::edge_weight_t, int> EdgeProperties; typedef boost::adjacency_list< // Data structure to represent the out edges for each vertex. // Possibilities: // // #vecS selects std::vector. // #listS selects std::list. // #slistS selects std::slist. // #setS selects std::set. // #multisetS selects std::multiset. // #hash_setS selects std::hash_set. // // `S` standas for Selector. boost::vecS, // Data structure to represent the vertex set. boost::vecS, // Directed type. // #bidirectionalS: directed graph with access to in and out edges // #directedS: directed graph with access only to out-edges // #undirectedS: undirected graph boost::bidirectionalS, // Optional. VertexProperties, // Optional. EdgeProperties > Graph; //typedef boost::graph_traits<Graph>::vertex_iterator VertexIter; //typedef boost::graph_traits<Graph>::vertex_descriptor Vertex; //typedef boost::property_map<Graph, boost::vertex_index_t>::type IndexMap; // Fix number of vertices, and add one edge at a time. int num_vertices = 3; Graph g(num_vertices); boost::add_edge(0, 1, g); boost::add_edge(1, 2, g); // Fix number of vertices, and add one edge array. { int num_vertices = 3; typedef std::pair<int, int> Edge; std::vector<Edge> edges{ {0, 1}, {1, 2}, }; Graph g(edges.data(), edges.data() + edges.size(), num_vertices); } // It is also possible to add vertices with #add_vertex. //#vertices { // Number of vertices. boost::graph_traits<Graph>::vertices_size_type num_vertices = boost::num_vertices(g); assert(num_vertices == 3u); //#vertices() Returns a begin() end() vertex iterator pair so we know where to stop. { typedef std::vector<boost::graph_traits<Graph>::vertex_descriptor> Vertices; Vertices vertices; vertices.reserve(num_vertices); //IndexMap auto index = boost::get(boost::vertex_index, g); //std::pair<vertex_iter, vertex_iter> vp for (auto vp = boost::vertices(g); vp.first != vp.second; ++vp.first) { // Vertex auto v = *vp.first; vertices.push_back(index[v]); } assert((vertices == Vertices{0, 1, 2})); } // The iterator is a ranom access iterator. { auto index = boost::get(boost::vertex_index, g); auto it = boost::vertices(g).first; assert(index[it[2]] == 2); assert(index[it[1]] == 1); } } //#edges { // It seems that only AdjencyMatrix has a method to get an edge given two vertices: //edge(u, v, g) } } //#source is also a global function: <http://stackoverflow.com/questions/16114616/why-is-boost-graph-librarys-source-a-global-function> //#dijikstra std::cout << "#dijkstra" << std::endl; { typedef boost::adjacency_list< boost::listS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, int> > Graph; typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; typedef boost::graph_traits<Graph>::edge_descriptor edge_descriptor; typedef std::pair<int, int> Edge; // Model inputs. const int num_nodes = 5; const int sorce = 0; std::vector<Edge> edges{ {0, 2}, {1, 1}, {1, 3}, {1, 4}, {2, 1}, {2, 3}, {3, 4}, {4, 0}, {4, 1} }; std::vector<int> weights{ 1, 2, 1, 2, 7, 3, 1, 1, 1 }; // Solve. Graph g(edges.data(), edges.data() + edges.size(), weights.data(), num_nodes); std::vector<vertex_descriptor> p(num_vertices(g)); std::vector<int> d(num_vertices(g)); vertex_descriptor s = vertex(sorce, g); dijkstra_shortest_paths(g, s, predecessor_map(boost::make_iterator_property_map( p.begin(), boost::get(boost::vertex_index, g) )).distance_map(boost::make_iterator_property_map( d.begin(), boost::get(boost::vertex_index, g) )) ); // Print solution to stdout. std::cout << "node | distance from source | parent" << std::endl; boost::graph_traits<Graph>::vertex_iterator vi, vend; for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) std::cout << *vi << " " << d[*vi] << " " << p[*vi] << std::endl; std::cout <<std::endl; // Generate a .dot graph file with shortest path highlighted. // To PNG with: dot -Tpng -o outfile.png input.dot boost::property_map<Graph, boost::edge_weight_t>::type weightmap = boost::get(boost::edge_weight, g); std::ofstream dot_file("dijkstra.dot"); dot_file << "digraph D {\n" << " rankdir=LR\n" << " size=\"4,3\"\n" << " ratio=\"fill\"\n" << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n"; boost::graph_traits <Graph>::edge_iterator ei, ei_end; for (std::tie(ei, ei_end) = boost::edges(g); ei != ei_end; ++ei) { edge_descriptor e = *ei; boost::graph_traits<Graph>::vertex_descriptor u = boost::source(e, g), v = boost::target(e, g); dot_file << u << " -> " << v << "[label=\"" << boost::get(weightmap, e) << "\""; if (p[v] == u) dot_file << ", color=\"black\""; else dot_file << ", color=\"grey\""; dot_file << "]"; } dot_file << "}"; // Construct forward path to a destination. int dest = 4; int cur = dest; std::vector<int> path; path.push_back(cur); while(cur != sorce) { cur = p[cur]; path.push_back(cur); } std::reverse(path.begin(), path.end()); // Print. std::cout << "Path to node " << std::to_string(dest) << ":" << std::endl; for(auto& node : path) { std::cout << node << std::endl; } } }