41 typedef VertexType& VertexRef;
42 typedef EdgeType& EdgeRef;
49 , m_compute_vertex_levels(true)
57 template <
class ContainerT>
58 class SortedElementSet
67 ReverseOrderSet(
const T& elements)
68 : m_elements(elements)
71 virtual ~ReverseOrderSet() {}
73 typedef typename std::reverse_iterator<typename T::iterator> iterator;
74 typedef typename std::reverse_iterator<typename T::const_iterator> const_iterator;
76 iterator begin() {
return iterator(m_elements.end()); }
77 const_iterator begin()
const
79 return iterator(m_elements.end());
83 iterator end() {
return iterator(m_elements.begin()); }
84 const_iterator end()
const {
return iterator(m_elements.begin()); }
86 Integer size() {
return m_elements.size(); }
95 SortedElementSet(
const ContainerT& elements)
96 : m_elements(elements)
100 : m_elements(elements)
103 SortedElementSet() {}
105 virtual ~SortedElementSet() {}
107 typedef typename ContainerT::iterator iterator;
108 typedef typename ContainerT::const_iterator const_iterator;
110 iterator begin() {
return m_elements.begin(); }
111 const_iterator begin()
const {
return m_elements.begin(); }
113 iterator end() {
return m_elements.end(); }
114 const_iterator end()
const {
return m_elements.end(); }
116 Integer size() {
return m_elements.size(); }
122 ContainerT m_elements;
128 typedef std::map<typename Base::VertexTypeConstRef, Integer> VertexLevelMap;
129 typedef std::map<typename Base::EdgeTypeConstRef, Integer> EdgeLevelMap;
130 typedef std::set<std::pair<VertexType, Integer>, std::function<bool(std::pair<VertexType, Integer>, std::pair<VertexType, Integer>)>> VertexLevelSet;
132 void addEdge(
const VertexType& source_vertex,
const VertexType& target_vertex,
const EdgeType& source_to_target_edge)
134 Base::addEdge(source_vertex, target_vertex, source_to_target_edge);
135 m_compute_vertex_levels =
true;
138 void addEdge(VertexType&& source_vertex, VertexType&& target_vertex, EdgeType&& source_to_target_edge)
140 Base::addEdge(source_vertex, target_vertex, source_to_target_edge);
141 m_compute_vertex_levels =
true;
144 SortedVertexSet topologicalSort()
146 if (m_compute_vertex_levels)
147 _computeVertexLevels();
148 typename Base::VertexTypeRefArray sorted_vertices;
149 for (
auto& vertex : this->m_vertices) {
150 sorted_vertices.add(std::ref(vertex));
152 std::sort(sorted_vertices.begin(), sorted_vertices.end(), [&](
const VertexType& a,
const VertexType& b) { return m_vertex_level_map[a] < m_vertex_level_map[b]; });
153 return SortedVertexSet(std::move(sorted_vertices));
156 SortedEdgeSet spanningTree()
158 if (m_compute_vertex_levels)
159 _computeVertexLevels();
160 typename Base::EdgeTypeRefArray spaning_tree_edges;
161 for (
auto& edge : this->m_edges) {
162 Integer level = _computeEdgeLevel(edge);
163 m_edge_level_map[edge] = level;
166 spaning_tree_edges.add(std::ref(edge));
168 std::sort(spaning_tree_edges.begin(), spaning_tree_edges.end(), [&](
const EdgeType& a,
const EdgeType& b) { return m_edge_level_map[a] < m_edge_level_map[b]; });
169 return SortedEdgeSet(spaning_tree_edges);
174 if (m_compute_vertex_levels)
175 _computeVertexLevels();
176 this->m_trace_mng->info() <<
"--- Directed Graph ---";
177 for (
const auto& vertex_entry : this->m_adjacency_list)
178 _printGraphEntry(vertex_entry);
180 std::ostringstream oss;
181 this->m_trace_mng->info() << oss.str();
183 for (
const auto& vertex_level_set_entry : m_vertex_level_map)
184 this->m_trace_mng->info() <<
"-- Graph has vertex " << vertex_level_set_entry.first <<
" with level " << vertex_level_set_entry.second;
192 bool has_cycle =
false;
194 _computeVertexLevels();
204 std::set<typename Base::VertexTypeConstRef> m_colored_vertices;
205 VertexLevelMap m_vertex_level_map;
206 EdgeLevelMap m_edge_level_map;
207 bool m_compute_vertex_levels;
211 void _computeVertexLevels()
214 m_vertex_level_map.clear();
216 for (
const auto& vertex_entry : this->m_adjacency_list)
217 _computeVertexLevel(vertex_entry.first, 0);
218 m_compute_vertex_levels =
false;
221 void _computeVertexLevel(
const VertexType& vertex,
Integer level)
224 if (!m_colored_vertices.insert(std::cref(vertex)).second)
225 throw FatalErrorException(
"Cycle in graph. Exiting");
228 bool update_children =
true;
229 auto vertex_level_set_entry = m_vertex_level_map.insert(std::make_pair(std::cref(vertex), level));
230 if (!vertex_level_set_entry.second)
232 if (vertex_level_set_entry.first->second < level)
233 vertex_level_set_entry.first->second = level;
235 update_children =
false;
237 if (update_children) {
238 auto vertex_adjacency_list = Base::m_adjacency_list.find(vertex);
239 if (vertex_adjacency_list != Base::m_adjacency_list.end()) {
241 for (
const auto& child_vertex : vertex_adjacency_list->second.first)
242 _computeVertexLevel(child_vertex, level);
246 m_colored_vertices.erase(vertex);
249 Integer _computeEdgeLevel(
const EdgeType& edge)
253 throw FatalErrorException(
"Not existing edge.");
254 typename Base::VertexPair edge_vertices = edge_vertices_iterator->second;
256 Integer edge_level = m_vertex_level_map[std::cref(edge_vertices.first)];
258 if (math::abs(edge_level - m_vertex_level_map[std::cref(edge_vertices.second)]) > 1)
263 void _printGraphEntry(
const typename Base::AdjacencyListType::value_type& vertex_entry)
265 this->m_trace_mng->info() <<
"-- Vertex " << vertex_entry.first <<
" depends on ";
266 for (
const auto& connected_vertex : vertex_entry.second.first)
267 this->m_trace_mng->info() <<
" - " << connected_vertex;