41 typedef VertexType& VertexRef;
42 typedef EdgeType& EdgeRef;
48 , m_compute_vertex_levels(true){}
55 template <
class ContainerT>
67 typedef typename std::reverse_iterator<typename T::iterator> iterator;
68 typedef typename std::reverse_iterator<typename T::const_iterator> const_iterator;
70 iterator begin() {
return iterator(m_elements.end()); }
71 const_iterator begin()
const {
return iterator(m_elements.end()); ;}
73 iterator end() {
return iterator(m_elements.begin());}
74 const_iterator end()
const {
return iterator(m_elements.begin());}
76 Integer size() {
return m_elements.size();}
89 virtual ~SortedElementSet(){}
91 typedef typename ContainerT::iterator iterator;
92 typedef typename ContainerT::const_iterator const_iterator;
94 iterator begin() {
return m_elements.begin();}
95 const_iterator begin()
const {
return m_elements.begin();}
97 iterator end() {
return m_elements.end();}
98 const_iterator end()
const {
return m_elements.end();}
100 Integer size() {
return m_elements.size();}
102 ReverseOrderSet<ContainerT> reverseOrder() {
return ReverseOrderSet<ContainerT>(m_elements);}
105 ContainerT m_elements;
108 typedef GraphBaseT<VertexType,EdgeType> Base;
109 typedef SortedElementSet<typename Base::EdgeTypeRefArray> SortedEdgeSet;
110 typedef SortedElementSet<typename Base::VertexTypeRefArray> SortedVertexSet;
111 typedef std::map<typename Base::VertexTypeConstRef,Integer> VertexLevelMap;
112 typedef std::map<typename Base::EdgeTypeConstRef,Integer> EdgeLevelMap;
113 typedef std::set<std::pair<VertexType,Integer>, std::function<bool (std::pair<VertexType,Integer>,std::pair<VertexType,Integer>)>> VertexLevelSet;
115 void addEdge(
const VertexType& source_vertex,
const VertexType& target_vertex,
const EdgeType& source_to_target_edge)
117 Base::addEdge(source_vertex,target_vertex,source_to_target_edge);
118 m_compute_vertex_levels =
true;
121 void addEdge(VertexType&& source_vertex, VertexType&& target_vertex, EdgeType&& source_to_target_edge)
123 Base::addEdge(source_vertex,target_vertex,source_to_target_edge);
124 m_compute_vertex_levels =
true;
127 SortedVertexSet topologicalSort()
129 if (m_compute_vertex_levels) _computeVertexLevels();
130 typename Base::VertexTypeRefArray sorted_vertices;
131 for (
auto& vertex : this->m_vertices) {sorted_vertices.add(std::ref(vertex));}
132 std::sort(sorted_vertices.begin(),sorted_vertices.end(),[&](
const VertexType& a,
const VertexType& b){
133 return m_vertex_level_map[a] < m_vertex_level_map[b];});
134 return SortedVertexSet(std::move(sorted_vertices));
137 SortedEdgeSet spanningTree()
139 if (m_compute_vertex_levels) _computeVertexLevels();
140 typename Base::EdgeTypeRefArray spaning_tree_edges;
141 for (
auto& edge : this->m_edges)
143 Integer level = _computeEdgeLevel(edge);
144 m_edge_level_map[edge] = level;
145 if (level < 0)
continue;
146 spaning_tree_edges.add(std::ref(edge));
148 std::sort(spaning_tree_edges.begin(),spaning_tree_edges.end(), [&](
const EdgeType& a,
const EdgeType& b){
149 return m_edge_level_map[a] < m_edge_level_map[b];});
150 return SortedEdgeSet(spaning_tree_edges);
155 if (m_compute_vertex_levels) _computeVertexLevels();
156 this->m_trace_mng->
info() <<
"--- Directed Graph ---";
157 for (
const auto& vertex_entry: this->m_adjacency_list)
158 _printGraphEntry(vertex_entry);
160 std::ostringstream oss;
161 this->m_trace_mng->
info() << oss.str();
163 for (
const auto& vertex_level_set_entry : m_vertex_level_map)
164 this->m_trace_mng->info() <<
"-- Graph has vertex " << vertex_level_set_entry.first <<
" with level " << vertex_level_set_entry.second;
172 bool has_cycle =
false;
174 _computeVertexLevels();
182 std::set<typename Base::VertexTypeConstRef> m_colored_vertices;
183 VertexLevelMap m_vertex_level_map;
184 EdgeLevelMap m_edge_level_map;
185 bool m_compute_vertex_levels;
189 void _computeVertexLevels()
192 m_vertex_level_map.clear();
194 for (
const auto& vertex_entry : this->m_adjacency_list)
195 _computeVertexLevel(vertex_entry.first,0);
196 m_compute_vertex_levels =
false;
199 void _computeVertexLevel(
const VertexType& vertex, Integer level)
202 if (! m_colored_vertices.insert(std::cref(vertex)).second)
throw FatalErrorException(
"Cycle in graph. Exiting");
205 bool update_children =
true;
206 auto vertex_level_set_entry = m_vertex_level_map.insert(std::make_pair(std::cref(vertex),level));
207 if (!vertex_level_set_entry.second)
209 if (vertex_level_set_entry.first->second < level) vertex_level_set_entry.first->second = level;
210 else update_children =
false;
214 auto vertex_adjacency_list = Base::m_adjacency_list.find(vertex);
215 if (vertex_adjacency_list != Base::m_adjacency_list.end())
218 for (
const auto& child_vertex : vertex_adjacency_list->second.first)
219 _computeVertexLevel(child_vertex,level);
223 m_colored_vertices.erase(vertex);
226 Integer _computeEdgeLevel(
const EdgeType& edge)
229 if (edge_vertices_iterator == this->
m_edge_to_vertex_map.end())
throw FatalErrorException(
"Not existing edge.");
230 typename Base::VertexPair edge_vertices = edge_vertices_iterator->second;
232 Integer edge_level = m_vertex_level_map[std::cref(edge_vertices.first)];
234 if (math::abs(edge_level - m_vertex_level_map[std::cref(edge_vertices.second)]) >1) edge_level = -1;
238 void _printGraphEntry(
const typename Base::AdjacencyListType::value_type& vertex_entry)
240 this->m_trace_mng->
info() <<
"-- Vertex " << vertex_entry.first <<
" depends on ";
241 for (
const auto& connected_vertex : vertex_entry.second.first )
242 this->m_trace_mng->info() <<
" - " << connected_vertex;