是的。您可以使用带有边缘过滤器的过滤图形适配器。我有几个答案up on SO 展示了如何使用它,但会看看我是否可以根据您的 sn-p 创建一个有用的示例。
所以我做了一个独立的样本¹:Live On Coliru,
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/property_map/transform_value_property_map.hpp>
#include <boost/graph/random.hpp>
#include <boost/graph/graphviz.hpp>
#include <random>
using G = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
using V = G::vertex_descriptor;
using E = G::edge_descriptor;
using W = double;
int main(int argc, char** argv) {
G g;
auto seed = 9353; // fixed seed for demo
if (argc > 1) {
seed = atol(argv[1]);
std::cerr << "Using PRNG seed: " << seed << "\n";
}
std::mt19937 engine(seed);
auto weight_gen = bind(std::uniform_real_distribution<W>(0, 1), engine);
boost::generate_random_graph(g, 10, 6, engine);
std::map<E, W> weights;
for (auto e : boost::make_iterator_range(edges(g)))
weights[e] = weight_gen();
std::vector<int> components(boost::num_vertices(g));
auto cmap = boost::make_iterator_vertex_map(components.data());
int n = boost::connected_components(g, cmap);
std::cerr << n << " components\n";
boost::dynamic_properties dp;
dp.property("node_id", get(boost::vertex_index, g));
dp.property("style", boost::make_constant_property<V>(std::string("filled")));
dp.property("color",
boost::make_transform_value_property_map(
[](int componentid) {
static std::array cc{"red", "green", "yellow",
"blue", "brown", "black",
"orange", "purple"};
return cc[componentid % cc.size()];
},
cmap));
dp.property("label", boost::make_assoc_property_map(weights));
boost::write_graphviz_dp(std::cout, g, dp);
}
生成伪随机图:
让我们为其添加一些过滤:
Live On Coliru
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/property_map/transform_value_property_map.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/graph/random.hpp>
#include <boost/graph/graphviz.hpp>
#include <random>
using G = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
using V = G::vertex_descriptor;
using E = G::edge_descriptor;
using W = double;
struct NonRemoved {
std::set<E> const* _ref;
bool operator()(E e) const { return not _ref->contains(e); }
};
int main(int argc, char** argv)
{
G g;
auto seed = 9353; // fixed seed for demo
if (argc > 1) {
seed = atol(argv[1]);
std::cerr << "Using PRNG seed: " << seed << "\n";
}
std::mt19937 engine(seed);
auto weight_gen = bind(std::uniform_real_distribution<W>(0, 1), engine);
boost::generate_random_graph(g, 10, 6, engine);
std::map<E, W> weights;
for (auto e : boost::make_iterator_range(edges(g)))
weights[e] = weight_gen();
std::vector<int> components(boost::num_vertices(g));
auto cmap = boost::make_iterator_vertex_map(components.data());
auto random_edges = [&g] {
auto [f,l] = edges(g);
std::deque<E> re(f,l);
std::random_shuffle(begin(re), end(re));
return re;
}();
std::set<E> removed;
NonRemoved predicate{&removed};
boost::filtered_graph<G, NonRemoved, boost::keep_all> f(g, predicate, {});
do {
int n = boost::connected_components(f, cmap);
std::cerr << n << " components\n";
boost::dynamic_properties dp;
dp.property("node_id", get(boost::vertex_index, f));
dp.property("style", boost::make_constant_property<V>(std::string("filled")));
dp.property("color",
boost::make_transform_value_property_map(
[](int componentid) {
static std::array cc{"red", "green", "yellow",
"blue", "brown", "black",
"orange", "purple"};
return cc[componentid % cc.size()];
},
cmap));
dp.property("color",
boost::make_function_property_map<E>([&removed](E e) {
return removed.contains(e) ? "red" : "blue";
}));
dp.property("label",
boost::make_function_property_map<E>([&removed, &weights](E e) {
if (removed.contains(e))
return std::string("REMOVED");
return std::to_string(weights.at(e));
}));
std::ofstream ofs("graph_" + std::to_string(random_edges.size()) + ".dot");
boost::write_graphviz_dp(ofs, f, dp);
removed.insert(random_edges.front());
random_edges.pop_front();
} while (not random_edges.empty());
}
现在编写一系列graph_XXX.dot 图表,显示为:
¹(更改vertex container selector to vecS for simplicity)