44# ifndef RANDOM_GRAPH_H
45# define RANDOM_GRAPH_H
47# include <gsl/gsl_rng.h>
97 template <
class GT,
class Init_Node,
class Init_Arc>
109 std::unique_ptr<DynArray<GT_Node *>>
nodes;
159 for (
unsigned long i = 0; i <
k; ++i, it.
next_ne()) {}
172 <<
"Number of nodes must be greater than 0";
212 for (
size_t i = 0; i <
num_arcs; ++i)
216 if (
idx_arc->search(src, tgt) ==
nullptr)
277 g = this->
create_p(__num_nodes, p,
true);
311 const double & p = 0.5)
313 g = this->
create_p(__num_nodes, p,
true);
383 this->odd_nodes.
remove(src);
384 this->even_nodes.
insert(src);
388 this->even_nodes.
remove(src);
389 this->odd_nodes.
insert(src);
394 this->odd_nodes.
remove(tgt);
395 this->even_nodes.
insert(tgt);
399 this->even_nodes.
remove(tgt);
400 this->odd_nodes.
insert(tgt);
406 this->
nodes = std::unique_ptr<DynArray<GT_Node *>>
411 for (
size_t i = 0; i < this->
num_nodes; ++i)
414 this->
nodes->access(i) = p;
418 this->even_nodes.
insert(p);
440 it.has_curr(); it.next_ne())
443 for (
size_t i = 1; i <
num_subs; ++i)
460 for (
size_t i = 0; i + 1 < this->
num_nodes; ++i)
462 auto src = this->
nodes->access(i);
463 for (
size_t j = i + 1; j < this->
num_nodes; ++j)
466 auto tgt = this->
nodes->access(j);
475 return std::move(this->
g);
491 <<
"Building of random digraph through a graph";
500 <<
"Building of random digraph through a graph";
558 while (this->odd_nodes.
size() > 1)
565 src = this->odd_nodes.
select
568 tgt = this->odd_nodes.
select
572 if (this->
idx_arc->search(src, tgt) ==
nullptr)
574 else if (this->odd_nodes.
size() == 2)
578 p = this->even_nodes.
select
580 while (this->
idx_arc->search(src, p) !=
nullptr or
581 this->idx_arc->search(tgt, p) !=
nullptr);
597 if (this->
idx_arc->search(src, tgt) ==
nullptr)
605 if (p == src
or p == tgt)
608 if (this->
idx_arc->search(src, p) ==
nullptr)
614 if (this->
idx_arc->search(tgt, p) ==
nullptr)
622 for (
size_t i = 0; i + 1 < n; ++i)
624 auto src = this->
nodes->access(i);
625 for (
size_t j = i + 1; j < n; ++j)
651 return std::move(this->
g);
674 this->
g = this->
create_p(__num_nodes, p,
true);
677 return std::move(this->
g);
708 const double & p = 0.5)
710 this->
g = this->
create_p(__num_nodes, p,
true);
713 return std::move(this->
g);
750 const size_t & n = this->
nodes->size();
753 std::cout <<
"Warning num of nodes of graph does not match with array "
758 std::cout <<
"Inconsistency with nodes parity" << std::endl
759 <<
"greater = " <<
greater.size() << std::endl
761 <<
"equal = " <<
equal.
size() << std::endl
762 <<
"total = " <<
total << std::endl
765 for (
size_t i = 0; i < n; ++i)
767 auto p = this->
nodes->access(i);
775 std::cout <<
"Inconsistency " <<
in_sz <<
"/" <<
out_sz <<
" found "
776 <<
" in smaller table" << std::endl;
778 if (
greater.search(p) !=
nullptr)
779 std::cout <<
"Inconsistency " <<
in_sz <<
"/" <<
out_sz <<
" found "
780 <<
" in greater table" << std::endl;
784 std::cout <<
"node of same in/out degree is not in equal table"
792 if (
greater.search(p) !=
nullptr)
793 std::cout <<
"Inconsistency " <<
in_sz <<
"/" <<
out_sz <<
" found "
794 <<
" in greater table" << std::endl;
797 std::cout <<
"Inconsistency " <<
in_sz <<
"/" <<
out_sz <<
" found "
802 std::cout <<
"node with " <<
in_sz <<
"/" <<
out_sz <<
" not found "
803 <<
"smaller table" << std::endl;
811 std::cout <<
"Inconsistency " <<
in_sz <<
"/" <<
out_sz <<
" found "
812 <<
" in smaller table" << std::endl;
815 std::cout <<
"Inconsistency " <<
in_sz <<
"/" <<
out_sz <<
" found "
818 if (
greater.search(p) ==
nullptr)
820 std::cout <<
"node with " <<
in_sz <<
"/" <<
out_sz <<
" not found "
821 <<
"greater table" << std::endl;
844 this->smaller.
remove(src);
852 this->greater.
insert(src);
865 this->greater.
remove(tgt);
875 this->smaller.
insert(tgt);
885 this->
nodes = std::unique_ptr<DynArray<GT_Node *>>
890 for (
size_t i = 0; i < this->
num_nodes; ++i)
893 this->
nodes->access(i) = p;
914 typename GT::Node_Iterator it(this->
g);
915 for (
int i = 0; it.has_curr(); it.next_ne(), ++i)
921 for (
size_t i = 0; it.has_curr(); it.next_ne(), ++i)
936 for (
size_t i = 0; it.has_curr(); it.next_ne(), ++i)
944 for (
size_t i = 0; i + 1 < num_blocks; ++i)
947 auto tgt = b1.
access((i + 1) % num_blocks);
949 if (this->
idx_arc->search_directed(src, tgt) ==
nullptr)
953 tgt = b2.
access((i + 1) % num_blocks);
955 if (this->
idx_arc->search_directed(tgt, src) ==
nullptr)
969 for (
size_t i = 0; i < this->
num_nodes; ++i)
971 auto src = this->
nodes->access(i);
972 for (
size_t j = 0; j < this->
num_nodes; ++j)
975 auto tgt = this->
nodes->access(j);
984 return std::move(this->
g);
1084 tgt = this->greater.
select
1086 src = this->smaller.
select
1091 if (this->
idx_arc->search_directed(src, tgt) ==
nullptr)
1097 this->equal.
size()));
1099 while (this->
idx_arc->search_directed(src,
mid) !=
nullptr or
1100 this->idx_arc->search_directed(
mid, tgt) !=
nullptr)
1113 const size_t n2 = n / 2;
1121 if (this->
idx_arc->search_directed(p, q) ==
nullptr)
1127 if (this->
idx_arc->search_directed(q, p) ==
nullptr)
1139 if (this->
idx_arc->search_directed(src, tgt) !=
nullptr)
1152 if (p == src
or p == tgt)
1155 if (this->
idx_arc->search_directed(src, p) ==
nullptr)
1164 if (this->
idx_arc->search_directed(p, tgt) ==
nullptr)
1179 for (
typename GT::Arc_Iterator it(this->
g); it.has_curr(); it.next_ne())
1184 for (
size_t i = 0; i < n; ++i)
1186 auto src = this->
nodes->access(i);
1187 for (
size_t j = 0; j < n; ++j)
1192 auto tgt = this->
nodes->access(j);
Tarjan's algorithm for strongly connected components.
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_bad_alloc_if(C)
Throws std::bad_alloc if condition holds.
void insert(Dlink *node) noexcept
Insert node after this.
T & access(const size_t i) const noexcept
Fast access without checking allocation and bound_min_clock checking.
void reserve(const size_t l, const size_t r)
Allocate a range of entries.
Iterator on the items of list.
T & get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
Append a new item by copy.
Dynamic set implemented using randomized binary search trees of type Rand_Tree<Key>.
const size_t & size() const
Returns the cardinality of the set.
Key * insert(const Key &key)
Inserts a key into the dynamic set.
size_t remove(const Key &key)
Removes a key from the dynamic set.
Key * search(const Key &key) const
Find an element in the set.
Key & select(size_t i)
Returns the ith node in infix position.
void next_ne() noexcept
Move the iterator one position forward guaranteeing no exception.
size_t size() const noexcept
Count the number of elements of the list.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Random directed graph (digraph) generator.
DynSetRandTree< GT_Node * > equal
DynSetRandTree< GT_Node * > greater
Random_Digraph(const Init_Node &__init_node, const Init_Arc &__init_arc)
DynSetRandTree< GT_Node * > smaller
virtual void update_parity_after_arc_insertion(GT_Node *src, GT_Node *tgt)
GT create_p(const size_t &__num_nodes, const double &p, bool connected) override
GT operator()(const size_t &__num_nodes, const size_t &__num_arcs, bool connected=true)
Create a sparse random digraph.
void balance_digraph_node(GT_Node *p)
void make_hamiltonian() override
void balance_digraph_nodes_degree(GT_Node *src, GT_Node *tgt)
Random_Digraph(unsigned long seed, const Init_Node &__init_node, const Init_Arc &__init_arc)
Constructor.
void make_eulerian() override
void create_nodes_and_initialize_arc_index() override
Random_Digraph(unsigned long seed=time(nullptr), const Init_Node &&__init_node=Init_Node(), const Init_Arc &&__init_arc=Init_Arc())
virtual void create_nodes_and_initialize_arc_index()=0
std::unique_ptr< DynArray< GT_Node * > > nodes
std::unique_ptr< IndexArc< GT > > idx_arc
void initialize_and_create_nodes(const size_t &__num_nodes, const size_t &__num_arcs)
GT create(const size_t &__num_nodes, const size_t &__num_arcs, const bool connected)
Create a sparse random graph.
Random_Graph_Base(const unsigned long seed, const Init_Node &__init_node, const Init_Arc &__init_arc)
GT eulerian(const size_t &__num_nodes, const size_t &__num_arcs)
Create a random Eulerian graph (sparse version).
virtual void make_hamiltonian()=0
GT_Arc * insert_arc(GT_Node *src, GT_Node *tgt)
virtual void update_parity_after_arc_insertion(GT_Node *src, GT_Node *tgt)=0
GT eulerian(const size_t &__num_nodes, const double &p)
Create a random Eulerian graph (dense version).
virtual GT create_p(const size_t &__num_nodes, const double &p, bool connected)=0
GT_Node * select_random_node(DynList< GT_Node * > &list) noexcept
Select a random node from the given list.
virtual ~Random_Graph_Base()
virtual void make_eulerian()=0
GT_Node * select_random_node(GT_Node *excluded=nullptr) noexcept
Select a random node different from excluded.
Random undirected graph generator.
DynSetRandTree< GT_Node * > odd_nodes
virtual void update_parity_after_arc_insertion(GT_Node *src, GT_Node *tgt)
Random_Graph(unsigned long seed=time(nullptr), const Init_Node &&__init_node=Init_Node(), const Init_Arc &&__init_arc=Init_Arc())
void make_hamiltonian() override
Random_Graph(unsigned long seed, const Init_Node &__init_node, const Init_Arc &__init_arc)
Constructor.
GT operator()(const size_t &__num_nodes, const size_t &__num_arcs, bool connected=true)
Create a sparse random graph.
void create_nodes_and_initialize_arc_index() override
GT create_p(const size_t &__num_nodes, const double &p, const bool connected) override
DynSetRandTree< GT_Node * > even_nodes
void balance_graph_nodes_degree(GT_Node *src, GT_Node *tgt)
GT eulerian(const size_t &__num_nodes, const size_t &__num_arcs)
Create a random Eulerian graph (sparse version).
GT eulerian(const size_t &__num_nodes, const double &p)
Create a random Eulerian graph (dense version).
void make_eulerian() override
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
bool is_digraph() const noexcept
Return true if the graph this is directed.
void set_digraph(bool val)
Temporal indication for preventing to other algorithms that an graph must be treated as a directed gr...
void reset_counter_nodes() const noexcept
Reset all the counters to zero for all the nodes of graph.
constexpr size_t get_num_arcs() const noexcept
List_Graph< Graph_Node< int >, Graph_Arc< int > > GT
#define NODE_COUNTER(p)
Get the counter of a node.
GT sufficient_hamiltonian(const size_t &__num_nodes, const double &p=0.5)
Create a random Hamiltonian graph.
size_t in_degree(typename GT::Node *p, SA sa=SA())
Compute the filtered in degree of node p.
GT sufficient_hamiltonian(const size_t &__num_nodes, const double &p=0.5)
Create a random Hamiltonian graph.
Main namespace for Aleph-w library functions.
bool is_even(const long n)
Return true if n is even.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Default arc initializer for random graph generation.
void operator()(GT &, typename GT::Arc *) const noexcept
Default node initializer for random graph generation.
void operator()(GT &, typename GT::Node *) const noexcept
Arc of graph implemented with double-linked adjacency lists.
Graph connectivity and connected components.
Utility algorithms and operations for graphs.
Arc indexing for fast lookup by endpoint nodes.