나는 최근에 같은 요구 사항을 가지고있었습니다. 필자는 코드에서 데이터베이스 엔터티를 모델링하고 종속성을 매핑하여 올바른 순서로 엔터티를 만들고 파괴 할 수있는 방법이 필요했습니다.
boost::graph
라이브러리가있는 솔루션을 발견했습니다. 나는 당신이 올바른 방향으로 시작할 수 있기를 희망하면서 (실제 코드의) 스 니펫을 포함 시켰습니다. 아래의 코드에서
이 함수
create_order
들이 작성해야합니다 순서로 개체의 벡터를 산출하고,
drop_order
반대를하지 (가장 의존하는 기업이 먼저 온다) :
using edge = std::pair<std::size_t, std::size_t>;
using edge_vector = std::vector<edge>;
using graph_properties = boost::property<
boost::vertex_color_t,
boost::default_color_type
>;
typedef boost::adjacency_list<boost::vecS, boost::vecS,
boost::bidirectionalS,
graph_properties
> Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
struct cycle_detector : public boost::dfs_visitor<>
{
cycle_detector(edge_vector& back_edges)
: _back_edges(back_edges)
{ }
void back_edge(const boost::graph_traits<Graph>::edge_descriptor& e, const Graph&) const {
_back_edges.emplace_back(e.m_source, e.m_target);
}
protected:
edge_vector& _back_edges;
};
auto generate_graph() const {
Graph g(std::begin(_edges), std::end(_edges), _entities.size());
return g;
}
void check_cycles(const Graph& g) const
{
edge_vector back_edges;
cycle_detector vis(back_edges);
boost::depth_first_search(g, visitor(vis));
if (back_edges.size())
{
std::ostringstream ss;
ss << "cyclic dependency detected. Back edges are:\n";
for (auto& p : back_edges)
{
ss << value::debug::demangle(typeid(_entities[p.first].get()))
<< " <<==>> "
<< value::debug::demangle(typeid(_entities[p.second].get()))
<< std::endl;
}
throw std::logic_error(ss.str());
}
}
auto create_order() const {
using namespace boost;
auto g = generate_graph();
check_cycles(g);
std::vector<std::size_t> result_order;
vector_type result;
boost::topological_sort(g, std::back_inserter(result_order));
std::transform(std::begin(result_order), std::end(result_order),
std::back_inserter(result), [this](auto i) {
return _entities[i];
});
return result;
}
auto drop_order() const {
auto result = create_order();
std::reverse(std::begin(result), std::end(result));
return result;
}
아니요, 불가능합니다. ** A ** ** ** B **에 의존하고 ** B ** ** ** C **에 달려 있다고 가정하십시오. 자, 주장 된 술어는 ** A **와 ** C **를 어떻게 비교합니까? – Leon
[토폴로지 정렬] (https://en.wikipedia.org/wiki/Topological_sorting)을 찾고있는 것처럼 들립니다. –
@VittorioRomeo와 동의하십시오.정점이 플러그인이고 가장자리가 그들 사이의 관계 인 위상 학적 정렬의 고전적인 응용 프로그램처럼 보입니다 ... –