16 : successors_(NULL), predecessors_(NULL),
17 successor_index_(NULL), predecessor_index_(NULL)
72 const std::pair<verti, verti> &b )
74 return a.first < b.first || (a.first == b.first && a.second < b.second);
78 const std::pair<verti, verti> &b )
80 return a.second < b.second || (a.second == b.second && a.first < b.first);
89 if (sccs.
size() <= 1)
return;
95 const std::vector<verti> scc;
96 for (
verti j = 0; j < scc.size(); ++j)
101 std::vector<char> is_top(sccs.
size(), 1),
102 is_bot(sccs.
size(), 1);
108 if (index[v] != index[w])
110 is_bot[index[v]] = 0;
111 is_top[index[w]] = 0;
119 std::vector<verti> vertis;
122 if (is_top[i] || is_bot[i])
124 vertis.push_back(sccs[i][rand()%sccs[i].
size()]);
128 <<
" of " <<
V_ <<
" vertices to create an SCC." << std::endl;
132 const verti v = vertis[i],
133 w = vertis[(i + 1)%sccs.
size()];
134 edges.push_back(std::make_pair(v, w));
149 assert(RAND_MAX >= 2*outdeg);
150 assert(RAND_MAX >=
V);
156 std::vector<verti> neighbours(
V);
157 for (
verti i = 0; i <
V; ++i) neighbours[i] = i;
158 for (
verti i = 0; i <
V; ++i)
160 unsigned N = 1 + rand()%(2*outdeg - 1);
161 if (N >=
V - 1) N =
V - 1;
162 for (
unsigned n = 0; n < N; ++n)
164 std::swap(neighbours[n], neighbours[n + rand()%(
V - n)]);
165 if (neighbours[n] == i)
168 neighbours[n + 1 + rand()%(
V - n - 1)] );
170 edges.push_back(std::make_pair(i, neighbours[n]));
186 assert(new_sccs.
size() == 1);
194 assert(cluster_size > 1);
195 std::size_t clusters =
V/cluster_size;
204 for (std::size_t i = 0; i < clusters; ++i)
206 subgraphs[i].
make_random( cluster_size + (i <
V%cluster_size),
211 for (
int i = 0; clusters > 1; ++i)
214 << i <<
"..." << std::endl;
215 std::size_t next_clusters = (clusters + cluster_size - 1)/cluster_size;
217 std::vector<verti> offset(clusters, 0);
218 for (std::size_t c = 0; c < next_clusters; ++c)
221 std::size_t i = c*clusters/next_clusters,
222 j = (c + 1)*clusters/next_clusters;
224 << i <<
" through " << j <<
" of "
225 << clusters <<
")" << std::endl;
228 for (std::size_t k = i + 1; k < j; ++k)
230 offset[k] = offset[k - 1] + subgraphs[k - 1].
V();
235 for (std::size_t k = i; k < j; ++k)
238 for ( edge_list::const_iterator it = subedges.begin();
239 it != subedges.end(); ++it )
241 edges.push_back(std::make_pair( it->first + offset[k],
242 it->second + offset[k] ));
250 for (std::size_t e = 0; e < paredges.size(); ++e)
252 verti v = paredges[e].first,
253 w = paredges[e].second;
254 edges.push_back(std::make_pair(
255 offset[i + v] + rand()%subgraphs[i + v].
V(),
256 offset[i + w] + rand()%subgraphs[i + w].
V() ));
261 subgraphs = next_subgraphs;
262 clusters = next_clusters;
264 assert(clusters == 1);
271 std::vector<verti> perm(
V_);
272 for (
verti i = 0; i <
V_; ++i) perm[i] = i;
280 for (edge_list::iterator it = edges.begin(); it != edges.end(); ++it)
282 it->first = perm[it->first];
283 it->second = perm[it->second];
290 if (&graph ==
this)
return;
312 for (edge_list::iterator it = edges.begin(); it != edges.end(); ++it)
314 if (it->first >=
V)
V = it->first + 1;
315 if (it->second >=
V)
V = it->second + 1;
320 assert(
E == edges.size());
335 for (
verti v = 0; v <
V; ++v)
337 while (pos <
E && edges[pos].first < v) ++pos;
353 for (
verti v = 0; v <
V; ++v)
355 while (pos <
E && edges[pos].second < v) ++pos;
368 edges.push_back(std::make_pair(
V_,
V_));
379 StaticGraph::edge_list::const_iterator it = edges.begin();
390 std::pair<verti, verti> edge(v, *p++);
392 if (*it == edge) ++it;
else successors_[e++] = edge.second;
402 StaticGraph::edge_list::const_iterator it = edges.begin();
413 std::pair<verti, verti> edge(*p++, v);
447 for (
edgei i = begin; i < end; ++i)
450 result.push_back(std::make_pair(v, w));
453 assert(result.size() ==
E_);
459 os.write((
const char*)&
V_,
sizeof(
V_));
460 os.write((
const char*)&
E_,
sizeof(
E_));
480 is.read((
char*)&
V,
sizeof(
V));
481 is.read((
char*)&
E,
sizeof(
E));
500 if (
this == &g)
return;
513 const verti num_vertices,
515 EdgeDirection edge_dir )
517 assert(
this != &graph);
526 for (
verti i = 0; i < num_vertices; ++i)
532 #pragma omp for reduction(+:num_edges)
533 for (
verti i = 0; i < num_vertices; ++i)
537 while (a != b)
if (map[*a++] !=
NO_VERTEX) ++num_edges;
553 for (
verti i = 0; i < num_vertices; ++i)
555 const verti u = verts[i];
562 verti w = map[*succ_it];
566 if (!std::is_sorted(begin, end, std::less<verti>()))
568 std::sort(begin, end);
570 if (proper) assert(begin != end);
572 assert(v ==
V_ && e ==
E_);
581 for (
verti i = 0; i < num_vertices; ++i)
583 const verti u = verts[i];
590 verti w = map[*pred_it];
594 if (!std::is_sorted(begin, end, std::less<verti>()))
596 std::sort(begin, end);
599 assert(v ==
V_ && e ==
E_);
static bool edge_cmp_backward(const std::pair< verti, verti > &a, const std::pair< verti, verti > &b)
static bool edge_cmp_forward(const std::pair< verti, verti > &a, const std::pair< verti, verti > &b)
std::size_t edgei
type used to number edges
std::size_t verti
type used to number vertices
std::vector< std::pair< verti, verti > > edge_list
void make_random(verti V, unsigned outdeg, EdgeDirection edge_dir, bool scc)
const_iterator succ_end(verti v) const
void reset(verti V, edgei E, EdgeDirection edge_dir)
EdgeDirection edge_dir() const
edgei * predecessor_index_
void make_random_clustered(verti cluster_size, verti V, unsigned outdeg, EdgeDirection edge_dir)
void read_raw(std::istream &is)
void swap(StaticGraph &g)
const_iterator succ_begin(verti v) const
void make_subgraph_threads(const StaticGraph &graph, const verti *verts, const verti nvert, bool proper, EdgeDirection edge_dir=EDGE_NONE)
void make_random_scc(edge_list &edges)
void write_raw(std::ostream &os) const
edge_list get_edges() const
void assign(const StaticGraph &graph)
void remove_edges(edge_list &edges)
const_iterator pred_begin(verti v) const
const_iterator pred_end(verti v) const
const verti * const_iterator
int decompose_graph(const StaticGraph &graph, Callback &callback)
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
void swap(atermpp::unprotected_aterm_core &t1, atermpp::unprotected_aterm_core &t2) noexcept
Swaps two aterms.
static void shuffle_vector(std::vector< T > &v)