15 vertices_.emplace_back(
id, context);
16 vertex_valid_flags_.push_back(
true);
39 auto& vertex = vertices_[v];
42 auto num_us = vertex.us_edge.size();
43 auto num_ds = vertex.ds_edge.size();
44 std::vector<size_t> adj_verts;
45 adj_verts.reserve(num_us+num_ds);
47 for (
size_t u : vertex.us_edge)
48 adj_verts.push_back(u);
50 for (
size_t u : vertex.ds_edge)
51 adj_verts.push_back(u);
54 for (
size_t u : adj_verts)
56 vertices_[u].us_edge.erase(v);
57 vertices_[u].ds_edge.erase(v);
60 vertex_valid_flags_[v] =
false;
68 if (not vertex_valid_flags_[v])
70 <<
"chi_graph::DirectedGraph::VertexAccessor: "
71 "Invalid vertex accessed. Vertex may have been removed.";
107 AddEdge(
size_t from,
size_t to,
double weight)
112 vertices[from].ds_weights[to] = weight;
113 vertices[to].us_weights[from] = weight;
133 std::vector<bool> &visited,
136 traversal.push_back(cur_vid);
137 visited[cur_vid] =
true;
139 for (
auto v :
vertices[cur_vid].ds_edge)
151 std::vector<int>& disc,
152 std::vector<int>& low,
153 std::vector<bool>& on_stack,
154 std::stack<size_t>& stack,
155 std::vector<std::vector<size_t>>& SCCs)
158 disc[u] = low[u] = ++time;
167 low[u] = std::min(low[u],low[v]);
169 else if (on_stack[v])
170 low[u] = std::min(low[u],disc[v]);
174 if (low[u] == disc[u])
176 std::vector<size_t> sub_SCC;
177 while (stack.top() != u)
180 sub_SCC.push_back(w);
185 sub_SCC.push_back(w);
186 if (sub_SCC.size() > 1) SCCs.push_back(sub_SCC);
202std::vector<std::vector<size_t>>
208 std::vector<int> disc(V,-1);
209 std::vector<int> low(V,-1);
210 std::vector<bool> on_stack(V,
false);
211 std::stack<size_t> stack;
213 std::vector<std::vector<size_t>> SCCs;
217 for (
size_t v=0; v<V; ++v)
238 bool has_cycles=
false;
239 std::vector<size_t> L;
240 std::vector<GraphVertex*> S;
250 for (
auto& vertex : cur_vertices)
251 if (vertex.us_edge.empty())
252 S.push_back(&vertex);
262 while (not S.empty())
268 auto nodes_m = node_n->
ds_edge;
269 for (
size_t m : nodes_m)
306 for (
size_t ds : vertex.ds_edge)
307 delta += 1.0*vertex.ds_weights[ds];
309 for (
size_t us : vertex.us_edge)
310 delta -= 1.0*vertex.us_weights[us];
318 std::vector<size_t> s1,s2,s;
319 while (TG.vertices.GetNumValid()>0)
322 while (TG.GetNumSinks()>0)
324 for (
auto& u : TG.vertices)
325 if (u.ds_edge.empty())
327 TG.RemoveVertex(u.id);
334 while (TG.GetNumSources()>0)
336 for (
auto& u : TG.vertices)
337 if (u.us_edge.empty())
339 TG.RemoveVertex(u.id);
346 std::pair<int,double> max_delta(-1,-100.0);
347 for (
auto& u : TG.vertices)
349 double delta = GetVertexDelta(u);
350 if (delta > max_delta.second)
351 max_delta = std::make_pair(u.id,delta);
355 TG.RemoveVertex(max_delta.first);
356 s1.push_back(max_delta.first);
361 s.reserve(s1.size() + s2.size());
362 for (
size_t u : s1) s.push_back(u);
363 for (
size_t u : s2) s.push_back(u);
373 if (
Chi::mpi.location_id != location_mask)
return;
376 std::string offset(
" ");
377 o <<
"Printing directed graph:\n";
378 o <<
"digraph DG {\n";
380 o << offset <<
"splines=\"FALSE\";\n";
381 o << offset <<
"rankdir=\"LR\";\n\n";
384 o << offset <<
"/* Vertices */\n";
386 o << offset << v.id <<
" [shape=\"circle\"]\n";
388 o <<
"\n" << offset <<
"/* Edges */\n";
390 for (
int w : v.ds_edge)
391 o << offset << v.id <<
" -> " << w <<
"\n";
395 std::cout << o.str();
404 if (
Chi::mpi.location_id != location_mask)
return;
407 std::string offset(
" ");
408 o <<
"Printing directed graph:\n";
409 o <<
"digraph DG {\n";
411 o << offset <<
"splines=\"FALSE\";\n";
412 o << offset <<
"rankdir=\"LR\";\n\n";
415 o << offset <<
"/* Vertices */\n";
416 for (
int v : verts_to_print)
417 o << offset << v <<
" [shape=\"circle\"]\n";
419 o <<
"\n" << offset <<
"/* Edges */\n";
420 for (
int v : verts_to_print)
423 if (std::find(verts_to_print.begin(),
424 verts_to_print.end(),
425 w) != verts_to_print.end())
426 o << offset << v <<
" -> " << w <<
"\n";
431 std::cout << o.str();
435std::vector<std::pair<size_t,size_t>>
438 std::vector<std::pair<size_t,size_t>> edges_to_remove;
441 auto IsInList = [](std::vector<size_t>& list,
size_t val)
443 return std::find(list.begin(),list.end(),val) != list.end();
451 while (not SCCs.empty())
453 if (
Chi::log.GetVerbosity() >= chi::ChiLog::LOG_LVL::LOG_0VERBOSE_2)
455 <<
"Inter cell cyclic dependency removal. Iteration " << ++iter;
460 for (
auto& subDG : SCCs)
466 edges_to_remove.emplace_back(subDG.front(), subDG.back());
469 else if (subDG.size()==3)
472 for (
size_t u : subDG)
474 for (
size_t v :
vertices[u].ds_edge)
475 if (IsInList(subDG,v))
479 edges_to_remove.emplace_back(u, v);
490 for (
size_t k=0; k<subDG.size(); ++k)
499 auto mapv = std::find(subDG.begin(),subDG.end(),v);
500 if (mapv != subDG.end())
502 size_t mapping_v = mapv - subDG.begin();
511 std::vector<chi::GraphVertex> verts_copy;
514 verts_copy.push_back(v);
526 std::vector<int> smap(s.size(),-1);
532 std::vector<std::pair<int,int>> edges_to_rem;
533 for (
auto& u : verts_copy)
535 int cur_map = smap[u.id];
536 for (
size_t v : u.ds_edge)
538 int adj_map = smap[v];
539 if (adj_map < cur_map)
540 edges_to_rem.emplace_back(u.id,v);
544 for (
auto& edge : edges_to_rem)
546 size_t u = subDG[edge.first];
547 size_t v = subDG[edge.second];
549 edges_to_remove.emplace_back(u, v);
564 return edges_to_remove;
#define ChiLogicalErrorIf(condition, message)
static chi::MPI_Info & mpi
void RemoveVertex(size_t v)
void AddVertex(size_t id, void *context)
std::vector< bool > vertex_valid_flags_
GraphVertex & operator[](size_t v)
std::vector< GraphVertex > vertices_
std::vector< size_t > GenerateTopologicalSort()
void SCCAlgorithm(size_t u, int &time, std::vector< int > &disc, std::vector< int > &low, std::vector< bool > &on_stack, std::stack< size_t > &stack, std::vector< std::vector< size_t > > &SCCs)
std::vector< std::pair< size_t, size_t > > RemoveCyclicDependencies()
void AddVertex(size_t id, void *context=nullptr)
std::vector< size_t > FindApproxMinimumFAS()
void PrintSubGraphviz(const std::vector< int > &verts_to_print, int location_mask=0)
std::vector< std::vector< size_t > > FindStronglyConnectedComponents()
void RemoveEdge(size_t from, size_t to)
void DFSAlgorithm(std::vector< size_t > &traversal, std::vector< bool > &visited, size_t cur_vid)
void RemoveVertex(size_t v)
bool AddEdge(size_t from, size_t to, double weight=1.0)
void PrintGraphviz(int location_mask=0)
std::set< size_t > ds_edge
std::set< size_t > us_edge