Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
load_digraph_example.cc
Go to the documentation of this file.
1
23#include <iostream>
24#include <fstream>
25#include <sstream>
26#include <load_digraph.H>
27
28using namespace std;
29using namespace Aleph;
30
31int main()
32{
33 cout << "=== Graph Serialization: Educational Examples ===\n\n";
34
35 // =========================================================================
36 // EXAMPLE 1: Basic Graph Saving
37 // =========================================================================
38 {
39 cout << "--- Example 1: Saving Graph to File ---\n\n";
40
41 Digrafo g;
42
43 // STEP 1: Build a directed graph
44 cout << "Building directed graph (workflow):\n";
45 cout << " Start -> Process1 -> Process2 -> End\n";
46 cout << " Process1 -> Process3 -> End\n\n";
47
48 auto start = g.insert_node({"start", {"Start", "Node", "Type:Source"}});
49 auto p1 = g.insert_node({"p1", {"Process1", "CPU-Intensive"}});
50 auto p2 = g.insert_node({"p2", {"Process2", "I/O-Intensive"}});
51 auto p3 = g.insert_node({"p3", {"Process3", "Memory-Intensive"}});
52 auto end = g.insert_node({"end", {"End", "Node", "Type:Sink"}});
53
54 g.insert_arc(start, p1, "trigger");
55 g.insert_arc(p1, p2, "pass_data");
56 g.insert_arc(p1, p3, "parallel");
57 g.insert_arc(p2, end, "complete");
58 g.insert_arc(p3, end, "complete");
59
60 cout << "Graph created: " << g.get_num_nodes() << " nodes, "
61 << g.get_num_arcs() << " arcs\n\n";
62
63 // STEP 2: Save to files
64 cout << "Saving to files...\n";
65
66 ofstream nodes_file("/tmp/workflow_nodes.txt");
67 ofstream arcs_file("/tmp/workflow_arcs.txt");
68
69 // Save nodes (format: id|field1|field2|...)
70 for (Node_Iterator<Digrafo> it(g); it.has_curr(); it.next())
71 {
72 auto node = it.get_curr();
73 auto& info = node->get_info();
74
75 nodes_file << info.first; // ID
76 for (auto& field : info.second)
77 nodes_file << "|" << field;
78 nodes_file << "\n";
79 }
80
81 // Save arcs (format: src_id dst_id [arc_info])
82 for (Arc_Iterator<Digrafo> it(g); it.has_curr(); it.next())
83 {
84 auto arc = it.get_curr();
85 auto src = g.get_src_node(arc);
86 auto tgt = g.get_tgt_node(arc);
87
88 arcs_file << src->get_info().first << " "
89 << tgt->get_info().first;
90 if (!arc->get_info().empty())
91 arcs_file << " " << arc->get_info();
92 arcs_file << "\n";
93 }
94
95 nodes_file.close();
96 arcs_file.close();
97
98 cout << " Nodes saved to: /tmp/workflow_nodes.txt\n";
99 cout << " Arcs saved to: /tmp/workflow_arcs.txt\n\n";
100
101 cout << "FILE CONTENTS:\n";
102 cout << "Nodes file:\n";
103 cout << " start|Start|Node|Type:Source\n";
104 cout << " p1|Process1|CPU-Intensive\n";
105 cout << " ...\n\n";
106 cout << "Arcs file:\n";
107 cout << " start p1 trigger\n";
108 cout << " p1 p2 pass_data\n";
109 cout << " ...\n\n";
110 }
111
112 // =========================================================================
113 // EXAMPLE 2: Loading Graph from File
114 // =========================================================================
115 {
116 cout << "--- Example 2: Loading Graph from File ---\n\n";
117
118 // STEP 1: Open saved files
119 ifstream nodes_file("/tmp/workflow_nodes.txt");
120 ifstream arcs_file("/tmp/workflow_arcs.txt");
121
122 if (!nodes_file || !arcs_file)
123 {
124 cout << "ERROR: Could not open saved files\n";
125 cout << "Make sure Example 1 ran successfully\n\n";
126 }
127 else
128 {
129 // STEP 2: Load graph
131
132 cout << "Loading graph from files...\n";
134
135 cout << " Loaded: " << loaded_graph.get_num_nodes() << " nodes, "
136 << loaded_graph.get_num_arcs() << " arcs\n\n";
137
138 // STEP 3: Verify loaded data
139 cout << "Loaded nodes:\n";
140 for (Node_Iterator<Digrafo> it(loaded_graph); it.has_curr(); it.next())
141 {
142 auto node = it.get_curr();
143 auto& info = node->get_info();
144
145 cout << " ID: " << info.first << ", Fields: ";
146 for (size_t i = 0; i < info.second.size(); ++i)
147 {
148 if (i > 0) cout << ", ";
149 cout << info.second[i];
150 }
151 cout << "\n";
152 }
153
154 cout << "\nKEY INSIGHT: Graph structure perfectly preserved\n";
155 cout << " All nodes, arcs, and data restored\n\n";
156 }
157 }
158
159 // =========================================================================
160 // EXAMPLE 3: Round-Trip Verification
161 // =========================================================================
162 {
163 cout << "--- Example 3: Round-Trip Test (Save → Load → Verify) ---\n\n";
164
165 // Create original graph
167 auto n1 = original.insert_node({"1", {"Node", "One"}});
168 auto n2 = original.insert_node({"2", {"Node", "Two"}});
169 auto n3 = original.insert_node({"3", {"Node", "Three"}});
170
171 original.insert_arc(n1, n2, "arc12");
172 original.insert_arc(n2, n3, "arc23");
173 original.insert_arc(n3, n1, "arc31"); // Creates cycle
174
175 cout << "Original graph: " << original.get_num_nodes() << " nodes, "
176 << original.get_num_arcs() << " arcs\n";
177
178 // Save
179 stringstream nodes_stream, arcs_stream;
180
181 for (Node_Iterator<Digrafo> it(original); it.has_curr(); it.next())
182 {
183 auto node = it.get_curr();
184 auto& info = node->get_info();
185 nodes_stream << info.first;
186 for (auto& field : info.second)
187 nodes_stream << "|" << field;
188 nodes_stream << "\n";
189 }
190
191 for (Arc_Iterator<Digrafo> it(original); it.has_curr(); it.next())
192 {
193 auto arc = it.get_curr();
194 auto src = original.get_src_node(arc);
195 auto tgt = original.get_tgt_node(arc);
196 arcs_stream << src->get_info().first << " "
197 << tgt->get_info().first << " "
198 << arc->get_info() << "\n";
199 }
200
201 // Load into new graph
204
205 cout << "Loaded graph: " << loaded.get_num_nodes() << " nodes, "
206 << loaded.get_num_arcs() << " arcs\n\n";
207
208 // Verify
209 bool same_structure = (original.get_num_nodes() == loaded.get_num_nodes()) &&
210 (original.get_num_arcs() == loaded.get_num_arcs());
211
212 if (same_structure)
213 cout << "✓ VERIFICATION PASSED: Structure preserved\n";
214 else
215 cout << "✗ VERIFICATION FAILED: Structure mismatch\n";
216
217 cout << "\nIMPORTANT: This format preserves:\n";
218 cout << " ✓ Node IDs and attributes\n";
219 cout << " ✓ Arc connectivity\n";
220 cout << " ✓ Arc labels/weights\n";
221 cout << " ✓ Directed graph structure\n\n";
222 }
223
224 // =========================================================================
225 // EXAMPLE 4: Error Handling
226 // =========================================================================
227 {
228 cout << "--- Example 4: Error Handling ---\n\n";
229
230 cout << "COMMON ERRORS AND SOLUTIONS:\n\n";
231
232 cout << "1. File Not Found:\n";
233 cout << " ifstream file(\"nonexistent.txt\");\n";
234 cout << " if (!file) {\n";
235 cout << " cerr << \"ERROR: Cannot open file\\n\";\n";
236 cout << " return 1;\n";
237 cout << " }\n\n";
238
239 cout << "2. Invalid Arc (node ID not found):\n";
240 cout << " Arc references node that doesn't exist\n";
241 cout << " Solution: Validate node IDs before loading arcs\n\n";
242
243 cout << "3. Malformed Data:\n";
244 cout << " Missing delimiters, incorrect format\n";
245 cout << " Solution: Use try-catch around load_digraph()\n\n";
246
247 cout << "4. Encoding Issues:\n";
248 cout << " Non-ASCII characters in node names\n";
249 cout << " Solution: Use UTF-8 encoding consistently\n\n";
250 }
251
252 // =========================================================================
253 // EXAMPLE 5: Large Graph Handling
254 // =========================================================================
255 {
256 cout << "--- Example 5: Performance Tips ---\n\n";
257
258 cout << "FOR LARGE GRAPHS:\n\n";
259
260 cout << "1. STREAMING:\n";
261 cout << " Don't load entire file into memory\n";
262 cout << " Process line by line\n\n";
263
264 cout << "2. BINARY FORMAT:\n";
265 cout << " Text files: human-readable but large\n";
266 cout << " Binary: compact but not portable\n";
267 cout << " Trade-off based on use case\n\n";
268
269 cout << "3. COMPRESSION:\n";
270 cout << " Use gzip for text files\n";
271 cout << " Can reduce size by 80-90%\n";
272 cout << " Read/write through compression library\n\n";
273
274 cout << "4. CHUNKING:\n";
275 cout << " Save/load in chunks for very large graphs\n";
276 cout << " Process incrementally\n\n";
277 }
278
279 cout << "=== SUMMARY: Graph Serialization Best Practices ===\n";
280 cout << "\n1. FILE FORMAT CHOICE:\n";
281 cout << " Text: Human-readable, easy to debug, larger files\n";
282 cout << " Binary: Compact, fast, not human-readable\n";
283 cout << " Choose based on needs (debugging vs production)\n";
284 cout << "\n2. ALWAYS VERIFY:\n";
285 cout << " After loading, check node/arc counts\n";
286 cout << " Validate graph properties (connectivity, etc.)\n";
287 cout << " Round-trip test: save → load → compare\n";
288 cout << "\n3. ERROR HANDLING:\n";
289 cout << " Check file open success\n";
290 cout << " Validate node IDs before creating arcs\n";
291 cout << " Use try-catch for parsing errors\n";
292 cout << "\n4. METADATA:\n";
293 cout << " Include version info in file header\n";
294 cout << " Add timestamp, graph name, etc.\n";
295 cout << " Document file format in comments\n";
296 cout << "\n5. LARGE GRAPHS:\n";
297 cout << " Use streaming for memory efficiency\n";
298 cout << " Consider compression (gzip)\n";
299 cout << " Chunk processing for huge graphs\n";
300 cout << "\n6. APPLICATIONS:\n";
301 cout << " * Checkpoint long-running algorithms\n";
302 cout << " * Share datasets between researchers\n";
303 cout << " * Version control for graph evolution\n";
304 cout << " * Backup and disaster recovery\n";
305
306 return 0;
307}
Generic directed graph (digraph) wrapper template.
Definition graph-dry.H:3848
void next()
Advances the iterator to the next filtered element.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Filtered iterator on the nodes of a graph.
Definition tpl_graph.H:1206
void load_digraph(Digrafo &g, std::istream &nodes_input, std::istream &arcs_input)
Load nodes and arcs from streams into the directed graph.
Utilities for loading directed graphs from pipe-separated files.
int main()
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
Filtered iterator on all the arcs of a graph.
Definition tpl_graph.H:1164