5 template<
typename ElementType,
typename NodeIndexType,
6 template<
typename,
typename...>
class NodeContainerType,
7 template<
typename,
typename...>
class IndexContainerType>
20 using node_ref_t = std::tuple<ElementType&, index_container_t&>;
23 using node_info_t = std::tuple<const ElementType&, const_ref_element_container_t>;
34 auto begin() {
return this->m_nodes.begin(); }
35 auto end() {
return this->m_nodes.end(); }
37 auto cbegin() {
return this->m_nodes.cbegin(); }
38 auto cend() {
return this->m_nodes.cend(); }
40 bool empty()
const {
return this->m_nodes.empty(); }
44 return tpf::element<node_container_t&>(m_nodes, node_index);
49 return tpf::element<const node_container_t&>(m_nodes, node_index);
58 auto indices = tpf::element<node_container_t&>(m_nodes, node_index);
60 for(
auto& idx: indices)
62 auto& value = tpf::element<element_container_t&>(m_values, idx);
63 elements.emplace_back(
std::ref(value));
72 auto indices = tpf::element<const node_container_t&>(m_nodes, node_index);
74 for(
auto& idx: indices)
76 auto& value = tpf::element<const element_container_t&>(m_values, idx);
77 elements.emplace_back(std::cref(value));
85 return tpf::element<element_container_t&>(m_values, node_index);
90 return tpf::element<const element_container_t&>(m_values, node_index);
96 auto indices = tpf::element<const node_container_t&>(m_nodes, node_index);
98 for(
auto& idx: indices)
100 auto& value = tpf::element<const element_container_t&>(m_values, idx);
101 elements.emplace_back(std::cref(value));
104 return {
node_value(node_index), std::move(elements) };
109 os <<
"node_"<<index;
return os;
124 size_t size = this->m_nodes.size();
126 for(
size_t i=0; i <
size; ++i)
133 using set_t = std::vector<index_t>;
134 using sets_t = std::vector<set_t>;
138 for(
size_t i = 0; i <
size; ++i)
141 for(
const auto& v: nodes)
154 if(vmode == visit_mode::graph)
161 if(vmode != visit_mode::graph)
162 os <<
" [dir=none, color=red, style=dashed] ; \n";
167 if(vmode != visit_mode::graph)
170 std::vector<index_t> visit_order;
172 if(vmode == visit_mode::visit_bfs)
177 if(visit_order.size() > 1)
181 for(
size_t i = 1; i < visit_order.size(); ++i )
187 os <<
" [ color = blue ] ; \n";
196 if(vmode == visit_mode::graph)
201 os <<
"label=\"Plain Graph\"\n";
213 os <<
"digraph G {\n";
215 if(vmode == visit_mode::visit_bfs)
216 os <<
"label=\"Breadth First Search\"\n";
218 os <<
"label=\"Depth First Search\"\n";
230 size_t size() {
return this->m_nodes.size(); }
232 template<
typename EleType,
typename Type,
typename... Types>
235 auto v = tpf::make_random_access_container<IndexContainerType>((NodeIndexType)std::forward<Type>(index0),
236 (NodeIndexType)std::forward<Types>(indices)...);
239 this->m_nodes.emplace_back(std::move(v));
240 this->m_values.emplace_back(std::forward<EleType>(value));
245 return node_ref_t{ tpf::element<element_container_t&>(this->m_values, node_index),
246 tpf::element<node_container_t&>(this->m_nodes, node_index) };
251 return const_node_ref_t{ tpf::element<const element_container_t&>(this->m_values, node_index),
252 tpf::element<const node_container_t&>(this->m_nodes, node_index) };
260 std::deque<index_t> queue;
261 std::vector<char> visited(m_nodes.size());
262 std::vector<index_t> traversal;
264 for(
auto& v: visited) v = 0;
265 queue.push_back(start);
267 visited[(size_t)start] = 1;
269 while(!queue.empty())
271 auto p = queue.front();
274 traversal.push_back(p);
277 for(
auto&
node: node_list)
279 if(visited[(
size_t)
node] == 0)
281 queue.push_back(
node);
282 visited[(size_t)
node] = 1;
292 std::vector<char>& visited,
298 for(
const auto&
node: node_list)
300 if(visited[(
size_t)
node] != 1)
302 stack.push_front(
node);
303 visited[(size_t)
node] = 1;
313 std::deque<index_t> stack;
314 std::vector<char> visited(this->m_nodes.size());
315 std::vector<index_t> traversal;
317 for(
auto& v: visited) v = 0;
321 while(!stack.empty())
323 traversal.push_back(stack.front());
325 push_stack(stack, visited, (
size_t)traversal.back());
333 if(g.m_nodes.empty())
342 auto last_itr = g.m_nodes.cend();
350 for(
auto itr = g.m_nodes.cbegin(); itr != g.m_nodes.cend(); ++itr)
351 os << std::setw(3) << index <<
" - ("
352 << tpf::element<const element_container_t&>(g.m_values, index++)<<
") " << *itr <<
"\n";
360 template<
typename ElementType = int,
typename NodeIndexType = int,
361 template<
typename,
typename...>
class NodeContainerType = std::list,
362 template<
typename,
typename...>
class IndexContainerType = std::vector>
363 using graph_t = graph<ElementType, NodeIndexType, NodeContainerType, IndexContainerType>;
reference_wrapper< Type > ref(Type &val) noexcept
std::tuple< const ElementType &, const_ref_element_container_t > node_info_t
const element_container_t & values() const
NodeContainerType< std::reference_wrapper< element_t > > ref_element_container_t
tpf::sstream & build_graph_edges(tpf::sstream &os, visit_mode vmode=visit_mode::graph)
std::vector< index_t > traverse_dfs(index_t start=0)
std::string build_graph(visit_mode vmode=visit_mode::graph)
std::vector< index_t > traverse_bfs(index_t start=0)
decltype(auto) node_value(size_t node_index) const
auto adjacent_node_values(size_t node_index) const
std::tuple< const ElementType &, const index_container_t & > const_node_ref_t
decltype(auto) adjacency_node_list(size_t node_index)
tpf::sstream & get_node_name(tpf::sstream &os, size_t index)
tpf::sstream & get_node_definition(tpf::sstream &os, size_t index)
decltype(auto) adjacency_node_list(size_t node_index) const
auto operator[](size_t node_index)
void emplace_back(EleType &&value, Type &&index0, Types &&... indices)
NodeContainerType< std::reference_wrapper< const element_t > > const_ref_element_container_t
NodeContainerType< index_container_t > node_container_t
auto operator[](size_t node_index) const
std::tuple< ElementType &, index_container_t & > node_ref_t
decltype(auto) node_value(size_t node_index)
friend tpf::sstream & operator<<(tpf::sstream &os, const graph &g)
void push_stack(std::deque< index_t > &stack, std::vector< char > &visited, size_t node_index)
auto adjacent_node_values(size_t node_index)
NodeContainerType< element_t > element_container_t
const node_container_t & node_lists() const
node_info_t node_info(size_t node_index) const
IndexContainerType< index_t > index_container_t
types::enable_if_container_type_t< ContainerType< EleType, Types... >, bool > sort_in_place(ContainerType< EleType, Types... > &container, sort_order order=sort_order::ascending, sort_method method=sort_method::size)
Includes subnamespace conversion.
typename SetTagType::set_t set_t
typename SetTagType::sets_t sets_t
Implements set operations.