200#include <tclap/CmdLine.h>
203using namespace Aleph;
233 auto home = g.insert_node(
"Homepage");
234 auto about = g.insert_node(
"About");
235 auto products = g.insert_node(
"Products");
236 auto services = g.insert_node(
"Services");
237 auto contact = g.insert_node(
"Contact");
240 auto blog = g.insert_node(
"Blog");
241 auto art1 = g.insert_node(
"Article1");
242 auto art2 = g.insert_node(
"Article2");
243 auto art3 = g.insert_node(
"Article3");
282 auto core = g.insert_node(
"Core");
283 auto utils = g.insert_node(
"Utils");
286 auto db = g.insert_node(
"Database");
287 auto cache = g.insert_node(
"Cache");
288 auto logger = g.insert_node(
"Logger");
291 auto api = g.insert_node(
"API");
292 auto auth = g.insert_node(
"Auth");
293 auto session = g.insert_node(
"Session");
301 g.insert_arc(
utils, cache);
302 g.insert_arc(
db, cache);
303 g.insert_arc(cache,
db);
304 g.insert_arc(cache,
logger);
305 g.insert_arc(
logger, cache);
322 auto a = g.insert_node(
"A");
323 auto b = g.insert_node(
"B");
324 auto c = g.insert_node(
"C");
325 auto d = g.insert_node(
"D");
326 auto e = g.insert_node(
"E");
342 for (
auto it = g.get_node_it(); it.has_curr(); it.next())
343 if (it.get_curr()->get_info() == name)
344 return it.get_curr();
354 cout <<
"Nodes: " << g.get_num_nodes() <<
endl;
355 cout <<
"Edges: " << g.get_num_arcs() <<
endl;
357 cout <<
"\nAdjacency structure:" <<
endl;
358 for (
auto nit = g.get_node_it();
nit.has_curr();
nit.next())
360 auto* node =
nit.get_curr();
361 cout <<
" " << node->get_info() <<
" -> ";
364 for (
auto ait = g.get_out_it(node);
ait.has_curr();
ait.next())
367 cout <<
ait.get_tgt_node()->get_info();
370 if (first)
cout <<
"(none)";
380 cout <<
"\n--- Finding Strongly Connected Components ---" <<
endl;
389 cout <<
"\nFound " <<
sccs.
size() <<
" strongly connected components:" <<
endl;
394 auto&
scc =
sit.get_curr();
401 cout <<
nit.get_curr()->get_info();
406 cout <<
" [cycle exists]";
408 cout <<
" [single node]";
418 cout <<
"\n--- Cycle Detection ---" <<
endl;
425 cout <<
"Result: Graph CONTAINS cycles" <<
endl;
433 cout <<
"A cycle found: ";
435 for (
auto it =
cycle.
get_it(); it.has_curr(); it.next())
438 cout << it.get_curr()->get_info();
441 cout <<
" -> " <<
cycle.get_first_node()->get_info() <<
" (back to start)" <<
endl;
446 cout <<
"Result: Graph is a DAG (no cycles)" <<
endl;
447 cout <<
"This graph can be topologically sorted." <<
endl;
456 cout <<
"\n" << string(60,
'=') <<
endl;
457 cout <<
"Example: Web Page Community Detection" <<
endl;
465 cout <<
"\n--- Analysis ---" <<
endl;
466 cout <<
"Pages in the same SCC form a 'community' - they mutually" <<
endl;
467 cout <<
"link to each other (directly or through intermediate pages)." <<
endl;
468 cout <<
"This is useful for:" <<
endl;
469 cout <<
" - Detecting website structure" <<
endl;
470 cout <<
" - Finding related content clusters" <<
endl;
479 cout <<
"\n" << string(60,
'=') <<
endl;
480 cout <<
"Example: Software Module Dependency Analysis" <<
endl;
489 cout <<
"\n--- Analysis ---" <<
endl;
490 cout <<
"Modules in the same SCC have circular dependencies." <<
endl;
492 cout <<
" - These modules must be built together" <<
endl;
493 cout <<
" - Changes to one may affect others" <<
endl;
494 cout <<
" - Consider refactoring to break cycles" <<
endl;
502 cout <<
"\n" << string(60,
'=') <<
endl;
503 cout <<
"Example: DAG Detection" <<
endl;
512 cout <<
"\n--- Analysis ---" <<
endl;
513 cout <<
"Each SCC contains only one node, confirming this is a DAG." <<
endl;
514 cout <<
"DAGs can be topologically sorted and processed in order." <<
endl;
521 TCLAP::CmdLine
cmd(
"Tarjan's SCC Algorithm Example",
' ',
"1.0");
523 TCLAP::SwitchArg
webArg(
"w",
"web",
524 "Show web community detection example",
false);
525 TCLAP::SwitchArg
modArg(
"m",
"modules",
526 "Show module dependency analysis example",
false);
527 TCLAP::SwitchArg
dagArg(
"d",
"dag",
528 "Show DAG detection example",
false);
529 TCLAP::SwitchArg
allArg(
"a",
"all",
530 "Run all demos",
false);
547 cout <<
"=== Tarjan's Algorithm: Strongly Connected Components ===" <<
endl;
548 cout <<
"An SCC is a maximal set where every vertex reaches every other." <<
endl;
559 cout <<
"\n=== Algorithm Summary ===" <<
endl;
560 cout <<
"Tarjan's Algorithm: O(V + E) time, single DFS pass" <<
endl;
561 cout <<
"Uses index (visit order) and lowlink (lowest reachable index)" <<
endl;
562 cout <<
"When lowlink[v] == index[v], v is root of an SCC" <<
endl;
566 catch (TCLAP::ArgException& e)
568 cerr <<
"Error: " << e.error() <<
" for arg " << e.argId() <<
endl;
Tarjan's algorithm for strongly connected components.
Generic directed graph (digraph) wrapper template.
typename BaseGraph::Node Node
Dynamic singly linked list with functional programming support.
size_t size() const noexcept
Count the number of elements of the list.
Computes strongly connected components (SCCs) in a directed graph using Tarjan's algorithm.
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Main namespace for Aleph-w library functions.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Arc of graph implemented with double-linked adjacency lists.
Node belonging to a graph implemented with a double linked adjacency list.
void demo_web_communities()
Demonstrate practical application: web communities.
void demo_find_sccs(SDigraph &g, const string &description)
Demonstrate finding SCCs with Tarjan's algorithm.
SDigraph::Node * find_node(SDigraph &g, const string &name)
Find a node by name.
SDigraph build_module_graph()
Build a software module dependency graph.
void demo_dependency_analysis()
Demonstrate practical application: dependency analysis.
void print_graph(SDigraph &g, const string &title)
Print the graph structure.
void demo_dag_detection()
Demonstrate DAG detection.
void demo_cycle_detection(SDigraph &g, const string &description)
Demonstrate cycle detection.
SDigraph build_dag()
Build a simple graph with no cycles (DAG)
SDigraph build_web_graph()
Build a sample web page link graph.
Generic graph and digraph implementations.