mirror of
https://github.com/boostorg/graph.git
synced 2026-07-21 13:23:42 +00:00
algorithms mostly ok
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Example: Finding all maximal cliques with Bron-Kerbosch algorithm
|
||||
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/bron_kerbosch_all_cliques.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// Undirected graph with no properties
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
// Custom visitor that prints each maximal clique found.
|
||||
// The clique is passed as a deque of vertex descriptors.
|
||||
struct PrintCliquesVisitor
|
||||
{
|
||||
template <typename Clique, typename G>
|
||||
void clique(const Clique& c, const G& /*g*/)
|
||||
{
|
||||
// Copy to a vector and sort so output is deterministic
|
||||
std::vector<Vertex> sorted(c.begin(), c.end());
|
||||
std::sort(sorted.begin(), sorted.end());
|
||||
|
||||
std::cout << "Clique: {";
|
||||
for (std::size_t i = 0; i < sorted.size(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
std::cout << ", ";
|
||||
}
|
||||
std::cout << sorted[i];
|
||||
}
|
||||
std::cout << "}" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Build an undirected graph with 4 vertices:
|
||||
//
|
||||
// 0 --- 1
|
||||
// | / |
|
||||
// | / |
|
||||
// | / |
|
||||
// 2 --- 3
|
||||
//
|
||||
// Edges: 0-1, 0-2, 1-2, 1-3, 2-3
|
||||
// Triangle {0,1,2} and triangle {1,2,3} are the maximal cliques.
|
||||
|
||||
Graph g{4};
|
||||
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(1, 3, g);
|
||||
boost::add_edge(2, 3, g);
|
||||
|
||||
std::cout << "Finding all maximal cliques:" << std::endl;
|
||||
boost::bron_kerbosch_all_cliques(g, PrintCliquesVisitor{});
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/edge_coloring.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
|
||||
boost::no_property, boost::property<boost::edge_color_t, int>>;
|
||||
Graph g(4);
|
||||
boost::add_edge(0, 1, g); boost::add_edge(0, 2, g);
|
||||
boost::add_edge(0, 3, g); boost::add_edge(1, 2, g);
|
||||
boost::add_edge(2, 3, g);
|
||||
|
||||
auto color_map = get(boost::edge_color, g);
|
||||
auto num_colors = boost::edge_coloring(g, color_map);
|
||||
|
||||
std::cout << "Edge coloring uses " << num_colors << " colors:\n";
|
||||
for (auto ep = edges(g); ep.first != ep.second; ++ep.first) {
|
||||
auto e = *ep.first;
|
||||
std::cout << " " << source(e, g) << "-" << target(e, g)
|
||||
<< " : color " << get(color_map, e) << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/bipartite.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
Graph g(5);
|
||||
// Triangle 0-1-2 makes this non-bipartite
|
||||
boost::add_edge(0, 1, g); boost::add_edge(1, 2, g);
|
||||
boost::add_edge(2, 0, g); boost::add_edge(2, 3, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
|
||||
using Partition = boost::one_bit_color_map<
|
||||
boost::property_map<Graph, boost::vertex_index_t>::type>;
|
||||
Partition partition(num_vertices(g), get(boost::vertex_index, g));
|
||||
|
||||
std::vector<int> cycle;
|
||||
boost::find_odd_cycle(g, get(boost::vertex_index, g), partition,
|
||||
std::back_inserter(cycle));
|
||||
|
||||
if (cycle.empty()) {
|
||||
std::cout << "Graph is bipartite\n";
|
||||
} else {
|
||||
std::cout << "Odd cycle found:";
|
||||
for (auto v : cycle) std::cout << " " << v;
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Bipartite Check example
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/bipartite.hpp>
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
|
||||
int main() {
|
||||
// Bipartite graph: {0,2} and {1,3} with edges only between sets
|
||||
Graph bipartite_g{4};
|
||||
boost::add_edge(0, 1, bipartite_g); boost::add_edge(0, 3, bipartite_g);
|
||||
boost::add_edge(2, 1, bipartite_g); boost::add_edge(2, 3, bipartite_g);
|
||||
|
||||
// Non-bipartite graph: triangle
|
||||
Graph triangle{3};
|
||||
boost::add_edge(0, 1, triangle); boost::add_edge(1, 2, triangle);
|
||||
boost::add_edge(0, 2, triangle);
|
||||
|
||||
std::cout << "4-cycle is bipartite: "
|
||||
<< (boost::is_bipartite(bipartite_g) ? "yes" : "no") << "\n";
|
||||
std::cout << "Triangle is bipartite: "
|
||||
<< (boost::is_bipartite(triangle) ? "yes" : "no") << "\n";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Sequential Vertex Coloring example
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/sequential_vertex_coloring.hpp>
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
boost::add_edge(0, 1, g); boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 2, g); boost::add_edge(1, 3, g);
|
||||
boost::add_edge(2, 4, g); boost::add_edge(3, 4, g);
|
||||
|
||||
std::vector<int> colors(boost::num_vertices(g));
|
||||
auto color_map = boost::make_iterator_property_map(
|
||||
colors.begin(), boost::get(boost::vertex_index, g));
|
||||
int num_colors = boost::sequential_vertex_coloring(g, color_map);
|
||||
|
||||
std::cout << "Colors used: " << num_colors << "\n";
|
||||
for (Vertex v = 0; v < boost::num_vertices(g); ++v) {
|
||||
std::cout << " Vertex " << v << " -> color " << colors[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/biconnected_components.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
no_property, property<edge_index_t, int>>;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, 0, g);
|
||||
add_edge(1, 2, 1, g);
|
||||
add_edge(2, 0, 2, g); // triangle
|
||||
add_edge(2, 3, 3, g);
|
||||
add_edge(3, 4, 4, g);
|
||||
add_edge(4, 2, 5, g); // second triangle
|
||||
|
||||
std::vector<std::size_t> comp(num_edges(g));
|
||||
auto comp_map = make_iterator_property_map(comp.begin(), get(edge_index, g));
|
||||
auto num = biconnected_components(g, comp_map);
|
||||
|
||||
std::cout << "Biconnected components: " << num << "\n";
|
||||
for (auto ei = edges(g).first; ei != edges(g).second; ++ei) {
|
||||
std::cout << " " << source(*ei, g) << "-" << target(*ei, g)
|
||||
<< " component " << get(comp_map, *ei) << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Connected Components example
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/connected_components.hpp>
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
|
||||
int main() {
|
||||
Graph g{7};
|
||||
// Component 0: {0,1,2} Component 1: {3,4} Component 2: {5,6}
|
||||
boost::add_edge(0, 1, g); boost::add_edge(1, 2, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
boost::add_edge(5, 6, g);
|
||||
|
||||
std::vector<int> comp(boost::num_vertices(g));
|
||||
int n = boost::connected_components(g,
|
||||
boost::make_iterator_property_map(comp.begin(), boost::get(boost::vertex_index, g)));
|
||||
|
||||
std::cout << "Number of components: " << n << "\n";
|
||||
for (std::size_t v = 0; v < comp.size(); ++v) {
|
||||
std::cout << " Vertex " << v << " -> component " << comp[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/incremental_components.hpp>
|
||||
#include <boost/pending/disjoint_sets.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
Graph g(5);
|
||||
std::vector<std::size_t> rank(5, 0);
|
||||
std::vector<std::size_t> parent(5);
|
||||
boost::disjoint_sets<std::size_t*, std::size_t*> ds(rank.data(), parent.data());
|
||||
for (std::size_t i = 0; i < 5; ++i) ds.make_set(i);
|
||||
|
||||
auto add_and_report = [&](int u, int v) {
|
||||
boost::add_edge(u, v, g);
|
||||
ds.union_set(static_cast<std::size_t>(u), static_cast<std::size_t>(v));
|
||||
// Count components
|
||||
std::size_t count = 0;
|
||||
for (std::size_t i = 0; i < 5; ++i)
|
||||
if (ds.find_set(i) == i) ++count;
|
||||
std::cout << " After adding " << u << "-" << v << ": " << count << " components\n";
|
||||
};
|
||||
|
||||
std::cout << "Incremental connected components:\n";
|
||||
add_and_report(0, 1);
|
||||
add_and_report(2, 3);
|
||||
add_and_report(1, 2);
|
||||
add_and_report(3, 4);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Strongly Connected Components example
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/strong_components.hpp>
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>;
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
// Cycle: 0->1->2->0, plus 2->3->4
|
||||
boost::add_edge(0, 1, g); boost::add_edge(1, 2, g); boost::add_edge(2, 0, g);
|
||||
boost::add_edge(2, 3, g); boost::add_edge(3, 4, g);
|
||||
|
||||
std::vector<int> comp(boost::num_vertices(g));
|
||||
int n = boost::strong_components(g,
|
||||
boost::make_iterator_property_map(comp.begin(), boost::get(boost::vertex_index, g)));
|
||||
|
||||
std::cout << "Number of strongly connected components: " << n << "\n";
|
||||
for (std::size_t v = 0; v < comp.size(); ++v) {
|
||||
std::cout << " Vertex " << v << " -> component " << comp[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/edge_connectivity.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g); add_edge(0, 2, g);
|
||||
add_edge(1, 2, g); add_edge(1, 3, g); add_edge(2, 3, g);
|
||||
|
||||
std::vector<Edge> cut_edges;
|
||||
auto connectivity = edge_connectivity(g, std::back_inserter(cut_edges));
|
||||
|
||||
std::cout << "Edge connectivity: " << connectivity << "\n";
|
||||
std::cout << "Min cut edges: " << cut_edges.size() << "\n";
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/st_connected.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
int main() {
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g);
|
||||
// vertices 3 and 4 are isolated from 0-1-2
|
||||
|
||||
bool connected_0_2 = graph::st_connected(g, vertex(0, g), vertex(2, g));
|
||||
bool connected_0_3 = graph::st_connected(g, vertex(0, g), vertex(3, g));
|
||||
|
||||
std::cout << "0 connected to 2: " << std::boolalpha << connected_0_2 << "\n";
|
||||
std::cout << "0 connected to 3: " << std::boolalpha << connected_0_3 << "\n";
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/hawick_circuits.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
struct circuit_printer {
|
||||
template <typename Vertices, typename G>
|
||||
void cycle(const Vertices& circuit, const G&) {
|
||||
for (auto v : circuit) { std::cout << v << " "; }
|
||||
std::cout << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g);
|
||||
add_edge(2, 0, g); add_edge(2, 3, g); add_edge(3, 0, g);
|
||||
|
||||
std::cout << "Circuits:\n";
|
||||
circuit_printer visitor;
|
||||
hawick_circuits(g, visitor);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/howard_cycle_ratio.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// howard_cycle_ratio requires property-tag-based weight maps.
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property,
|
||||
property<edge_weight_t, double, property<edge_weight2_t, double>>>;
|
||||
|
||||
int main() {
|
||||
Graph g(3);
|
||||
// Cycle: 0->1->2->0 with weights 3,1,2 and transit times 1,1,1
|
||||
add_edge(0, 1, {3.0, 1.0}, g);
|
||||
add_edge(1, 2, {1.0, 1.0}, g);
|
||||
add_edge(2, 0, {2.0, 1.0}, g);
|
||||
add_edge(0, 2, {10.0, 1.0}, g);
|
||||
|
||||
std::vector<graph_traits<Graph>::edge_descriptor> cycle;
|
||||
double mcr = minimum_cycle_ratio(g,
|
||||
get(vertex_index, g),
|
||||
get(edge_weight, g),
|
||||
get(edge_weight2, g), &cycle);
|
||||
|
||||
std::cout << "Minimum cycle ratio: " << mcr << "\n";
|
||||
std::cout << "Cycle length: " << cycle.size() << " edges\n";
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Example: Finding all elementary cycles with Tiernan's algorithm
|
||||
|
||||
#include <boost/graph/directed_graph.hpp>
|
||||
#include <boost/graph/tiernan_all_cycles.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// Directed graph with no bundled properties
|
||||
using Graph = boost::directed_graph<>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
// Custom visitor that prints each cycle found.
|
||||
// The cycle is passed as a const vector of vertex descriptors.
|
||||
struct PrintCyclesVisitor
|
||||
{
|
||||
template <typename Path, typename G>
|
||||
void cycle(const Path& p, const G& g)
|
||||
{
|
||||
std::cout << "Cycle: ";
|
||||
for (std::size_t i = 0; i < p.size(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
std::cout << " -> ";
|
||||
}
|
||||
std::cout << boost::get(boost::vertex_index, g, p[i]);
|
||||
}
|
||||
std::cout << " -> " << boost::get(boost::vertex_index, g, p.front())
|
||||
<< std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Build a directed graph with 4 vertices and two cycles:
|
||||
//
|
||||
// 0 --> 1 --> 2
|
||||
// ^ ^ |
|
||||
// | | |
|
||||
// +-----+-----+
|
||||
// |
|
||||
// 3
|
||||
//
|
||||
// Edges: 0->1, 1->2, 2->0, 1->3, 3->1
|
||||
// Cycle 1: 0 -> 1 -> 2 -> 0
|
||||
// Cycle 2: 1 -> 3 -> 1
|
||||
|
||||
Graph g;
|
||||
|
||||
Vertex v0 = g.add_vertex();
|
||||
Vertex v1 = g.add_vertex();
|
||||
Vertex v2 = g.add_vertex();
|
||||
Vertex v3 = g.add_vertex();
|
||||
|
||||
g.add_edge(v0, v1);
|
||||
g.add_edge(v1, v2);
|
||||
g.add_edge(v2, v0);
|
||||
g.add_edge(v1, v3);
|
||||
g.add_edge(v3, v1);
|
||||
|
||||
std::cout << "Finding all elementary cycles:" << std::endl;
|
||||
boost::tiernan_all_cycles(g, PrintCyclesVisitor{});
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/isomorphism.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>;
|
||||
Graph g1, g2;
|
||||
// Triangle: 0->1->2->0
|
||||
boost::add_edge(0, 1, g1); boost::add_edge(1, 2, g1); boost::add_edge(2, 0, g1);
|
||||
// Same triangle, relabeled: 2->0->1->2
|
||||
boost::add_edge(2, 0, g2); boost::add_edge(0, 1, g2); boost::add_edge(1, 2, g2);
|
||||
|
||||
bool result = boost::isomorphism(g1, g2);
|
||||
std::cout << "Graphs are " << (result ? "isomorphic" : "not isomorphic") << "\n";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/mcgregor_common_subgraphs.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
using Size = graph_traits<Graph>::vertices_size_type;
|
||||
|
||||
struct max_callback {
|
||||
Size largest = 0;
|
||||
template <typename Map1, typename Map2>
|
||||
bool operator()(Map1, Map2, Size subgraph_size) {
|
||||
if (subgraph_size > largest) largest = subgraph_size;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g1(4);
|
||||
add_edge(0, 1, g1); add_edge(1, 2, g1);
|
||||
add_edge(2, 3, g1); add_edge(3, 0, g1);
|
||||
|
||||
Graph g2(5);
|
||||
add_edge(0, 1, g2); add_edge(1, 2, g2);
|
||||
add_edge(2, 3, g2); add_edge(3, 4, g2); add_edge(4, 0, g2);
|
||||
|
||||
max_callback cb;
|
||||
mcgregor_common_subgraphs(g1, g2, true, std::ref(cb));
|
||||
std::cout << "Largest common subgraph size: " << cb.largest << "\n";
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/vf2_sub_graph_iso.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, bidirectionalS>;
|
||||
|
||||
struct first_only_callback {
|
||||
bool found = false;
|
||||
template <typename Map1, typename Map2>
|
||||
bool operator()(Map1, Map2) { found = true; return false; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
// Small graph: triangle (0-1-2)
|
||||
Graph small(3);
|
||||
add_edge(0, 1, small); add_edge(1, 2, small); add_edge(2, 0, small);
|
||||
// Large graph: square with diagonal (0-1-2-3, plus 0-2)
|
||||
Graph large(4);
|
||||
add_edge(0, 1, large); add_edge(1, 2, large);
|
||||
add_edge(2, 3, large); add_edge(3, 0, large); add_edge(0, 2, large);
|
||||
|
||||
first_only_callback cb;
|
||||
vf2_subgraph_iso(small, large, std::ref(cb));
|
||||
std::cout << "Subgraph isomorphism found: " << std::boolalpha
|
||||
<< cb.found << "\n";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/circle_layout.hpp>
|
||||
#include <boost/graph/topology.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Point = convex_topology<2>::point_type;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
int main() {
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g);
|
||||
add_edge(2, 3, g); add_edge(3, 4, g); add_edge(4, 0, g);
|
||||
|
||||
std::vector<Point> positions(num_vertices(g));
|
||||
auto pos_map = make_iterator_property_map(
|
||||
positions.begin(), get(vertex_index, g));
|
||||
|
||||
circle_graph_layout(g, pos_map, 50.0);
|
||||
|
||||
for (auto v : make_iterator_range(vertices(g)))
|
||||
std::cout << "vertex " << v << ": ("
|
||||
<< positions[v][0] << ", " << positions[v][1] << ")\n";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/fruchterman_reingold.hpp>
|
||||
#include <boost/graph/topology.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Point = rectangle_topology<>::point_type;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS, property<vertex_index_t, int>>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g);
|
||||
add_edge(2, 3, g); add_edge(3, 4, g); add_edge(4, 0, g);
|
||||
|
||||
minstd_rand gen(42);
|
||||
rectangle_topology<> topology(gen, 0.0, 0.0, 100.0, 100.0);
|
||||
|
||||
std::vector<Point> positions(num_vertices(g));
|
||||
for (auto& p : positions) { p = topology.random_point(); }
|
||||
auto pos_map = make_iterator_property_map(positions.begin(), get(vertex_index, g));
|
||||
|
||||
fruchterman_reingold_force_directed_layout(g, pos_map, topology);
|
||||
|
||||
for (auto v : make_iterator_range(vertices(g))) {
|
||||
auto& p = positions[v];
|
||||
std::cout << "vertex " << v << ": (" << p[0] << ", " << p[1] << ")\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/gursoy_atun_layout.hpp>
|
||||
#include <boost/graph/topology.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
using Point = boost::heart_topology<>::point_type;
|
||||
|
||||
int main() {
|
||||
Graph g(5);
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(2, 3, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
boost::add_edge(4, 0, g);
|
||||
|
||||
std::vector<Point> positions(num_vertices(g));
|
||||
auto pos_map = boost::make_iterator_property_map(
|
||||
positions.begin(), get(boost::vertex_index, g));
|
||||
|
||||
boost::heart_topology<> topo;
|
||||
boost::gursoy_atun_layout(g, topo, pos_map);
|
||||
|
||||
for (auto v : boost::make_iterator_range(vertices(g))) {
|
||||
auto& p = positions[v];
|
||||
std::cout << "vertex " << v << ": (" << p[0] << ", " << p[1] << ")\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/kamada_kawai_spring_layout.hpp>
|
||||
#include <boost/graph/circle_layout.hpp>
|
||||
#include <boost/graph/topology.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
no_property, property<edge_weight_t, double>>;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, 1.0, g);
|
||||
add_edge(1, 2, 1.0, g);
|
||||
add_edge(2, 3, 1.0, g);
|
||||
add_edge(3, 4, 1.0, g);
|
||||
add_edge(4, 0, 1.0, g);
|
||||
|
||||
using Topo = rectangle_topology<>;
|
||||
Topo topo(0.0, 0.0, 100.0, 100.0);
|
||||
using Point = Topo::point_type;
|
||||
|
||||
std::vector<Point> pos(num_vertices(g));
|
||||
auto pos_map = make_iterator_property_map(pos.begin(), get(vertex_index, g));
|
||||
|
||||
circle_graph_layout(g, pos_map, 25.0);
|
||||
|
||||
bool ok = kamada_kawai_spring_layout(g, pos_map, get(edge_weight, g),
|
||||
topo, side_length(50.0), layout_tolerance<double>(0.1));
|
||||
|
||||
std::cout << std::fixed << std::setprecision(1);
|
||||
std::cout << "converged: " << (ok ? "yes" : "no") << "\n";
|
||||
for (auto v : make_iterator_range(vertices(g))) {
|
||||
std::cout << "vertex " << v << ": ("
|
||||
<< pos[v][0] << ", " << pos[v][1] << ")\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/random_layout.hpp>
|
||||
#include <boost/graph/topology.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Point = rectangle_topology<>::point_type;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
int main() {
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g);
|
||||
add_edge(2, 3, g); add_edge(3, 4, g);
|
||||
|
||||
minstd_rand gen(42);
|
||||
rectangle_topology<> topology(gen, 0.0, 0.0, 100.0, 100.0);
|
||||
|
||||
std::vector<Point> positions(num_vertices(g));
|
||||
auto pos_map = make_iterator_property_map(
|
||||
positions.begin(), get(vertex_index, g));
|
||||
|
||||
random_graph_layout(g, pos_map, topology);
|
||||
|
||||
for (auto v : make_iterator_range(vertices(g)))
|
||||
std::cout << "vertex " << v << ": ("
|
||||
<< positions[v][0] << ", " << positions[v][1] << ")\n";
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/bandwidth.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
Graph g{5};
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(0, 4, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
|
||||
auto bw = boost::bandwidth(g);
|
||||
std::cout << "Bandwidth: " << bw << "\n";
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/betweenness_centrality.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
Graph g{5};
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(2, 3, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
|
||||
std::vector<double> centrality(num_vertices(g), 0.0);
|
||||
boost::brandes_betweenness_centrality(g,
|
||||
boost::make_iterator_property_map(centrality.begin(),
|
||||
get(boost::vertex_index, g)));
|
||||
|
||||
std::cout << "Betweenness centrality:\n";
|
||||
for (std::size_t i = 0; i < centrality.size(); ++i) {
|
||||
std::cout << " Vertex " << i << ": " << centrality[i] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/closeness_centrality.hpp>
|
||||
#include <boost/graph/dijkstra_shortest_paths.hpp>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
// Bundled edge property holding the weight
|
||||
struct EdgeProps {
|
||||
int weight;
|
||||
};
|
||||
|
||||
int main() {
|
||||
// Undirected graph with bundled edge properties
|
||||
using Graph = boost::adjacency_list<
|
||||
boost::vecS, boost::vecS, boost::undirectedS,
|
||||
boost::no_property, EdgeProps>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g{5};
|
||||
|
||||
// Build a small weighted undirected graph:
|
||||
// 0 --1-- 1 --2-- 2
|
||||
// | |
|
||||
// 3 1
|
||||
// | |
|
||||
// 3 ------2------ 4
|
||||
add_edge(0, 1, EdgeProps{1}, g);
|
||||
add_edge(1, 2, EdgeProps{2}, g);
|
||||
add_edge(0, 3, EdgeProps{3}, g);
|
||||
add_edge(2, 4, EdgeProps{1}, g);
|
||||
add_edge(3, 4, EdgeProps{2}, g);
|
||||
|
||||
auto weight_map = boost::get(&EdgeProps::weight, g);
|
||||
auto index_map = boost::get(boost::vertex_index, g);
|
||||
|
||||
std::cout << std::fixed << std::setprecision(4);
|
||||
std::cout << "Closeness centrality (1 / sum of shortest distances):\n";
|
||||
|
||||
for (Vertex v = 0; v < boost::num_vertices(g); ++v) {
|
||||
// Run Dijkstra from vertex v to get shortest distances
|
||||
auto n = boost::num_vertices(g);
|
||||
std::vector<int> distances(n);
|
||||
std::vector<Vertex> predecessors(n);
|
||||
auto dist_map = boost::make_iterator_property_map(
|
||||
distances.begin(), index_map);
|
||||
auto pred_map = boost::make_iterator_property_map(
|
||||
predecessors.begin(), index_map);
|
||||
|
||||
boost::dijkstra_shortest_paths(g, v,
|
||||
pred_map, dist_map, weight_map, index_map,
|
||||
std::less<int>{}, std::plus<int>{},
|
||||
(std::numeric_limits<int>::max)(), int{0},
|
||||
boost::default_dijkstra_visitor{});
|
||||
|
||||
// Compute closeness centrality from the distance map
|
||||
double cc = boost::closeness_centrality(g, dist_map);
|
||||
std::cout << " vertex " << v << ": " << cc << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <boost/graph/adjacency_matrix.hpp>
|
||||
#include <boost/graph/clustering_coefficient.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// clustering_coefficient requires AdjacencyMatrix concept (lookup_edge),
|
||||
// so we use adjacency_matrix instead of adjacency_list.
|
||||
using Graph = boost::adjacency_matrix<boost::undirectedS>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 2, g); // triangle on {0,1,2}
|
||||
boost::add_edge(2, 3, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
|
||||
for (auto v : boost::make_iterator_range(vertices(g))) {
|
||||
double cc = boost::clustering_coefficient(g, v);
|
||||
std::cout << "vertex " << v << ": clustering coeff = " << cc << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/core_numbers.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// Bundled vertex property
|
||||
struct VertexProps {
|
||||
std::string label;
|
||||
};
|
||||
|
||||
int main() {
|
||||
// Undirected graph with bundled vertex properties
|
||||
using Graph = boost::adjacency_list<
|
||||
boost::vecS, boost::vecS, boost::undirectedS, VertexProps>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
using SizeType = boost::graph_traits<Graph>::vertices_size_type;
|
||||
|
||||
Graph g(7);
|
||||
g[0].label = "a";
|
||||
g[1].label = "b";
|
||||
g[2].label = "c";
|
||||
g[3].label = "d";
|
||||
g[4].label = "e";
|
||||
g[5].label = "f";
|
||||
g[6].label = "g";
|
||||
|
||||
// Dense 4-clique: a-b-c-d (vertices 0,1,2,3)
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(0, 3, g);
|
||||
add_edge(1, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
add_edge(2, 3, g);
|
||||
|
||||
// Peripheral vertices attached loosely
|
||||
add_edge(3, 4, g); // d -- e
|
||||
add_edge(4, 5, g); // e -- f
|
||||
add_edge(5, 6, g); // f -- g
|
||||
|
||||
// Compute core numbers into a vector property map
|
||||
std::vector<SizeType> core_nums(boost::num_vertices(g));
|
||||
auto core_map = boost::make_iterator_property_map(
|
||||
core_nums.begin(), boost::get(boost::vertex_index, g));
|
||||
|
||||
boost::core_numbers(g, core_map);
|
||||
|
||||
std::cout << "Core numbers (k-core decomposition):\n";
|
||||
for (Vertex v = 0; v < boost::num_vertices(g); ++v) {
|
||||
std::cout << " vertex " << v
|
||||
<< " (" << g[v].label << "): "
|
||||
<< core_nums[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/degree_centrality.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// Bundled vertex property
|
||||
struct VertexProps {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
int main() {
|
||||
// Bidirectional graph with bundled vertex properties
|
||||
// (bidirectionalS is needed so that in-degree / prestige can be computed)
|
||||
using Graph = boost::adjacency_list<
|
||||
boost::vecS, boost::vecS, boost::bidirectionalS, VertexProps>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g(5);
|
||||
g[0].name = "Alice";
|
||||
g[1].name = "Bob";
|
||||
g[2].name = "Carol";
|
||||
g[3].name = "Dave";
|
||||
g[4].name = "Eve";
|
||||
|
||||
// Build a small directed network:
|
||||
// Alice -> Bob, Alice -> Carol, Alice -> Dave
|
||||
// Bob -> Carol
|
||||
// Carol -> Dave, Carol -> Eve
|
||||
// Dave -> Eve
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(0, 3, g);
|
||||
add_edge(1, 2, g);
|
||||
add_edge(2, 3, g);
|
||||
add_edge(2, 4, g);
|
||||
add_edge(3, 4, g);
|
||||
|
||||
std::cout << "Degree centrality (influence = out-degree):\n";
|
||||
for (Vertex v = 0; v < boost::num_vertices(g); ++v) {
|
||||
auto c = boost::degree_centrality(g, v, boost::measure_influence(g));
|
||||
std::cout << " " << g[v].name << ": " << c << "\n";
|
||||
}
|
||||
|
||||
std::cout << "\nDegree centrality (prestige = in-degree):\n";
|
||||
for (Vertex v = 0; v < boost::num_vertices(g); ++v) {
|
||||
auto c = boost::degree_centrality(g, v, boost::measure_prestige(g));
|
||||
std::cout << " " << g[v].name << ": " << c << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/exterior_property.hpp>
|
||||
#include <boost/graph/floyd_warshall_shortest.hpp>
|
||||
#include <boost/graph/eccentricity.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct EdgeProps { int weight; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
|
||||
boost::no_property, EdgeProps>;
|
||||
using DistProp = boost::exterior_vertex_property<Graph, int>;
|
||||
using DistMatrix = DistProp::matrix_type;
|
||||
using DistMatrixMap = DistProp::matrix_map_type;
|
||||
using EccMap = boost::exterior_vertex_property<Graph, int>;
|
||||
|
||||
int main() {
|
||||
Graph g{4};
|
||||
boost::add_edge(0, 1, EdgeProps{1}, g);
|
||||
boost::add_edge(1, 2, EdgeProps{2}, g);
|
||||
boost::add_edge(2, 3, EdgeProps{1}, g);
|
||||
boost::add_edge(0, 3, EdgeProps{5}, g);
|
||||
|
||||
DistMatrix dist(num_vertices(g));
|
||||
DistMatrixMap dm(dist, g);
|
||||
boost::floyd_warshall_all_pairs_shortest_paths(g, dm,
|
||||
boost::weight_map(get(&EdgeProps::weight, g)));
|
||||
|
||||
EccMap::container_type ecc_vec(num_vertices(g));
|
||||
EccMap::map_type ecc(ecc_vec, g);
|
||||
auto rd = boost::all_eccentricities(g, dm, ecc);
|
||||
|
||||
std::cout << "Radius: " << rd.first << ", Diameter: " << rd.second << "\n";
|
||||
for (auto v : boost::make_iterator_range(vertices(g)))
|
||||
std::cout << "eccentricity[" << v << "] = " << ecc_vec[v] << "\n";
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/exterior_property.hpp>
|
||||
#include <boost/graph/floyd_warshall_shortest.hpp>
|
||||
#include <boost/graph/geodesic_distance.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct EdgeProps { int weight; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
|
||||
boost::no_property, EdgeProps>;
|
||||
using DistProp = boost::exterior_vertex_property<Graph, int>;
|
||||
using DistMatrix = DistProp::matrix_type;
|
||||
using DistMatrixMap = DistProp::matrix_map_type;
|
||||
using GeoProp = boost::exterior_vertex_property<Graph, double>;
|
||||
|
||||
int main() {
|
||||
Graph g{4};
|
||||
boost::add_edge(0, 1, EdgeProps{1}, g);
|
||||
boost::add_edge(1, 2, EdgeProps{2}, g);
|
||||
boost::add_edge(2, 3, EdgeProps{1}, g);
|
||||
boost::add_edge(0, 3, EdgeProps{5}, g);
|
||||
|
||||
DistMatrix dist(num_vertices(g));
|
||||
DistMatrixMap dm(dist, g);
|
||||
boost::floyd_warshall_all_pairs_shortest_paths(g, dm,
|
||||
boost::weight_map(get(&EdgeProps::weight, g)));
|
||||
|
||||
GeoProp::container_type geo_vec(num_vertices(g));
|
||||
GeoProp::map_type geo(geo_vec, g);
|
||||
double graph_mean = boost::all_mean_geodesics(g, dm, geo,
|
||||
boost::measure_mean_geodesic(g, GeoProp::map_type(geo_vec, g)));
|
||||
|
||||
for (auto v : boost::make_iterator_range(vertices(g)))
|
||||
std::cout << "mean geodesic[" << v << "] = " << geo_vec[v] << "\n";
|
||||
std::cout << "Graph mean geodesic: " << graph_mean << "\n";
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/page_rank.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
|
||||
// A small web graph: 0 -> 1, 0 -> 2, 1 -> 2, 2 -> 0, 3 -> 2
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 2, g);
|
||||
add_edge(2, 0, g);
|
||||
add_edge(3, 2, g);
|
||||
|
||||
std::vector<double> ranks(num_vertices(g));
|
||||
auto rank_map = make_iterator_property_map(
|
||||
ranks.begin(), get(vertex_index, g));
|
||||
|
||||
// Run PageRank with default damping=0.85 and 20 iterations
|
||||
graph::page_rank(g, rank_map);
|
||||
|
||||
std::cout << std::fixed << std::setprecision(4);
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v << " rank=" << ranks[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/profile.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
Graph g{5};
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(0, 4, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
|
||||
auto p = boost::profile(g);
|
||||
std::cout << "Profile: " << p << "\n";
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/wavefront.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
Graph g{5};
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(0, 4, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
|
||||
auto mw = boost::max_wavefront(g);
|
||||
auto aw = boost::aver_wavefront(g);
|
||||
std::cout << "Max wavefront: " << mw << "\n";
|
||||
std::cout << "Avg wavefront: " << aw << "\n";
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
using Traits = adjacency_list_traits<vecS, vecS, directedS>;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS,
|
||||
property<vertex_color_t, default_color_type,
|
||||
property<vertex_distance_t, long,
|
||||
property<vertex_predecessor_t, Traits::edge_descriptor>>>,
|
||||
property<edge_capacity_t, int,
|
||||
property<edge_residual_capacity_t, int,
|
||||
property<edge_reverse_t, Traits::edge_descriptor>>>>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
void add_flow_edge(Graph& g, int u, int v, int cap) {
|
||||
Edge e1 = add_edge(u, v, g).first;
|
||||
Edge e2 = add_edge(v, u, g).first;
|
||||
put(edge_capacity, g, e1, cap);
|
||||
put(edge_capacity, g, e2, 0);
|
||||
put(edge_reverse, g, e1, e2);
|
||||
put(edge_reverse, g, e2, e1);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_flow_edge(g, 0, 1, 3);
|
||||
add_flow_edge(g, 0, 2, 2);
|
||||
add_flow_edge(g, 1, 3, 2);
|
||||
add_flow_edge(g, 2, 3, 3);
|
||||
|
||||
int flow = boykov_kolmogorov_max_flow(g, vertex(0, g), vertex(3, g));
|
||||
std::cout << "Boykov-Kolmogorov max flow: " << flow << "\n";
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/cycle_canceling.hpp>
|
||||
#include <boost/graph/edmonds_karp_max_flow.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
using Traits = adjacency_list_traits<vecS, vecS, directedS>;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property,
|
||||
property<edge_capacity_t, int,
|
||||
property<edge_residual_capacity_t, int,
|
||||
property<edge_weight_t, int,
|
||||
property<edge_reverse_t, Traits::edge_descriptor>>>>>;
|
||||
using Edge = Traits::edge_descriptor;
|
||||
|
||||
void add_edge_pair(Graph& g, int u, int v, int cap, int cost) {
|
||||
Edge e = add_edge(u, v, g).first;
|
||||
Edge r = add_edge(v, u, g).first;
|
||||
put(edge_capacity, g, e, cap); put(edge_capacity, g, r, 0);
|
||||
put(edge_weight, g, e, cost); put(edge_weight, g, r, -cost);
|
||||
put(edge_reverse, g, e, r); put(edge_reverse, g, r, e);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_edge_pair(g, 0, 1, 2, 1);
|
||||
add_edge_pair(g, 0, 2, 1, 3);
|
||||
add_edge_pair(g, 1, 3, 2, 2);
|
||||
add_edge_pair(g, 2, 3, 3, 1);
|
||||
|
||||
edmonds_karp_max_flow(g, 0, 3);
|
||||
cycle_canceling(g);
|
||||
int cost = find_flow_cost(g);
|
||||
std::cout << "Min cost: " << cost << "\n";
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/edmonds_karp_max_flow.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
using Traits = adjacency_list_traits<vecS, vecS, directedS>;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS,
|
||||
property<vertex_index_t, std::size_t>,
|
||||
property<edge_capacity_t, int,
|
||||
property<edge_residual_capacity_t, int,
|
||||
property<edge_reverse_t, Traits::edge_descriptor>>>>;
|
||||
using Edge = Traits::edge_descriptor;
|
||||
|
||||
void add_flow_edge(Graph& g, int from, int to, int cap) {
|
||||
auto cap_map = get(edge_capacity, g);
|
||||
auto rev_map = get(edge_reverse, g);
|
||||
Edge e = add_edge(from, to, g).first;
|
||||
Edge r = add_edge(to, from, g).first;
|
||||
cap_map[e] = cap;
|
||||
cap_map[r] = 0;
|
||||
rev_map[e] = r;
|
||||
rev_map[r] = e;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_flow_edge(g, 0, 1, 10);
|
||||
add_flow_edge(g, 0, 2, 10);
|
||||
add_flow_edge(g, 1, 3, 5);
|
||||
add_flow_edge(g, 2, 3, 15);
|
||||
add_flow_edge(g, 1, 2, 4);
|
||||
|
||||
int flow = edmonds_karp_max_flow(g, 0, 3);
|
||||
std::cout << "Edmonds-Karp max flow: " << flow << "\n";
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/edmonds_karp_max_flow.hpp>
|
||||
#include <boost/graph/find_flow_cost.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
using Traits = adjacency_list_traits<vecS, vecS, directedS>;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property,
|
||||
property<edge_capacity_t, int,
|
||||
property<edge_residual_capacity_t, int,
|
||||
property<edge_weight_t, int,
|
||||
property<edge_reverse_t, Traits::edge_descriptor>>>>>;
|
||||
using Edge = Traits::edge_descriptor;
|
||||
|
||||
void add_edge_pair(Graph& g, int u, int v, int cap, int cost) {
|
||||
Edge e = add_edge(u, v, g).first;
|
||||
Edge r = add_edge(v, u, g).first;
|
||||
put(edge_capacity, g, e, cap); put(edge_capacity, g, r, 0);
|
||||
put(edge_weight, g, e, cost); put(edge_weight, g, r, -cost);
|
||||
put(edge_reverse, g, e, r); put(edge_reverse, g, r, e);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_edge_pair(g, 0, 1, 2, 1);
|
||||
add_edge_pair(g, 0, 2, 1, 3);
|
||||
add_edge_pair(g, 1, 3, 2, 2);
|
||||
add_edge_pair(g, 2, 3, 3, 1);
|
||||
|
||||
edmonds_karp_max_flow(g, 0, 3);
|
||||
int cost = find_flow_cost(g);
|
||||
std::cout << "Flow cost: " << cost << "\n";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/max_cardinality_matching.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
Graph g(6);
|
||||
boost::add_edge(0, 1, g); boost::add_edge(0, 3, g);
|
||||
boost::add_edge(1, 2, g); boost::add_edge(2, 3, g);
|
||||
boost::add_edge(4, 5, g);
|
||||
|
||||
std::vector<Vertex> mate(num_vertices(g));
|
||||
auto mate_map = boost::make_iterator_property_map(
|
||||
mate.begin(), get(boost::vertex_index, g));
|
||||
boost::edmonds_maximum_cardinality_matching(g, mate_map);
|
||||
|
||||
std::cout << "Maximum matching (" << boost::matching_size(g, mate_map,
|
||||
get(boost::vertex_index, g)) << " edges):\n";
|
||||
for (Vertex v = 0; v < num_vertices(g); ++v) {
|
||||
if (mate[v] != boost::graph_traits<Graph>::null_vertex() && v < mate[v])
|
||||
std::cout << " " << v << " - " << mate[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/maximum_weighted_matching.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS, no_property,
|
||||
property<edge_weight_t, int>>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g(5);
|
||||
add_edge(0, 1, {3}, g);
|
||||
add_edge(1, 2, {1}, g);
|
||||
add_edge(2, 3, {4}, g);
|
||||
add_edge(3, 4, {2}, g);
|
||||
add_edge(0, 4, {5}, g);
|
||||
|
||||
std::vector<Vertex> mate(num_vertices(g));
|
||||
maximum_weighted_matching(g, &mate[0]);
|
||||
|
||||
std::cout << "Matched edges:\n";
|
||||
int total = 0;
|
||||
for (Vertex v = 0; v < num_vertices(g); ++v) {
|
||||
if (mate[v] != graph_traits<Graph>::null_vertex() && v < mate[v]) {
|
||||
auto w = get(edge_weight, g, edge(v, mate[v], g).first);
|
||||
std::cout << " " << v << " -- " << mate[v] << " (w=" << w << ")\n";
|
||||
total += w;
|
||||
}
|
||||
}
|
||||
std::cout << "Total weight: " << total << "\n";
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/push_relabel_max_flow.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
using Traits = adjacency_list_traits<vecS, vecS, directedS>;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS,
|
||||
property<vertex_index_t, std::size_t>,
|
||||
property<edge_capacity_t, int,
|
||||
property<edge_residual_capacity_t, int,
|
||||
property<edge_reverse_t, Traits::edge_descriptor>>>>;
|
||||
using Edge = Traits::edge_descriptor;
|
||||
|
||||
void add_flow_edge(Graph& g, int from, int to, int cap) {
|
||||
auto cap_map = get(edge_capacity, g);
|
||||
auto rev_map = get(edge_reverse, g);
|
||||
Edge e = add_edge(from, to, g).first;
|
||||
Edge r = add_edge(to, from, g).first;
|
||||
cap_map[e] = cap;
|
||||
cap_map[r] = 0;
|
||||
rev_map[e] = r;
|
||||
rev_map[r] = e;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_flow_edge(g, 0, 1, 10);
|
||||
add_flow_edge(g, 0, 2, 10);
|
||||
add_flow_edge(g, 1, 3, 5);
|
||||
add_flow_edge(g, 2, 3, 15);
|
||||
add_flow_edge(g, 1, 2, 4);
|
||||
|
||||
int flow = push_relabel_max_flow(g, 0, 3);
|
||||
std::cout << "Push-relabel max flow: " << flow << "\n";
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/stoer_wagner_min_cut.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct EdgeProps { int weight; };
|
||||
|
||||
using namespace boost;
|
||||
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
no_property, EdgeProps>;
|
||||
|
||||
int main() {
|
||||
Graph g{4};
|
||||
add_edge(0, 1, EdgeProps{2}, g);
|
||||
add_edge(0, 2, EdgeProps{3}, g);
|
||||
add_edge(1, 2, EdgeProps{3}, g);
|
||||
add_edge(1, 3, EdgeProps{2}, g);
|
||||
add_edge(2, 3, EdgeProps{4}, g);
|
||||
|
||||
auto weight_map = get(&EdgeProps::weight, g);
|
||||
int cut = stoer_wagner_min_cut(g, weight_map);
|
||||
std::cout << "Stoer-Wagner min cut: " << cut << "\n";
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/successive_shortest_path_nonnegative_weights.hpp>
|
||||
#include <boost/graph/find_flow_cost.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
// This algorithm requires internal property tags for edge properties.
|
||||
using Traits = adjacency_list_traits<vecS, vecS, directedS>;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property,
|
||||
property<edge_capacity_t, int,
|
||||
property<edge_residual_capacity_t, int,
|
||||
property<edge_weight_t, int,
|
||||
property<edge_reverse_t, Traits::edge_descriptor>>>>>;
|
||||
using Edge = Traits::edge_descriptor;
|
||||
|
||||
void add_edge_pair(Graph& g, int u, int v, int cap, int cost) {
|
||||
Edge e = add_edge(u, v, g).first;
|
||||
Edge r = add_edge(v, u, g).first;
|
||||
put(edge_capacity, g, e, cap); put(edge_capacity, g, r, 0);
|
||||
put(edge_weight, g, e, cost); put(edge_weight, g, r, -cost);
|
||||
put(edge_reverse, g, e, r); put(edge_reverse, g, r, e);
|
||||
put(edge_residual_capacity, g, e, 0);
|
||||
put(edge_residual_capacity, g, r, 0);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_edge_pair(g, 0, 1, 2, 1);
|
||||
add_edge_pair(g, 0, 2, 1, 3);
|
||||
add_edge_pair(g, 1, 3, 2, 2);
|
||||
add_edge_pair(g, 2, 3, 3, 1);
|
||||
|
||||
successive_shortest_path_nonnegative_weights(g, 0, 3);
|
||||
std::cout << "Min cost: " << find_flow_cost(g) << "\n";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/cuthill_mckee_ordering.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
Graph g{6};
|
||||
boost::add_edge(0, 3, g);
|
||||
boost::add_edge(0, 5, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(1, 4, g);
|
||||
boost::add_edge(2, 5, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
std::vector<Vertex> order;
|
||||
boost::cuthill_mckee_ordering(g, std::back_inserter(order));
|
||||
|
||||
std::cout << "Cuthill-McKee ordering:";
|
||||
for (auto v : order) {
|
||||
std::cout << " " << v;
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/king_ordering.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g(6);
|
||||
add_edge(0, 3, g); add_edge(0, 5, g);
|
||||
add_edge(1, 2, g); add_edge(1, 4, g);
|
||||
add_edge(2, 5, g); add_edge(3, 4, g);
|
||||
|
||||
std::vector<Vertex> order;
|
||||
king_ordering(g, std::back_inserter(order));
|
||||
|
||||
std::cout << "King ordering:";
|
||||
for (auto v : order)
|
||||
std::cout << " " << v;
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/minimum_degree_ordering.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
using size_type = graph_traits<Graph>::vertices_size_type;
|
||||
|
||||
int main() {
|
||||
int n = 6;
|
||||
Graph g(n);
|
||||
// Symmetric edges (required: both directions for each undirected edge)
|
||||
add_edge(0, 1, g); add_edge(1, 0, g);
|
||||
add_edge(0, 3, g); add_edge(3, 0, g);
|
||||
add_edge(1, 2, g); add_edge(2, 1, g);
|
||||
add_edge(2, 4, g); add_edge(4, 2, g);
|
||||
add_edge(3, 5, g); add_edge(5, 3, g);
|
||||
add_edge(4, 5, g); add_edge(5, 4, g);
|
||||
|
||||
std::vector<int> inverse_perm(n), perm(n), degree(n), supernode(n, 1);
|
||||
auto id = get(vertex_index, g);
|
||||
|
||||
minimum_degree_ordering(g,
|
||||
make_iterator_property_map(degree.begin(), id),
|
||||
make_iterator_property_map(inverse_perm.begin(), id),
|
||||
make_iterator_property_map(perm.begin(), id),
|
||||
make_iterator_property_map(supernode.begin(), id),
|
||||
0, id);
|
||||
|
||||
std::cout << "Minimum degree ordering:";
|
||||
for (int i = 0; i < n; ++i)
|
||||
std::cout << " " << inverse_perm[i];
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/sloan_ordering.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<setS, vecS, undirectedS,
|
||||
property<vertex_color_t, default_color_type,
|
||||
property<vertex_degree_t, int,
|
||||
property<vertex_priority_t, double>>>>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g(6);
|
||||
add_edge(0, 1, g); add_edge(0, 2, g); add_edge(1, 3, g);
|
||||
add_edge(2, 3, g); add_edge(3, 4, g); add_edge(4, 5, g);
|
||||
|
||||
std::vector<Vertex> order(num_vertices(g));
|
||||
sloan_ordering(g, order.begin(),
|
||||
get(vertex_color, g), get(vertex_degree, g), get(vertex_priority, g));
|
||||
|
||||
std::cout << "Sloan ordering:";
|
||||
for (auto v : order) { std::cout << " " << v; }
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/sloan_ordering.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// sloan_start_end_vertices requires property tags for color and degree.
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
property<vertex_color_t, default_color_type,
|
||||
property<vertex_degree_t, int,
|
||||
property<vertex_priority_t, double>>>>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g(6);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g);
|
||||
add_edge(2, 3, g); add_edge(3, 4, g);
|
||||
add_edge(4, 5, g); add_edge(0, 5, g);
|
||||
|
||||
// The degree map must be initialized with actual vertex degrees.
|
||||
auto deg = get(vertex_degree, g);
|
||||
for (auto v : make_iterator_range(vertices(g))) {
|
||||
put(deg, v, static_cast<int>(out_degree(v, g)));
|
||||
}
|
||||
|
||||
Vertex s = *vertices(g).first;
|
||||
Vertex e = sloan_start_end_vertices(g, s, get(vertex_color, g), deg);
|
||||
|
||||
std::cout << "Start vertex: " << s << "\n";
|
||||
std::cout << "End vertex: " << e << "\n";
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/boyer_myrvold_planar_test.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
Graph make_complete(int n) {
|
||||
Graph g(n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (int j = i + 1; j < n; ++j)
|
||||
add_edge(i, j, g);
|
||||
return g;
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto k4 = make_complete(4);
|
||||
auto k5 = make_complete(5);
|
||||
std::cout << "K4 is planar: " << std::boolalpha
|
||||
<< boyer_myrvold_planarity_test(k4) << "\n";
|
||||
std::cout << "K5 is planar: " << std::boolalpha
|
||||
<< boyer_myrvold_planarity_test(k5) << "\n";
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/boyer_myrvold_planar_test.hpp>
|
||||
#include <boost/graph/make_biconnected_planar.hpp>
|
||||
#include <boost/graph/make_maximal_planar.hpp>
|
||||
#include <boost/graph/planar_canonical_ordering.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
property<vertex_index_t, int>, property<edge_index_t, int>>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
void reindex(Graph& g) {
|
||||
int i = 0;
|
||||
for (auto e : make_iterator_range(edges(g))) { put(edge_index, g, e, i++); }
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Start with a triangle (already maximal planar for 3 vertices)
|
||||
Graph g(3);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g); add_edge(0, 2, g);
|
||||
reindex(g);
|
||||
|
||||
std::vector<std::vector<Edge>> storage(num_vertices(g));
|
||||
auto embedding = make_iterator_property_map(storage.begin(), get(vertex_index, g));
|
||||
boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
|
||||
boyer_myrvold_params::embedding = embedding);
|
||||
|
||||
std::vector<Vertex> order;
|
||||
planar_canonical_ordering(g, embedding, std::back_inserter(order),
|
||||
get(vertex_index, g));
|
||||
|
||||
std::cout << "Planar canonical ordering:";
|
||||
for (auto v : order) { std::cout << " " << v; }
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/boyer_myrvold_planar_test.hpp>
|
||||
#include <boost/graph/make_biconnected_planar.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
property<vertex_index_t, int>, property<edge_index_t, int>>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
int main() {
|
||||
// A path graph: 0-1-2-3 (planar but not biconnected)
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g); add_edge(2, 3, g);
|
||||
|
||||
// Assign edge indices
|
||||
int idx = 0;
|
||||
for (auto e : make_iterator_range(edges(g))) { put(edge_index, g, e, idx++); }
|
||||
|
||||
// Compute planar embedding
|
||||
using EmbStorage = std::vector<std::vector<Edge>>;
|
||||
EmbStorage storage(num_vertices(g));
|
||||
auto embedding = make_iterator_property_map(storage.begin(), get(vertex_index, g));
|
||||
boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
|
||||
boyer_myrvold_params::embedding = embedding);
|
||||
|
||||
std::cout << "Edges before: " << num_edges(g) << "\n";
|
||||
// Re-index edges before calling make_biconnected_planar
|
||||
idx = 0;
|
||||
for (auto e : make_iterator_range(edges(g))) { put(edge_index, g, e, idx++); }
|
||||
make_biconnected_planar(g, embedding, get(edge_index, g));
|
||||
std::cout << "Edges after make_biconnected_planar: " << num_edges(g) << "\n";
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/make_connected.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
int main() {
|
||||
Graph g(6);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(2, 3, g);
|
||||
add_edge(4, 5, g);
|
||||
|
||||
std::cout << "Edges before: " << num_edges(g) << "\n";
|
||||
make_connected(g);
|
||||
std::cout << "Edges after: " << num_edges(g) << "\n";
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/boyer_myrvold_planar_test.hpp>
|
||||
#include <boost/graph/make_biconnected_planar.hpp>
|
||||
#include <boost/graph/make_maximal_planar.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
property<vertex_index_t, int>, property<edge_index_t, int>>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
void reindex(Graph& g) {
|
||||
int i = 0;
|
||||
for (auto e : make_iterator_range(edges(g))) { put(edge_index, g, e, i++); }
|
||||
}
|
||||
|
||||
void reembed(Graph& g, std::vector<std::vector<Edge>>& s) {
|
||||
s.assign(num_vertices(g), {});
|
||||
auto emb = make_iterator_property_map(s.begin(), get(vertex_index, g));
|
||||
boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
|
||||
boyer_myrvold_params::embedding = emb);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g); add_edge(2, 3, g);
|
||||
|
||||
std::vector<std::vector<Edge>> st(num_vertices(g));
|
||||
reindex(g); reembed(g, st);
|
||||
auto emb = make_iterator_property_map(st.begin(), get(vertex_index, g));
|
||||
make_biconnected_planar(g, emb, get(edge_index, g));
|
||||
|
||||
reindex(g); reembed(g, st);
|
||||
emb = make_iterator_property_map(st.begin(), get(vertex_index, g));
|
||||
std::cout << "Edges before: " << num_edges(g) << "\n";
|
||||
make_maximal_planar(g, emb);
|
||||
std::cout << "Edges after make_maximal_planar: " << num_edges(g) << "\n";
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/boyer_myrvold_planar_test.hpp>
|
||||
#include <boost/graph/planar_face_traversal.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
property<vertex_index_t, int>, property<edge_index_t, int>>;
|
||||
|
||||
struct face_counter : public planar_face_traversal_visitor {
|
||||
int count = 0;
|
||||
void begin_face() { ++count; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g); add_edge(1, 2, g);
|
||||
add_edge(2, 3, g); add_edge(3, 0, g);
|
||||
add_edge(0, 2, g);
|
||||
|
||||
int idx = 0;
|
||||
for (auto e : make_iterator_range(edges(g)))
|
||||
put(edge_index, g, e, idx++);
|
||||
|
||||
using embedding_t = std::vector<std::vector<graph_traits<Graph>::edge_descriptor>>;
|
||||
embedding_t embedding(num_vertices(g));
|
||||
boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
|
||||
boyer_myrvold_params::embedding = &embedding[0]);
|
||||
|
||||
face_counter visitor;
|
||||
planar_face_traversal(g, &embedding[0], visitor);
|
||||
std::cout << "Number of faces: " << visitor.count << "\n";
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/astar_search.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
struct Edge { int weight; };
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property, Edge>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
struct zero_heuristic : public astar_heuristic<Graph, int> {
|
||||
int operator()(Vertex) const { return 0; }
|
||||
};
|
||||
|
||||
// Stop when target is found
|
||||
struct found_target { Vertex v; };
|
||||
struct target_visitor : public default_astar_visitor {
|
||||
target_visitor(Vertex t) : m_target{t} {}
|
||||
void examine_vertex(Vertex u, const Graph&) const {
|
||||
if (u == m_target) { throw found_target{u}; }
|
||||
}
|
||||
Vertex m_target;
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g{4};
|
||||
add_edge(0, 1, Edge{2}, g);
|
||||
add_edge(1, 2, Edge{3}, g);
|
||||
add_edge(0, 2, Edge{8}, g);
|
||||
add_edge(2, 3, Edge{1}, g);
|
||||
|
||||
using CostType = int;
|
||||
using IndexMap = decltype(get(vertex_index, std::declval<Graph&>()));
|
||||
|
||||
auto n = num_vertices(g);
|
||||
std::vector<CostType> dist(n, (std::numeric_limits<CostType>::max)());
|
||||
std::vector<CostType> cost(n, (std::numeric_limits<CostType>::max)());
|
||||
std::vector<Vertex> pred(n);
|
||||
|
||||
auto index_map = get(vertex_index, g);
|
||||
auto dist_map = make_iterator_property_map(dist.begin(), index_map);
|
||||
auto cost_map = make_iterator_property_map(cost.begin(), index_map);
|
||||
auto pred_map = make_iterator_property_map(pred.begin(), index_map);
|
||||
auto weight_map = get(&Edge::weight, g);
|
||||
two_bit_color_map<IndexMap> color_map{n, index_map};
|
||||
|
||||
CostType inf = (std::numeric_limits<CostType>::max)();
|
||||
CostType zero_val = CostType{};
|
||||
|
||||
try {
|
||||
astar_search(g, vertex(0, g), zero_heuristic(),
|
||||
target_visitor{3},
|
||||
pred_map, cost_map, dist_map, weight_map,
|
||||
index_map, color_map,
|
||||
std::less<CostType>{}, closed_plus<CostType>{inf},
|
||||
inf, zero_val);
|
||||
} catch (const found_target&) {}
|
||||
|
||||
for (auto v : make_iterator_range(vertices(g))) {
|
||||
std::cout << "distance to " << v << " = " << dist[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/bellman_ford_shortest_paths.hpp>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
struct Node {};
|
||||
struct Edge { int weight; };
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, Node, Edge>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g{4};
|
||||
add_edge(0, 1, Edge{1}, g);
|
||||
add_edge(1, 2, Edge{-2}, g);
|
||||
add_edge(0, 2, Edge{4}, g);
|
||||
add_edge(2, 3, Edge{3}, g);
|
||||
|
||||
auto n = num_vertices(g);
|
||||
std::vector<int> dist(n, (std::numeric_limits<int>::max)());
|
||||
std::vector<Vertex> pred(n);
|
||||
dist[0] = 0;
|
||||
for (std::size_t i = 0; i < n; ++i)
|
||||
pred[i] = i;
|
||||
|
||||
auto weight_map = get(&Edge::weight, g);
|
||||
auto dist_map = make_iterator_property_map(dist.begin(), get(vertex_index, g));
|
||||
auto pred_map = make_iterator_property_map(pred.begin(), get(vertex_index, g));
|
||||
|
||||
bellman_ford_shortest_paths(g, n, weight_map, pred_map, dist_map,
|
||||
std::plus<int>(), std::less<int>(), default_bellman_visitor());
|
||||
|
||||
for (auto v : make_iterator_range(vertices(g)))
|
||||
std::cout << "distance to " << v << " = " << dist[v] << "\n";
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/dag_shortest_paths.hpp>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
struct Node {};
|
||||
struct Edge { int weight; };
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, Node, Edge>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
add_edge(0, 1, Edge{2}, g);
|
||||
add_edge(0, 2, Edge{6}, g);
|
||||
add_edge(1, 3, Edge{5}, g);
|
||||
add_edge(2, 3, Edge{1}, g);
|
||||
add_edge(3, 4, Edge{3}, g);
|
||||
|
||||
std::vector<int> dist(num_vertices(g));
|
||||
std::vector<Vertex> pred(num_vertices(g));
|
||||
std::vector<default_color_type> color(num_vertices(g));
|
||||
|
||||
auto idx = get(vertex_index, g);
|
||||
dag_shortest_paths(g, vertex(0, g),
|
||||
make_iterator_property_map(dist.begin(), idx),
|
||||
get(&Edge::weight, g),
|
||||
make_iterator_property_map(color.begin(), idx),
|
||||
make_iterator_property_map(pred.begin(), idx),
|
||||
dijkstra_visitor<null_visitor>(),
|
||||
std::less<int>(), std::plus<int>(),
|
||||
(std::numeric_limits<int>::max)(), 0);
|
||||
|
||||
for (auto v : make_iterator_range(vertices(g)))
|
||||
std::cout << "distance to " << v << " = " << dist[v] << "\n";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/dijkstra_shortest_paths_no_color_map.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct EdgeProps { int weight; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, EdgeProps>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g{4};
|
||||
boost::add_edge(0, 1, EdgeProps{1}, g);
|
||||
boost::add_edge(1, 2, EdgeProps{2}, g);
|
||||
boost::add_edge(0, 2, EdgeProps{10}, g);
|
||||
boost::add_edge(2, 3, EdgeProps{1}, g);
|
||||
|
||||
std::vector<Vertex> pred(num_vertices(g));
|
||||
std::vector<int> dist(num_vertices(g));
|
||||
auto idx = get(boost::vertex_index, g);
|
||||
auto wt = get(&EdgeProps::weight, g);
|
||||
|
||||
boost::dijkstra_shortest_paths_no_color_map(g, vertex(0, g),
|
||||
boost::predecessor_map(boost::make_iterator_property_map(pred.begin(), idx))
|
||||
.distance_map(boost::make_iterator_property_map(dist.begin(), idx))
|
||||
.weight_map(wt));
|
||||
|
||||
for (auto v : boost::make_iterator_range(vertices(g)))
|
||||
std::cout << "dist[" << v << "] = " << dist[v] << "\n";
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/floyd_warshall_shortest.hpp>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
struct Node {};
|
||||
struct Edge { int weight; };
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, Node, Edge>;
|
||||
|
||||
int main() {
|
||||
Graph g{3};
|
||||
add_edge(0, 1, Edge{2}, g);
|
||||
add_edge(1, 2, Edge{3}, g);
|
||||
add_edge(0, 2, Edge{7}, g);
|
||||
|
||||
auto n = num_vertices(g);
|
||||
std::vector<std::vector<int>> D(n, std::vector<int>(n));
|
||||
|
||||
floyd_warshall_all_pairs_shortest_paths(g, D,
|
||||
get(&Edge::weight, g),
|
||||
std::less<int>{},
|
||||
closed_plus<int>{(std::numeric_limits<int>::max)()},
|
||||
(std::numeric_limits<int>::max)(),
|
||||
int{0});
|
||||
|
||||
for (std::size_t i = 0; i < n; ++i) {
|
||||
for (std::size_t j = 0; j < n; ++j)
|
||||
std::cout << D[i][j] << (j + 1 < n ? " " : "");
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/johnson_all_pairs_shortest.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct Node {};
|
||||
struct Edge { int weight; };
|
||||
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, Node, Edge>;
|
||||
|
||||
int main() {
|
||||
Graph g{3};
|
||||
add_edge(0, 1, Edge{2}, g);
|
||||
add_edge(1, 2, Edge{3}, g);
|
||||
add_edge(0, 2, Edge{7}, g);
|
||||
|
||||
auto n = num_vertices(g);
|
||||
std::vector<std::vector<int>> D(n, std::vector<int>(n));
|
||||
|
||||
johnson_all_pairs_shortest_paths(g, D,
|
||||
get(vertex_index, g), get(&Edge::weight, g), int{0});
|
||||
|
||||
for (std::size_t i = 0; i < n; ++i) {
|
||||
for (std::size_t j = 0; j < n; ++j)
|
||||
std::cout << D[i][j] << (j + 1 < n ? " " : "");
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/r_c_shortest_paths.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// r_c_shortest_paths requires an edge_index_map, so we include edge_index_t.
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property,
|
||||
property<edge_index_t, int, property<edge_weight_t, int>>>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
// Resource container: (cost, time)
|
||||
struct Res { int cost; int time; };
|
||||
bool operator==(const Res& a, const Res& b) { return a.cost == b.cost && a.time == b.time; }
|
||||
bool operator<(const Res& a, const Res& b) { return a.cost < b.cost; }
|
||||
|
||||
struct ResExt {
|
||||
bool operator()(const Graph& g, Res& new_r, const Res& old_r, Edge e) const {
|
||||
new_r.cost = old_r.cost + get(edge_weight, g, e);
|
||||
new_r.time = old_r.time + 1;
|
||||
return new_r.time <= 5; // hop-count constraint
|
||||
}
|
||||
};
|
||||
|
||||
struct Dom {
|
||||
bool operator()(const Res& r1, const Res& r2) const {
|
||||
return r1.cost <= r2.cost && r1.time <= r2.time;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
int idx = 0;
|
||||
auto ae = [&](int u, int v, int w) {
|
||||
auto e = add_edge(u, v, g).first;
|
||||
put(edge_index, g, e, idx++);
|
||||
put(edge_weight, g, e, w);
|
||||
};
|
||||
ae(0, 1, 2); ae(0, 2, 5); ae(1, 3, 3); ae(2, 3, 2);
|
||||
|
||||
std::vector<Edge> path;
|
||||
Res result{0, 0};
|
||||
r_c_shortest_paths(g, get(vertex_index, g), get(edge_index, g),
|
||||
vertex(0, g), vertex(3, g), path, result,
|
||||
Res{0, 0}, ResExt{}, Dom{});
|
||||
|
||||
std::cout << "Cost: " << result.cost << ", hops: " << result.time << "\n";
|
||||
std::cout << "Path edges: " << path.size() << "\n";
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/kruskal_min_spanning_tree.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct Road { int weight; };
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS, no_property, Road>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, Road{2}, g);
|
||||
add_edge(0, 3, Road{1}, g);
|
||||
add_edge(1, 2, Road{3}, g);
|
||||
add_edge(1, 3, Road{2}, g);
|
||||
add_edge(2, 3, Road{5}, g);
|
||||
add_edge(2, 4, Road{4}, g);
|
||||
add_edge(3, 4, Road{6}, g);
|
||||
|
||||
// Call the detail implementation directly to pass a bundled weight map
|
||||
auto n = num_vertices(g);
|
||||
std::vector<std::size_t> rank_vec(n);
|
||||
std::vector<Vertex> parent_vec(n);
|
||||
auto index = get(vertex_index, g);
|
||||
auto rank_map = make_iterator_property_map(rank_vec.begin(), index);
|
||||
auto parent_map = make_iterator_property_map(parent_vec.begin(), index);
|
||||
|
||||
std::vector<Edge> mst;
|
||||
detail::kruskal_mst_impl(g, std::back_inserter(mst),
|
||||
rank_map, parent_map, get(&Road::weight, g));
|
||||
|
||||
int total = 0;
|
||||
std::cout << "MST edges:\n";
|
||||
for (auto& e : mst) {
|
||||
int w = g[e].weight;
|
||||
std::cout << " " << source(e, g) << " -- "
|
||||
<< target(e, g) << " (weight " << w << ")\n";
|
||||
total += w;
|
||||
}
|
||||
std::cout << "Total weight: " << total << "\n";
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Prim Minimum Spanning Tree example
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/prim_minimum_spanning_tree.hpp>
|
||||
|
||||
struct EdgeWeight { int weight; };
|
||||
|
||||
using Graph = boost::adjacency_list<
|
||||
boost::vecS, boost::vecS, boost::undirectedS, boost::no_property, EdgeWeight>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
auto add = [&](int u, int v, int w) { boost::add_edge(u, v, EdgeWeight{w}, g); };
|
||||
add(0, 1, 2); add(0, 3, 1); add(1, 2, 3);
|
||||
add(1, 3, 2); add(2, 4, 4); add(3, 4, 6);
|
||||
|
||||
auto n = boost::num_vertices(g);
|
||||
std::vector<Vertex> pred(n);
|
||||
std::vector<int> dist(n);
|
||||
auto index_map = boost::get(boost::vertex_index, g);
|
||||
auto pred_map = boost::make_iterator_property_map(pred.begin(), index_map);
|
||||
auto dist_map = boost::make_iterator_property_map(dist.begin(), index_map);
|
||||
auto weight_map = boost::get(&EdgeWeight::weight, g);
|
||||
|
||||
boost::prim_minimum_spanning_tree(g, *boost::vertices(g).first,
|
||||
pred_map, dist_map, weight_map, index_map,
|
||||
boost::default_dijkstra_visitor{});
|
||||
|
||||
std::cout << "Predecessor map (vertex : parent):\n";
|
||||
for (Vertex v = 0; v < boost::num_vertices(g); ++v) {
|
||||
std::cout << " " << v << " : " << pred[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/random_spanning_tree.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
Graph g(5);
|
||||
boost::add_edge(0, 1, g); boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 2, g); boost::add_edge(1, 3, g);
|
||||
boost::add_edge(2, 3, g); boost::add_edge(3, 4, g);
|
||||
boost::add_edge(2, 4, g);
|
||||
|
||||
std::vector<Vertex> pred(num_vertices(g));
|
||||
std::vector<boost::default_color_type> color(num_vertices(g));
|
||||
std::mt19937 gen(42); // fixed seed for deterministic output
|
||||
boost::random_spanning_tree(g, gen, Vertex{0},
|
||||
boost::make_iterator_property_map(pred.begin(), get(boost::vertex_index, g)),
|
||||
boost::static_property_map<double>(1.0),
|
||||
boost::make_iterator_property_map(color.begin(), get(boost::vertex_index, g)));
|
||||
|
||||
std::cout << "Random spanning tree edges:\n";
|
||||
for (Vertex v = 0; v < num_vertices(g); ++v) {
|
||||
if (pred[v] != boost::graph_traits<Graph>::null_vertex() && pred[v] != v)
|
||||
std::cout << " " << pred[v] << " - " << v << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/two_graphs_common_spanning_trees.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
using Edge = boost::graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
int count = 0;
|
||||
|
||||
struct CountTrees {
|
||||
void operator()(const std::vector<bool>& inL) {
|
||||
++count;
|
||||
std::cout << " Tree " << count << ": edges";
|
||||
for (std::size_t i = 0; i < inL.size(); ++i) {
|
||||
if (inL[i]) { std::cout << " " << i; }
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
// Two identical triangle graphs (3 vertices, 3 edges)
|
||||
Graph g1(3), g2(3);
|
||||
boost::add_edge(0, 1, g1); boost::add_edge(1, 2, g1); boost::add_edge(0, 2, g1);
|
||||
boost::add_edge(0, 1, g2); boost::add_edge(1, 2, g2); boost::add_edge(0, 2, g2);
|
||||
|
||||
std::vector<bool> inL(num_edges(g1), false);
|
||||
std::cout << "Common spanning trees:\n";
|
||||
boost::two_graphs_common_spanning_trees(g1, g2, CountTrees{}, inL);
|
||||
std::cout << "Total: " << count << "\n";
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/topological_sort.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
struct VertexProps { std::string name; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProps>;
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
g[0].name = "A"; g[1].name = "B"; g[2].name = "C";
|
||||
g[3].name = "D"; g[4].name = "E";
|
||||
boost::add_edge(0, 2, g); // A -> C
|
||||
boost::add_edge(1, 2, g); // B -> C
|
||||
boost::add_edge(2, 3, g); // C -> D
|
||||
boost::add_edge(2, 4, g); // C -> E
|
||||
|
||||
std::vector<Graph::vertex_descriptor> order;
|
||||
boost::topological_sort(g, std::back_inserter(order));
|
||||
|
||||
std::cout << "Topological order: ";
|
||||
for (auto v : order) { std::cout << g[v].name << " "; }
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct VertexProps { int id; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProps>;
|
||||
|
||||
struct DiscoverVisitor : boost::default_bfs_visitor {
|
||||
void discover_vertex(Graph::vertex_descriptor v, const Graph& g) const {
|
||||
std::cout << g[v].id << " ";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
for (int i = 0; i < 5; ++i) { g[i].id = i; }
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 3, g);
|
||||
boost::add_edge(2, 4, g);
|
||||
|
||||
std::cout << "BFS discovery order: ";
|
||||
boost::breadth_first_search(g, 0, boost::visitor(DiscoverVisitor{}));
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/pending/queue.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct VertexProps { int id; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProps>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
struct PrintVisitor : boost::default_bfs_visitor {
|
||||
void discover_vertex(Vertex v, const Graph& g) const {
|
||||
std::cout << g[v].id << " ";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
for (int i = 0; i < 5; ++i) { g[i].id = i; }
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 3, g);
|
||||
boost::add_edge(2, 4, g);
|
||||
|
||||
// breadth_first_visit skips initialization (no white-painting of all vertices).
|
||||
// Caller must provide a color map and queue.
|
||||
std::vector<boost::default_color_type> colors(num_vertices(g), boost::white_color);
|
||||
auto color_map = boost::make_iterator_property_map(colors.begin(), get(boost::vertex_index, g));
|
||||
boost::queue<Vertex> q;
|
||||
|
||||
std::cout << "BFS visit order: ";
|
||||
boost::breadth_first_visit(g, vertex(0, g), q, PrintVisitor{}, color_map);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct VertexProps { int id; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProps>;
|
||||
|
||||
struct DFSVisitor : boost::default_dfs_visitor {
|
||||
void discover_vertex(Graph::vertex_descriptor v, const Graph& g) const {
|
||||
std::cout << "discover " << g[v].id << "\n";
|
||||
}
|
||||
void finish_vertex(Graph::vertex_descriptor v, const Graph& g) const {
|
||||
std::cout << "finish " << g[v].id << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g{4};
|
||||
for (int i = 0; i < 4; ++i) { g[i].id = i; }
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 3, g);
|
||||
|
||||
boost::depth_first_search(g, boost::visitor(DFSVisitor{}));
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct VertexProps { int id; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProps>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
struct PrintVisitor : boost::default_dfs_visitor {
|
||||
void discover_vertex(Vertex v, const Graph& g) const {
|
||||
std::cout << g[v].id << " ";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g{5};
|
||||
for (int i = 0; i < 5; ++i) { g[i].id = i; }
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 3, g);
|
||||
boost::add_edge(2, 4, g);
|
||||
|
||||
// depth_first_visit explores from a single source without initializing colors.
|
||||
// Caller must provide a color map.
|
||||
std::vector<boost::default_color_type> colors(num_vertices(g), boost::white_color);
|
||||
auto color_map = boost::make_iterator_property_map(colors.begin(), get(boost::vertex_index, g));
|
||||
|
||||
std::cout << "DFS visit order: ";
|
||||
boost::depth_first_visit(g, vertex(0, g), PrintVisitor{}, color_map);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/undirected_dfs.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct VertexProps { int id; };
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, VertexProps>;
|
||||
using Edge = boost::graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
struct Visitor : boost::default_dfs_visitor {
|
||||
void discover_vertex(Graph::vertex_descriptor v, const Graph& g) const {
|
||||
std::cout << "discover " << g[v].id << "\n";
|
||||
}
|
||||
void finish_vertex(Graph::vertex_descriptor v, const Graph& g) const {
|
||||
std::cout << "finish " << g[v].id << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Graph g{4};
|
||||
for (int i = 0; i < 4; ++i) { g[i].id = i; }
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 3, g);
|
||||
|
||||
using ColorMap = std::map<Graph::vertex_descriptor, boost::default_color_type>;
|
||||
using EdgeColorMap = std::map<Edge, boost::default_color_type>;
|
||||
ColorMap vcmap;
|
||||
EdgeColorMap ecmap;
|
||||
boost::undirected_dfs(g, Visitor{},
|
||||
boost::make_assoc_property_map(vcmap),
|
||||
boost::make_assoc_property_map(ecmap));
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/bc_clustering.hpp>
|
||||
#include <boost/graph/connected_components.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
no_property, property<edge_index_t, int>>;
|
||||
|
||||
int main() {
|
||||
Graph g(6);
|
||||
int idx = 0;
|
||||
auto ae = [&](int u, int v) { add_edge(u, v, {idx++}, g); };
|
||||
ae(0,1); ae(1,2); ae(0,2); // cluster A
|
||||
ae(3,4); ae(4,5); ae(3,5); // cluster B
|
||||
ae(2,3); // bridge
|
||||
|
||||
betweenness_centrality_clustering(g, bc_clustering_threshold<double>(1.0, g, false));
|
||||
|
||||
std::vector<int> comp(num_vertices(g));
|
||||
int nc = connected_components(g, &comp[0]);
|
||||
std::cout << "Clusters: " << nc << "\n";
|
||||
for (std::size_t v = 0; v < comp.size(); ++v) {
|
||||
std::cout << " vertex " << v << " -> cluster " << comp[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/copy.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>;
|
||||
Graph g;
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(2, 3, g);
|
||||
|
||||
Graph g_copy;
|
||||
boost::copy_graph(g, g_copy);
|
||||
|
||||
std::cout << "Original: " << num_vertices(g) << " vertices, "
|
||||
<< num_edges(g) << " edges\n";
|
||||
std::cout << "Copy: " << num_vertices(g_copy) << " vertices, "
|
||||
<< num_edges(g_copy) << " edges\n";
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/graph_stats.hpp>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>;
|
||||
|
||||
int main() {
|
||||
Graph g(4);
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(0, 1, g); // duplicate edge
|
||||
|
||||
unsigned long dups = boost::graph::num_dup_edges(g);
|
||||
std::cout << "Duplicate edges: " << dups << "\n";
|
||||
|
||||
auto dist = boost::graph::degree_dist(g);
|
||||
std::cout << "Degree distribution:\n";
|
||||
for (auto& p : dist) {
|
||||
std::cout << " degree " << p.first << ": " << p.second << " vertices\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/dominator_tree.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
Graph g(6);
|
||||
// CFG-like: 0 is entry
|
||||
boost::add_edge(0, 1, g); boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 3, g); boost::add_edge(2, 3, g);
|
||||
boost::add_edge(3, 4, g); boost::add_edge(4, 5, g);
|
||||
|
||||
std::vector<Vertex> dom(num_vertices(g), boost::graph_traits<Graph>::null_vertex());
|
||||
auto dom_map = boost::make_iterator_property_map(dom.begin(), get(boost::vertex_index, g));
|
||||
boost::lengauer_tarjan_dominator_tree(g, Vertex{0}, dom_map);
|
||||
|
||||
std::cout << "Immediate dominators (entry = 0):\n";
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
if (dom[v] != boost::graph_traits<Graph>::null_vertex())
|
||||
std::cout << " idom(" << v << ") = " << dom[v] << "\n";
|
||||
else
|
||||
std::cout << " idom(" << v << ") = none (entry)\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/loop_erased_random_walk.hpp>
|
||||
#include <boost/graph/random.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <random>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(1, 2, g);
|
||||
add_edge(2, 3, g);
|
||||
add_edge(3, 4, g);
|
||||
add_edge(1, 3, g); // shortcut
|
||||
|
||||
std::mt19937 gen(42);
|
||||
auto next_edge = [&](Vertex v, const Graph& gr) {
|
||||
auto range = out_edges(v, gr);
|
||||
auto n = std::distance(range.first, range.second);
|
||||
std::advance(range.first, gen() % n);
|
||||
return *range.first;
|
||||
};
|
||||
|
||||
std::vector<default_color_type> colors(num_vertices(g), white_color);
|
||||
colors[4] = black_color; // target
|
||||
|
||||
std::vector<Vertex> path;
|
||||
loop_erased_random_walk(g, vertex(0, g), next_edge,
|
||||
make_iterator_property_map(colors.begin(), get(vertex_index, g)),
|
||||
path);
|
||||
|
||||
std::cout << "Path from 0 to 4: ";
|
||||
for (auto v : path) { std::cout << v << " "; }
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/maximum_adjacency_search.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
// MAS requires edge_weight_t internal property
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS,
|
||||
no_property, property<edge_weight_t, int>>;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, 2, g);
|
||||
add_edge(0, 4, 3, g);
|
||||
add_edge(1, 2, 3, g);
|
||||
add_edge(1, 4, 2, g);
|
||||
add_edge(2, 3, 4, g);
|
||||
add_edge(3, 4, 1, g);
|
||||
|
||||
std::vector<int> weights(num_vertices(g));
|
||||
auto weight_map = make_iterator_property_map(
|
||||
weights.begin(), get(vertex_index, g));
|
||||
|
||||
maximum_adjacency_search(g,
|
||||
boost::weight_map(get(edge_weight, g)));
|
||||
|
||||
std::cout << "Maximum adjacency search completed\n";
|
||||
std::cout << "Last vertex visited has highest connectivity\n";
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/metric_tsp_approx.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS, no_property,
|
||||
property<edge_weight_t, double>>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
const int N = 4;
|
||||
Graph g(N);
|
||||
double w[][4] = {{0,10,15,20},{10,0,35,25},{15,35,0,30},{20,25,30,0}};
|
||||
for (int i = 0; i < N; ++i)
|
||||
for (int j = i + 1; j < N; ++j)
|
||||
add_edge(i, j, {w[i][j]}, g);
|
||||
|
||||
std::vector<Vertex> tour;
|
||||
metric_tsp_approx_tour(g, std::back_inserter(tour));
|
||||
|
||||
std::cout << "TSP tour:";
|
||||
for (auto v : tour) { std::cout << " " << v; }
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/neighbor_bfs.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct print_visitor : public boost::neighbor_bfs_visitor<> {
|
||||
template <typename Vertex, typename Graph>
|
||||
void discover_vertex(Vertex v, const Graph&) const {
|
||||
std::cout << v << " ";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, bidirectionalS>;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(2, 1, g);
|
||||
add_edge(3, 0, g);
|
||||
add_edge(1, 4, g);
|
||||
|
||||
std::cout << "Neighbor BFS from vertex 1: ";
|
||||
neighbor_breadth_first_search(g, vertex(1, g),
|
||||
visitor(print_visitor()));
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/smallest_last_ordering.hpp>
|
||||
#include <boost/property_map/shared_array_property_map.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
int main() {
|
||||
Graph g(5);
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(0, 2, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(2, 3, g);
|
||||
boost::add_edge(3, 4, g);
|
||||
|
||||
auto order = boost::smallest_last_vertex_ordering(g);
|
||||
std::cout << "Smallest-last ordering:\n";
|
||||
for (std::size_t i = 0; i < order.size(); ++i) {
|
||||
std::cout << " position " << i << ": vertex " << order[i] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/transitive_closure.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>;
|
||||
Graph g;
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(2, 3, g);
|
||||
|
||||
Graph tc;
|
||||
boost::transitive_closure(g, tc);
|
||||
|
||||
std::cout << "Transitive closure edges:\n";
|
||||
for (auto ep = edges(tc); ep.first != ep.second; ++ep.first) {
|
||||
std::cout << " " << source(*ep.first, tc) << " -> " << target(*ep.first, tc) << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/transitive_reduction.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>;
|
||||
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
|
||||
Graph g(4);
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(0, 2, g); // redundant: 0->1->2
|
||||
boost::add_edge(2, 3, g);
|
||||
boost::add_edge(0, 3, g); // redundant: 0->1->2->3
|
||||
|
||||
std::cout << "Before (" << num_edges(g) << " edges):";
|
||||
for (auto ep = edges(g); ep.first != ep.second; ++ep.first)
|
||||
std::cout << " " << source(*ep.first, g) << "->" << target(*ep.first, g);
|
||||
std::cout << "\n";
|
||||
|
||||
Graph tr;
|
||||
std::vector<Vertex> g_to_tr(num_vertices(g));
|
||||
boost::transitive_reduction(g, tr,
|
||||
boost::make_iterator_property_map(g_to_tr.begin(), get(boost::vertex_index, g)),
|
||||
get(boost::vertex_index, g));
|
||||
|
||||
std::cout << "After (" << num_edges(tr) << " edges):";
|
||||
for (auto ep = edges(tr); ep.first != ep.second; ++ep.first)
|
||||
std::cout << " " << source(*ep.first, tr) << "->" << target(*ep.first, tr);
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/transpose_graph.hpp>
|
||||
|
||||
int main() {
|
||||
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS>;
|
||||
Graph g;
|
||||
boost::add_edge(0, 1, g);
|
||||
boost::add_edge(1, 2, g);
|
||||
boost::add_edge(2, 0, g);
|
||||
|
||||
std::cout << "Original edges: ";
|
||||
for (auto ep = edges(g); ep.first != ep.second; ++ep.first) {
|
||||
std::cout << source(*ep.first, g) << "->" << target(*ep.first, g) << " ";
|
||||
}
|
||||
|
||||
Graph gt;
|
||||
boost::transpose_graph(g, gt);
|
||||
|
||||
std::cout << "\nTransposed edges: ";
|
||||
for (auto ep = edges(gt); ep.first != ep.second; ++ep.first) {
|
||||
std::cout << source(*ep.first, gt) << "->" << target(*ep.first, gt) << " ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <boost/pending/disjoint_sets.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
const int N = 6;
|
||||
std::vector<int> rank(N, 0);
|
||||
std::vector<int> parent(N);
|
||||
|
||||
boost::disjoint_sets<int*, int*> ds(rank.data(), parent.data());
|
||||
|
||||
// Make each element its own set
|
||||
for (int i = 0; i < N; ++i) {
|
||||
ds.make_set(i);
|
||||
}
|
||||
|
||||
// Union some sets: {0,1,2} and {3,4}
|
||||
ds.union_set(0, 1);
|
||||
ds.union_set(1, 2);
|
||||
ds.union_set(3, 4);
|
||||
|
||||
// Find representatives
|
||||
for (int i = 0; i < N; ++i) {
|
||||
std::cout << "find(" << i << ") = " << ds.find_set(i) << "\n";
|
||||
}
|
||||
|
||||
// Check connectivity
|
||||
std::cout << "0 and 2 same set? " << (ds.find_set(0) == ds.find_set(2)) << "\n";
|
||||
std::cout << "0 and 5 same set? " << (ds.find_set(0) == ds.find_set(5)) << "\n";
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/topological_sort.hpp>
|
||||
#include <boost/graph/exception.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
|
||||
Graph g(3);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(1, 2, g);
|
||||
add_edge(2, 0, g); // creates a cycle
|
||||
|
||||
std::vector<int> order;
|
||||
try {
|
||||
topological_sort(g, std::back_inserter(order));
|
||||
} catch (const not_a_dag& e) {
|
||||
std::cout << "Exception: " << e.what() << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/graph_utility.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
|
||||
Graph g(4);
|
||||
auto e = add_edge(1, 3, g).first;
|
||||
|
||||
// incident: get both endpoints of an edge
|
||||
auto endpoints = incident(e, g);
|
||||
std::cout << "incident(" << source(e, g) << "->" << target(e, g) << ") = ("
|
||||
<< endpoints.first << ", " << endpoints.second << ")\n";
|
||||
|
||||
// opposite: given one endpoint, get the other
|
||||
auto v = opposite(e, vertex(1, g), g);
|
||||
std::cout << "opposite(e, 1) = " << v << "\n";
|
||||
|
||||
v = opposite(e, vertex(3, g), g);
|
||||
std::cout << "opposite(e, 3) = " << v << "\n";
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/astar_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
struct Road { double km; };
|
||||
|
||||
// Heuristic: straight-line distance (here just returns 0 for simplicity)
|
||||
struct zero_heuristic : public boost::astar_heuristic<
|
||||
boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
|
||||
boost::no_property, Road>, double>
|
||||
{
|
||||
double operator()(unsigned long) const { return 0.0; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property, Road>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g(4);
|
||||
add_edge(0, 1, Road{1.0}, g);
|
||||
add_edge(1, 2, Road{2.0}, g);
|
||||
add_edge(0, 2, Road{5.0}, g);
|
||||
add_edge(2, 3, Road{1.0}, g);
|
||||
|
||||
std::vector<Vertex> pred(num_vertices(g));
|
||||
std::vector<double> dist(num_vertices(g),
|
||||
(std::numeric_limits<double>::max)());
|
||||
auto index = get(vertex_index, g);
|
||||
auto pred_map = make_iterator_property_map(pred.begin(), index);
|
||||
auto dist_map = make_iterator_property_map(dist.begin(), index);
|
||||
|
||||
auto vis = make_astar_visitor(
|
||||
record_predecessors(pred_map, on_edge_relaxed())
|
||||
);
|
||||
|
||||
astar_search(g, vertex(0, g), zero_heuristic(),
|
||||
visitor(vis).
|
||||
weight_map(get(&Road::km, g)).
|
||||
distance_map(dist_map).
|
||||
predecessor_map(pred_map));
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v
|
||||
<< " dist=" << dist[v]
|
||||
<< " pred=" << pred[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/bellman_ford_shortest_paths.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
struct Road { double km; };
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property, Road>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g(4);
|
||||
add_edge(0, 1, Road{1.0}, g);
|
||||
add_edge(1, 2, Road{-2.0}, g);
|
||||
add_edge(0, 2, Road{4.0}, g);
|
||||
add_edge(2, 3, Road{3.0}, g);
|
||||
|
||||
std::vector<Vertex> pred(num_vertices(g));
|
||||
std::vector<double> dist(num_vertices(g),
|
||||
(std::numeric_limits<double>::max)());
|
||||
dist[0] = 0.0;
|
||||
auto index = get(vertex_index, g);
|
||||
auto pred_map = make_iterator_property_map(pred.begin(), index);
|
||||
auto dist_map = make_iterator_property_map(dist.begin(), index);
|
||||
|
||||
auto vis = make_bellman_visitor(
|
||||
record_predecessors(pred_map, on_edge_relaxed())
|
||||
);
|
||||
|
||||
bellman_ford_shortest_paths(g, num_vertices(g),
|
||||
get(&Road::km, g), pred_map, dist_map,
|
||||
std::plus<double>(), std::less<double>(), vis);
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v
|
||||
<< " dist=" << dist[v]
|
||||
<< " pred=" << pred[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g(6);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
add_edge(2, 4, g);
|
||||
add_edge(3, 5, g);
|
||||
|
||||
std::vector<Vertex> pred(num_vertices(g), 0);
|
||||
pred[0] = 0;
|
||||
std::vector<int> dist(num_vertices(g), 0);
|
||||
|
||||
auto vis = make_bfs_visitor(
|
||||
std::make_pair(
|
||||
record_predecessors(pred.data(), on_tree_edge()),
|
||||
record_distances(dist.data(), on_tree_edge())
|
||||
)
|
||||
);
|
||||
breadth_first_search(g, vertex(0, g), visitor(vis));
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v
|
||||
<< " pred=" << pred[v]
|
||||
<< " dist=" << dist[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// Inherit from default_bfs_visitor to get empty defaults for all events.
|
||||
// Override only the events you care about.
|
||||
struct my_visitor : public boost::default_bfs_visitor {
|
||||
template <typename Vertex, typename Graph>
|
||||
void discover_vertex(Vertex v, const Graph&) const {
|
||||
std::cout << " discovered " << v << "\n";
|
||||
}
|
||||
|
||||
template <typename Edge, typename Graph>
|
||||
void tree_edge(Edge e, const Graph& g) const {
|
||||
std::cout << " tree edge " << source(e, g)
|
||||
<< " -> " << target(e, g) << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
add_edge(2, 4, g);
|
||||
|
||||
std::cout << "BFS from vertex 0:\n";
|
||||
breadth_first_search(g, vertex(0, g), visitor(my_visitor()));
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
add_edge(3, 4, g);
|
||||
add_edge(4, 0, g); // back edge
|
||||
|
||||
std::vector<int> dtime(num_vertices(g));
|
||||
std::vector<int> ftime(num_vertices(g));
|
||||
int t = 0;
|
||||
|
||||
auto vis = make_dfs_visitor(
|
||||
std::make_pair(
|
||||
stamp_times(dtime.data(), t, on_discover_vertex()),
|
||||
stamp_times(ftime.data(), t, on_finish_vertex())
|
||||
)
|
||||
);
|
||||
depth_first_search(g, visitor(vis));
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v
|
||||
<< " discover=" << dtime[v]
|
||||
<< " finish=" << ftime[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/dijkstra_shortest_paths.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
struct Road { double km; };
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property, Road>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, Road{1.0}, g);
|
||||
add_edge(0, 2, Road{4.0}, g);
|
||||
add_edge(1, 2, Road{2.0}, g);
|
||||
add_edge(1, 3, Road{6.0}, g);
|
||||
add_edge(2, 3, Road{3.0}, g);
|
||||
add_edge(3, 4, Road{1.0}, g);
|
||||
|
||||
std::vector<Vertex> pred(num_vertices(g));
|
||||
std::vector<double> dist(num_vertices(g));
|
||||
auto weight = get(&Road::km, g);
|
||||
auto index = get(vertex_index, g);
|
||||
auto pred_map = make_iterator_property_map(pred.begin(), index);
|
||||
auto dist_map = make_iterator_property_map(dist.begin(), index);
|
||||
|
||||
auto vis = make_dijkstra_visitor(
|
||||
record_predecessors(pred_map, on_edge_relaxed())
|
||||
);
|
||||
|
||||
dijkstra_shortest_paths(g, vertex(0, g),
|
||||
pred_map, dist_map, weight, index,
|
||||
std::less<double>(), std::plus<double>(),
|
||||
(std::numeric_limits<double>::max)(), 0.0,
|
||||
vis);
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v
|
||||
<< " dist=" << dist[v]
|
||||
<< " pred=" << pred[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
add_edge(3, 4, g);
|
||||
|
||||
std::vector<int> dist(num_vertices(g), 0);
|
||||
auto vis = make_bfs_visitor(
|
||||
record_distances(dist.data(), on_tree_edge())
|
||||
);
|
||||
breadth_first_search(g, vertex(0, g), visitor(vis));
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v << " distance=" << dist[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
|
||||
// Record the incoming edge for each vertex
|
||||
std::vector<Edge> pred_edge(num_vertices(g));
|
||||
auto vis = make_bfs_visitor(
|
||||
record_edge_predecessors(pred_edge.data(), on_tree_edge())
|
||||
);
|
||||
breadth_first_search(g, vertex(0, g), visitor(vis));
|
||||
|
||||
for (std::size_t v = 1; v < num_vertices(g); ++v) {
|
||||
Edge e = pred_edge[v];
|
||||
std::cout << "vertex " << v << " arrived via edge "
|
||||
<< source(e, g) << " -> " << target(e, g) << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
Graph g(6);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
add_edge(2, 4, g);
|
||||
add_edge(3, 5, g);
|
||||
|
||||
// Record predecessors during BFS
|
||||
std::vector<Vertex> pred(num_vertices(g), 0);
|
||||
pred[0] = 0; // root is its own predecessor
|
||||
|
||||
auto vis = make_bfs_visitor(
|
||||
record_predecessors(pred.data(), on_tree_edge())
|
||||
);
|
||||
breadth_first_search(g, vertex(0, g), visitor(vis));
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v << " predecessor=" << pred[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS,
|
||||
no_property, property<edge_index_t, int>>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
Graph g(4);
|
||||
add_edge(0, 1, 0, g);
|
||||
add_edge(1, 2, 1, g);
|
||||
add_edge(2, 0, 2, g); // creates a back edge
|
||||
add_edge(1, 3, 3, g);
|
||||
|
||||
// Mark back edges with true using property_put
|
||||
std::vector<bool> is_back(num_edges(g), false);
|
||||
auto edge_id = get(edge_index, g);
|
||||
auto back_map = make_iterator_property_map(is_back.begin(), edge_id);
|
||||
|
||||
auto vis = make_dfs_visitor(
|
||||
put_property(back_map, true, on_back_edge())
|
||||
);
|
||||
depth_first_search(g, visitor(vis));
|
||||
|
||||
for (auto ei = edges(g).first; ei != edges(g).second; ++ei) {
|
||||
Edge e = *ei;
|
||||
std::cout << source(e, g) << " -> " << target(e, g);
|
||||
if (is_back[get(edge_id, e)]) {
|
||||
std::cout << " [back edge]";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
Graph g(5);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
add_edge(2, 4, g);
|
||||
|
||||
// Print vertex indices as they are discovered
|
||||
std::ostream_iterator<int> out(std::cout, " ");
|
||||
auto vis = make_bfs_visitor(
|
||||
write_property(get(vertex_index, g), out, on_discover_vertex())
|
||||
);
|
||||
|
||||
std::cout << "BFS discovery order: ";
|
||||
breadth_first_search(g, vertex(0, g), visitor(vis));
|
||||
std::cout << "\n";
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS>;
|
||||
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
|
||||
std::vector<int> dtime(num_vertices(g));
|
||||
std::vector<int> ftime(num_vertices(g));
|
||||
int t = 0;
|
||||
|
||||
auto vis = make_dfs_visitor(
|
||||
std::make_pair(
|
||||
stamp_times(dtime.data(), t, on_discover_vertex()),
|
||||
stamp_times(ftime.data(), t, on_finish_vertex())
|
||||
)
|
||||
);
|
||||
depth_first_search(g, visitor(vis));
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v
|
||||
<< " discover=" << dtime[v]
|
||||
<< " finish=" << ftime[v] << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/graph/visitors.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, undirectedS>;
|
||||
|
||||
Graph g(6);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(0, 2, g);
|
||||
add_edge(1, 3, g);
|
||||
add_edge(2, 4, g);
|
||||
add_edge(3, 5, g);
|
||||
|
||||
// Record predecessors and distances using pre-built event visitors.
|
||||
// No need to write a visitor class.
|
||||
std::vector<int> pred(num_vertices(g), -1);
|
||||
std::vector<int> dist(num_vertices(g), 0);
|
||||
|
||||
auto vis = make_bfs_visitor(
|
||||
std::make_pair(
|
||||
record_predecessors(pred.data(), on_tree_edge()),
|
||||
record_distances(dist.data(), on_tree_edge())
|
||||
)
|
||||
);
|
||||
|
||||
breadth_first_search(g, vertex(0, g), visitor(vis));
|
||||
|
||||
for (std::size_t v = 0; v < num_vertices(g); ++v) {
|
||||
std::cout << "vertex " << v
|
||||
<< " predecessor=" << pred[v]
|
||||
<< " distance=" << dist[v] << "\n";
|
||||
}
|
||||
}
|
||||
+138
-108
@@ -16,91 +16,128 @@
|
||||
** xref:generators/ssca_generator.adoc[SSCA (Clustered Benchmark)]
|
||||
* Algorithms
|
||||
** Traversal
|
||||
*** xref:algorithms/breadth_first_search.adoc[Breadth First Search]
|
||||
*** xref:algorithms/breadth_first_visit.adoc[Breadth First Visit]
|
||||
*** xref:algorithms/depth_first_search.adoc[Depth First Search]
|
||||
*** xref:algorithms/depth_first_visit.adoc[Depth First Visit]
|
||||
*** xref:algorithms/undirected_dfs.adoc[Undirected DFS]
|
||||
*** xref:algorithms/traversal/traversal_overview.adoc[Overview]
|
||||
*** xref:algorithms/traversal/breadth_first_search.adoc[Breadth First Search]
|
||||
*** xref:algorithms/traversal/breadth_first_visit.adoc[Breadth First Visit]
|
||||
*** xref:algorithms/traversal/depth_first_search.adoc[Depth First Search]
|
||||
*** xref:algorithms/traversal/depth_first_visit.adoc[Depth First Visit]
|
||||
*** xref:algorithms/traversal/undirected_dfs.adoc[Undirected DFS]
|
||||
** Shortest Paths
|
||||
*** xref:algorithms/dijkstra_shortest_paths.adoc[Dijkstra Shortest Paths]
|
||||
*** xref:algorithms/dijkstra_shortest_paths_no_color_map.adoc[Dijkstra Shortest Paths No Color Map]
|
||||
*** xref:algorithms/bellman_ford_shortest.adoc[Bellman-Ford Shortest Paths]
|
||||
*** xref:algorithms/dag_shortest_paths.adoc[DAG Shortest Paths]
|
||||
*** xref:algorithms/johnson_all_pairs_shortest.adoc[Johnson All Pairs Shortest Paths]
|
||||
*** xref:algorithms/floyd_warshall_shortest.adoc[Floyd-Warshall All Pairs Shortest Paths]
|
||||
*** xref:algorithms/r_c_shortest_paths.adoc[Resource-Constrained Shortest Paths]
|
||||
*** xref:algorithms/astar_search.adoc[A* Search]
|
||||
*** xref:algorithms/shortest_paths/shortest_paths_overview.adoc[Overview]
|
||||
*** xref:algorithms/shortest_paths/dijkstra_shortest_paths.adoc[Dijkstra Shortest Paths]
|
||||
*** xref:algorithms/shortest_paths/dijkstra_shortest_paths_no_color_map.adoc[Dijkstra Shortest Paths No Color Map]
|
||||
*** xref:algorithms/shortest_paths/bellman_ford_shortest.adoc[Bellman-Ford Shortest Paths]
|
||||
*** xref:algorithms/shortest_paths/dag_shortest_paths.adoc[DAG Shortest Paths]
|
||||
*** xref:algorithms/shortest_paths/johnson_all_pairs_shortest.adoc[Johnson All Pairs Shortest Paths]
|
||||
*** xref:algorithms/shortest_paths/floyd_warshall_shortest.adoc[Floyd-Warshall All Pairs Shortest Paths]
|
||||
*** xref:algorithms/shortest_paths/r_c_shortest_paths.adoc[Resource-Constrained Shortest Paths]
|
||||
*** xref:algorithms/shortest_paths/astar_search.adoc[A* Search]
|
||||
** Spanning Trees
|
||||
*** xref:algorithms/kruskal_min_spanning_tree.adoc[Kruskal Minimum Spanning Tree]
|
||||
*** xref:algorithms/prim_minimum_spanning_tree.adoc[Prim Minimum Spanning Tree]
|
||||
*** xref:algorithms/random_spanning_tree.adoc[Random Spanning Tree]
|
||||
*** xref:algorithms/two_graphs_common_spanning_trees.adoc[Two Graphs Common Spanning Trees]
|
||||
*** xref:algorithms/spanning_trees/spanning_trees_overview.adoc[Overview]
|
||||
*** xref:algorithms/spanning_trees/kruskal_min_spanning_tree.adoc[Kruskal Minimum Spanning Tree]
|
||||
*** xref:algorithms/spanning_trees/prim_minimum_spanning_tree.adoc[Prim Minimum Spanning Tree]
|
||||
*** xref:algorithms/spanning_trees/random_spanning_tree.adoc[Random Spanning Tree]
|
||||
*** xref:algorithms/spanning_trees/two_graphs_common_spanning_trees.adoc[Two Graphs Common Spanning Trees]
|
||||
** Connected Components
|
||||
*** xref:algorithms/connected_components.adoc[Connected Components]
|
||||
*** xref:algorithms/strong_components.adoc[Strong Components]
|
||||
*** xref:algorithms/biconnected_components.adoc[Biconnected Components]
|
||||
*** xref:algorithms/incremental_components.adoc[Incremental Components]
|
||||
*** xref:algorithms/connected_components/connected_components_overview.adoc[Overview]
|
||||
*** xref:algorithms/connected_components/connected_components.adoc[Connected Components]
|
||||
*** xref:algorithms/connected_components/strong_components.adoc[Strong Components]
|
||||
*** xref:algorithms/connected_components/biconnected_components.adoc[Biconnected Components]
|
||||
*** xref:algorithms/connected_components/incremental_components.adoc[Incremental Components]
|
||||
** Network Flow
|
||||
*** xref:algorithms/edmonds_karp_max_flow.adoc[Edmonds-Karp Max Flow]
|
||||
*** xref:algorithms/push_relabel_max_flow.adoc[Push-Relabel Max Flow]
|
||||
*** xref:algorithms/boykov_kolmogorov_max_flow.adoc[Boykov-Kolmogorov Max Flow]
|
||||
*** xref:algorithms/stoer_wagner_min_cut.adoc[Stoer-Wagner Min Cut]
|
||||
*** xref:algorithms/cycle_canceling.adoc[Cycle Canceling]
|
||||
*** xref:algorithms/successive_shortest_path_nonnegative_weights.adoc[Successive Shortest Path Nonnegative Weights]
|
||||
*** xref:algorithms/find_flow_cost.adoc[Find Flow Cost]
|
||||
*** xref:algorithms/maximum_matching.adoc[Edmonds Maximum Cardinality Matching]
|
||||
*** xref:algorithms/maximum_weighted_matching.adoc[Maximum Weighted Matching]
|
||||
*** xref:algorithms/network_flow/network_flow_overview.adoc[Overview]
|
||||
*** xref:algorithms/network_flow/edmonds_karp_max_flow.adoc[Edmonds-Karp Max Flow]
|
||||
*** xref:algorithms/network_flow/push_relabel_max_flow.adoc[Push-Relabel Max Flow]
|
||||
*** xref:algorithms/network_flow/boykov_kolmogorov_max_flow.adoc[Boykov-Kolmogorov Max Flow]
|
||||
*** xref:algorithms/network_flow/stoer_wagner_min_cut.adoc[Stoer-Wagner Min Cut]
|
||||
*** xref:algorithms/network_flow/cycle_canceling.adoc[Cycle Canceling]
|
||||
*** xref:algorithms/network_flow/successive_shortest_path_nonnegative_weights.adoc[Successive Shortest Path Nonnegative Weights]
|
||||
*** xref:algorithms/network_flow/find_flow_cost.adoc[Find Flow Cost]
|
||||
*** xref:algorithms/network_flow/maximum_matching.adoc[Edmonds Maximum Cardinality Matching]
|
||||
*** xref:algorithms/network_flow/maximum_weighted_matching.adoc[Maximum Weighted Matching]
|
||||
** Topological Sort
|
||||
*** xref:algorithms/topological_sort.adoc[Topological Sort]
|
||||
*** xref:algorithms/topological_sort/topological_sort_overview.adoc[Overview]
|
||||
*** xref:algorithms/topological_sort/topological_sort.adoc[Topological Sort]
|
||||
** Graph Coloring
|
||||
*** xref:algorithms/sequential_vertex_coloring.adoc[Sequential Vertex Coloring]
|
||||
*** xref:algorithms/edge_coloring.adoc[Edge Coloring]
|
||||
*** xref:algorithms/is_bipartite.adoc[Is Bipartite]
|
||||
*** xref:algorithms/find_odd_cycle.adoc[Find Odd Cycle]
|
||||
*** xref:algorithms/coloring/coloring_overview.adoc[Overview]
|
||||
*** xref:algorithms/coloring/sequential_vertex_coloring.adoc[Sequential Vertex Coloring]
|
||||
*** xref:algorithms/coloring/edge_coloring.adoc[Edge Coloring]
|
||||
*** xref:algorithms/coloring/is_bipartite.adoc[Is Bipartite]
|
||||
*** xref:algorithms/coloring/find_odd_cycle.adoc[Find Odd Cycle]
|
||||
** Connectivity
|
||||
*** xref:algorithms/connectivity/connectivity_overview.adoc[Overview]
|
||||
*** xref:algorithms/connectivity/edge_connectivity.adoc[Edge Connectivity]
|
||||
*** xref:algorithms/connectivity/st_connected.adoc[ST Connected]
|
||||
** Graph Metrics
|
||||
*** xref:algorithms/profile.adoc[Profile]
|
||||
*** xref:algorithms/wavefront.adoc[Wavefront]
|
||||
*** xref:algorithms/bandwidth.adoc[Bandwidth]
|
||||
*** xref:algorithms/betweenness_centrality.adoc[Brandes Betweenness Centrality]
|
||||
*** xref:algorithms/metrics/metrics_overview.adoc[Overview]
|
||||
*** xref:algorithms/metrics/page_rank.adoc[PageRank]
|
||||
*** xref:algorithms/metrics/betweenness_centrality.adoc[Brandes Betweenness Centrality]
|
||||
*** xref:algorithms/metrics/degree_centrality.adoc[Degree Centrality]
|
||||
*** xref:algorithms/metrics/closeness_centrality.adoc[Closeness Centrality]
|
||||
*** xref:algorithms/metrics/eccentricity.adoc[Eccentricity]
|
||||
*** xref:algorithms/metrics/geodesic_distance.adoc[Geodesic Distance]
|
||||
*** xref:algorithms/metrics/clustering_coefficient.adoc[Clustering Coefficient]
|
||||
*** xref:algorithms/metrics/core_numbers.adoc[Core Numbers]
|
||||
*** xref:algorithms/metrics/profile.adoc[Profile]
|
||||
*** xref:algorithms/metrics/wavefront.adoc[Wavefront]
|
||||
*** xref:algorithms/metrics/bandwidth.adoc[Bandwidth]
|
||||
** Graph Isomorphism
|
||||
*** xref:algorithms/isomorphism.adoc[Isomorphism]
|
||||
*** xref:algorithms/vf2_sub_graph_iso.adoc[VF2 Subgraph Isomorphism]
|
||||
*** xref:algorithms/mcgregor_common_subgraphs.adoc[McGregor Common Subgraphs]
|
||||
*** xref:algorithms/isomorphism/isomorphism_overview.adoc[Overview]
|
||||
*** xref:algorithms/isomorphism/isomorphism.adoc[Isomorphism]
|
||||
*** xref:algorithms/isomorphism/vf2_sub_graph_iso.adoc[VF2 Subgraph Isomorphism]
|
||||
*** xref:algorithms/isomorphism/mcgregor_common_subgraphs.adoc[McGregor Common Subgraphs]
|
||||
** Planar Graphs
|
||||
*** xref:algorithms/planar_graphs.adoc[Planar Graphs Overview]
|
||||
*** xref:algorithms/boyer_myrvold.adoc[Boyer-Myrvold Planarity Test]
|
||||
*** xref:algorithms/planar_face_traversal.adoc[Planar Face Traversal]
|
||||
*** xref:algorithms/planar_canonical_ordering.adoc[Planar Canonical Ordering]
|
||||
*** xref:algorithms/straight_line_drawing.adoc[Chrobak-Payne Straight Line Drawing]
|
||||
*** xref:algorithms/is_straight_line_drawing.adoc[Is Straight Line Drawing]
|
||||
*** xref:algorithms/is_kuratowski_subgraph.adoc[Is Kuratowski Subgraph]
|
||||
*** xref:algorithms/make_connected.adoc[Make Connected]
|
||||
*** xref:algorithms/make_biconnected_planar.adoc[Make Biconnected Planar]
|
||||
*** xref:algorithms/make_maximal_planar.adoc[Make Maximal Planar]
|
||||
*** xref:algorithms/planar/planar_graphs.adoc[Overview]
|
||||
*** xref:algorithms/planar/boyer_myrvold.adoc[Boyer-Myrvold Planarity Test]
|
||||
*** xref:algorithms/planar/planar_face_traversal.adoc[Planar Face Traversal]
|
||||
*** xref:algorithms/planar/planar_canonical_ordering.adoc[Planar Canonical Ordering]
|
||||
*** xref:algorithms/planar/straight_line_drawing.adoc[Chrobak-Payne Straight Line Drawing]
|
||||
*** xref:algorithms/planar/is_straight_line_drawing.adoc[Is Straight Line Drawing]
|
||||
*** xref:algorithms/planar/is_kuratowski_subgraph.adoc[Is Kuratowski Subgraph]
|
||||
*** xref:algorithms/planar/make_connected.adoc[Make Connected]
|
||||
*** xref:algorithms/planar/make_biconnected_planar.adoc[Make Biconnected Planar]
|
||||
*** xref:algorithms/planar/make_maximal_planar.adoc[Make Maximal Planar]
|
||||
** Layout
|
||||
*** xref:algorithms/topology.adoc[Topologies]
|
||||
*** xref:algorithms/random_layout.adoc[Random Graph Layout]
|
||||
*** xref:algorithms/circle_layout.adoc[Circle Layout]
|
||||
*** xref:algorithms/kamada_kawai_spring_layout.adoc[Kamada-Kawai Spring Layout]
|
||||
*** xref:algorithms/fruchterman_reingold.adoc[Fruchterman-Reingold Force Directed Layout]
|
||||
*** xref:algorithms/gursoy_atun_layout.adoc[Gürsoy-Atun Layout]
|
||||
*** xref:algorithms/layout/layout_overview.adoc[Overview]
|
||||
*** xref:algorithms/layout/topology.adoc[Topologies]
|
||||
*** xref:algorithms/layout/random_layout.adoc[Random Graph Layout]
|
||||
*** xref:algorithms/layout/circle_layout.adoc[Circle Layout]
|
||||
*** xref:algorithms/layout/kamada_kawai_spring_layout.adoc[Kamada-Kawai Spring Layout]
|
||||
*** xref:algorithms/layout/fruchterman_reingold.adoc[Fruchterman-Reingold Force Directed Layout]
|
||||
*** xref:algorithms/layout/gursoy_atun_layout.adoc[Gürsoy-Atun Layout]
|
||||
*** xref:auxiliary/layout_tolerance.adoc[Layout Tolerance]
|
||||
** Sparse Matrix Ordering
|
||||
*** xref:algorithms/cuthill_mckee_ordering.adoc[Cuthill-McKee Ordering]
|
||||
*** xref:algorithms/king_ordering.adoc[King Ordering]
|
||||
*** xref:algorithms/minimum_degree_ordering.adoc[Minimum Degree Ordering]
|
||||
*** xref:algorithms/sloan_ordering.adoc[Sloan Ordering]
|
||||
*** xref:algorithms/sloan_start_end_vertices.adoc[Sloan Start End Vertices]
|
||||
*** xref:algorithms/ordering/ordering_overview.adoc[Overview]
|
||||
*** xref:algorithms/ordering/cuthill_mckee_ordering.adoc[Cuthill-McKee Ordering]
|
||||
*** xref:algorithms/ordering/king_ordering.adoc[King Ordering]
|
||||
*** xref:algorithms/ordering/minimum_degree_ordering.adoc[Minimum Degree Ordering]
|
||||
*** xref:algorithms/ordering/sloan_ordering.adoc[Sloan Ordering]
|
||||
*** xref:algorithms/ordering/sloan_start_end_vertices.adoc[Sloan Start End Vertices]
|
||||
** Cycle Detection
|
||||
*** xref:algorithms/hawick_circuits.adoc[Hawick Circuits]
|
||||
*** xref:algorithms/howard_cycle_ratio.adoc[Cycle Ratio]
|
||||
*** xref:algorithms/cycle_detection/cycle_detection_overview.adoc[Overview]
|
||||
*** xref:algorithms/cycle_detection/hawick_circuits.adoc[Hawick Circuits]
|
||||
*** xref:algorithms/cycle_detection/tiernan_all_cycles.adoc[Tiernan All Cycles]
|
||||
*** xref:algorithms/cycle_detection/howard_cycle_ratio.adoc[Cycle Ratio]
|
||||
** Clique Detection
|
||||
*** xref:algorithms/clique_detection/clique_detection_overview.adoc[Overview]
|
||||
*** xref:algorithms/clique_detection/bron_kerbosch.adoc[Bron-Kerbosch All Cliques]
|
||||
** Utility
|
||||
*** xref:algorithms/copy_graph.adoc[Copy Graph]
|
||||
*** xref:algorithms/transpose_graph.adoc[Transpose Graph]
|
||||
*** xref:algorithms/transitive_closure.adoc[Transitive Closure]
|
||||
*** xref:algorithms/lengauer_tarjan_dominator.adoc[Lengauer-Tarjan Dominator Tree]
|
||||
*** xref:algorithms/metric_tsp_approx.adoc[Metric TSP Approximation]
|
||||
*** xref:algorithms/maximum_adjacency_search.adoc[Maximum Adjacency Search]
|
||||
*** xref:algorithms/bc_clustering.adoc[Betweenness Centrality Clustering]
|
||||
*** xref:algorithms/utility/utility_overview.adoc[Overview]
|
||||
*** xref:algorithms/utility/copy_graph.adoc[Copy Graph]
|
||||
*** xref:algorithms/utility/transpose_graph.adoc[Transpose Graph]
|
||||
*** xref:algorithms/utility/transitive_closure.adoc[Transitive Closure]
|
||||
*** xref:algorithms/utility/transitive_reduction.adoc[Transitive Reduction]
|
||||
*** xref:algorithms/utility/smallest_last_ordering.adoc[Smallest Last Ordering]
|
||||
*** xref:algorithms/utility/lengauer_tarjan_dominator.adoc[Lengauer-Tarjan Dominator Tree]
|
||||
*** xref:algorithms/utility/metric_tsp_approx.adoc[Metric TSP Approximation]
|
||||
*** xref:algorithms/utility/maximum_adjacency_search.adoc[Maximum Adjacency Search]
|
||||
*** xref:algorithms/utility/bc_clustering.adoc[Betweenness Centrality Clustering]
|
||||
*** xref:auxiliary/disjoint_sets.adoc[Disjoint Sets]
|
||||
*** xref:auxiliary/incident.adoc[Incident]
|
||||
*** xref:auxiliary/opposite.adoc[Opposite]
|
||||
*** xref:algorithms/utility/neighbor_bfs.adoc[Neighbor BFS]
|
||||
*** xref:algorithms/utility/loop_erased_random_walk.adoc[Loop-Erased Random Walk]
|
||||
*** xref:algorithms/utility/graph_stats.adoc[Graph Statistics]
|
||||
* Property Maps
|
||||
** xref:property_maps/overview.adoc[Overview]
|
||||
** xref:property_maps/bundled.adoc[Bundled Properties]
|
||||
@@ -124,9 +161,28 @@
|
||||
*** xref:concepts/PropertyGraph.adoc[Property Graph]
|
||||
*** xref:concepts/MutablePropertyGraph.adoc[Mutable Property Graph]
|
||||
*** xref:concepts/IteratorConstructibleGraph.adoc[Iterator Constructible Graph]
|
||||
** Visitors
|
||||
*** xref:visitors/overview.adoc[Overview]
|
||||
*** xref:visitors/visitor_concepts.adoc[Visitor Concepts]
|
||||
** Property and Value Types
|
||||
*** xref:auxiliary/ColorValue.adoc[Color Value]
|
||||
*** xref:auxiliary/Buffer.adoc[Buffer]
|
||||
*** xref:auxiliary/BasicMatrix.adoc[Basic Matrix]
|
||||
*** xref:auxiliary/Monoid.adoc[Monoid]
|
||||
*** xref:auxiliary/KeyedUpdatableQueue.adoc[Keyed Updatable Queue]
|
||||
*** xref:auxiliary/UpdatableQueue.adoc[Updatable Queue]
|
||||
*** xref:auxiliary/PlanarEmbedding.adoc[Planar Embedding]
|
||||
*** xref:auxiliary/PropertyTag.adoc[Property Tag]
|
||||
* Visitors
|
||||
** xref:visitors/overview.adoc[Overview]
|
||||
** Pre-built Event Visitors
|
||||
*** xref:visitors/predecessor_recorder.adoc[Predecessor Recorder]
|
||||
*** xref:visitors/distance_recorder.adoc[Distance Recorder]
|
||||
*** xref:visitors/time_stamper.adoc[Time Stamper]
|
||||
*** xref:visitors/property_put.adoc[Property Put]
|
||||
*** xref:visitors/property_writer.adoc[Property Writer]
|
||||
*** xref:visitors/edge_predecessor_recorder.adoc[Edge Predecessor Recorder]
|
||||
*** xref:visitors/null_visitor.adoc[Null Visitor]
|
||||
*** xref:visitors/tsp_tour_visitor.adoc[TSP Tour Visitor]
|
||||
*** xref:visitors/tsp_tour_len_visitor.adoc[TSP Tour Len Visitor]
|
||||
** Concepts
|
||||
*** xref:visitors/BFSVisitor.adoc[BFS Visitor]
|
||||
*** xref:visitors/DFSVisitor.adoc[DFS Visitor]
|
||||
*** xref:visitors/DijkstraVisitor.adoc[Dijkstra Visitor]
|
||||
@@ -137,33 +193,13 @@
|
||||
*** xref:visitors/PlanarFaceVisitor.adoc[Planar Face Visitor]
|
||||
*** xref:visitors/TSPTourVisitor.adoc[TSP Tour Visitor]
|
||||
*** xref:visitors/AddEdgeVisitor.adoc[Add Edge Visitor]
|
||||
** Property and Value Types
|
||||
*** xref:auxiliary/ColorValue.adoc[Color Value]
|
||||
*** xref:auxiliary/Buffer.adoc[Buffer]
|
||||
*** xref:auxiliary/BasicMatrix.adoc[Basic Matrix]
|
||||
*** xref:auxiliary/Monoid.adoc[Monoid]
|
||||
*** xref:auxiliary/KeyedUpdatableQueue.adoc[Keyed Updatable Queue]
|
||||
*** xref:auxiliary/UpdatableQueue.adoc[Updatable Queue]
|
||||
*** xref:auxiliary/PlanarEmbedding.adoc[Planar Embedding]
|
||||
*** xref:auxiliary/PropertyTag.adoc[Property Tag]
|
||||
* Visitor Implementations
|
||||
** Adaptors
|
||||
** Algorithm adaptors
|
||||
*** xref:visitors/EventVisitorList.adoc[Event Visitor List]
|
||||
*** xref:visitors/bfs_visitor.adoc[BFS Visitor]
|
||||
*** xref:visitors/dfs_visitor.adoc[DFS Visitor]
|
||||
*** xref:visitors/dijkstra_visitor.adoc[Dijkstra Visitor]
|
||||
*** xref:visitors/bellman_visitor.adoc[Bellman Visitor]
|
||||
*** xref:visitors/astar_visitor.adoc[A* Visitor]
|
||||
*** xref:visitors/null_visitor.adoc[Null Visitor]
|
||||
** Event Visitors
|
||||
*** xref:visitors/predecessor_recorder.adoc[Predecessor Recorder]
|
||||
*** xref:visitors/edge_predecessor_recorder.adoc[Edge Predecessor Recorder]
|
||||
*** xref:visitors/distance_recorder.adoc[Distance Recorder]
|
||||
*** xref:visitors/time_stamper.adoc[Time Stamper]
|
||||
*** xref:visitors/property_writer.adoc[Property Writer]
|
||||
*** xref:visitors/property_put.adoc[Property Put]
|
||||
*** xref:visitors/tsp_tour_visitor.adoc[TSP Tour Visitor]
|
||||
*** xref:visitors/tsp_tour_len_visitor.adoc[TSP Tour Len Visitor]
|
||||
*** xref:visitors/bfs_visitor.adoc[BFS Visitor Adaptor]
|
||||
*** xref:visitors/dfs_visitor.adoc[DFS Visitor Adaptor]
|
||||
*** xref:visitors/dijkstra_visitor.adoc[Dijkstra Visitor Adaptor]
|
||||
*** xref:visitors/bellman_visitor.adoc[Bellman-Ford Visitor Adaptor]
|
||||
*** xref:visitors/astar_visitor.adoc[A* Visitor Adaptor]
|
||||
* Graph I/O
|
||||
** xref:io/overview.adoc[Overview]
|
||||
** xref:io/graphviz.adoc[GraphViz (DOT)]
|
||||
@@ -189,13 +225,7 @@
|
||||
** xref:examples/kevin_bacon.adoc[Six Degrees of Kevin Bacon]
|
||||
** xref:examples/graph_coloring.adoc[Graph Coloring]
|
||||
** xref:examples/sparse_matrix_ordering.adoc[Sparse Matrix Ordering]
|
||||
* Auxiliary
|
||||
** xref:auxiliary/incident.adoc[Incident]
|
||||
** xref:auxiliary/opposite.adoc[Opposite]
|
||||
** xref:auxiliary/exception.adoc[Exceptions]
|
||||
** xref:auxiliary/disjoint_sets.adoc[Disjoint Sets]
|
||||
** xref:auxiliary/disjoint_sets_biblio.adoc[Disjoint Sets Bibliography]
|
||||
** xref:auxiliary/layout_tolerance.adoc[Layout Tolerance]
|
||||
* xref:auxiliary/exception.adoc[Exceptions]
|
||||
* Background
|
||||
** xref:overview/graph_theory_review.adoc[Graph Theory Review]
|
||||
** xref:auxiliary/bgl_named_params.adoc[Named Parameters]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user