Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_indexArc_example.cc
Go to the documentation of this file.
1
30#include <iostream>
31#include <tpl_indexArc.H>
32#include <tpl_graph.H>
33
34using namespace std;
35using namespace Aleph;
36
37int main()
38{
39 cout << "=== Arc Indexing: Educational Examples ===\n\n";
40
41 // =========================================================================
42 // EXAMPLE 1: Basic Arc Indexing
43 // =========================================================================
44 {
45 cout << "--- Example 1: Fast Arc Lookup ---\n\n";
46
48 GT g;
49
50 // STEP 1: Create nodes
51 auto nyc = g.insert_node("NYC");
52 auto boston = g.insert_node("Boston");
53 auto dc = g.insert_node("DC");
54 auto philly = g.insert_node("Philadelphia");
55
56 // STEP 2: Create arc index for fast lookup
58
59 cout << "Road network: NYC, Boston, DC, Philadelphia\n\n";
60
61 // STEP 3: Insert arcs with distances (directed graph)
62 cout << "Adding roads (directed):\n";
63 arc_idx.insert_in_graph(nyc, boston, 215); // miles
64 arc_idx.insert_in_graph(nyc, philly, 95);
65 arc_idx.insert_in_graph(nyc, dc, 225);
66 arc_idx.insert_in_graph(philly, dc, 140);
67 arc_idx.insert_in_graph(boston, philly, 100);
68 arc_idx.insert_in_graph(dc, boston, 440);
69
70 cout << " NYC <-> Boston: 215 miles\n";
71 cout << " NYC <-> Philadelphia: 95 miles\n";
72 cout << " NYC <-> DC: 225 miles\n";
73 cout << " Philadelphia <-> DC: 140 miles\n\n";
74
75 // STEP 4: Fast arc queries
76 cout << "QUERY: Is there a direct road from NYC to Boston?\n";
77 auto road = arc_idx.search(nyc, boston);
78 if (road)
79 cout << " YES! Distance: " << road->get_info() << " miles (O(log m) lookup)\n";
80 else
81 cout << " NO direct road\n";
82
83 cout << "\nQUERY: Is there a direct road from Boston to DC?\n";
84 auto no_road = arc_idx.search(boston, dc);
85 if (no_road)
86 cout << " YES! Distance: " << no_road->get_info() << " miles\n";
87 else
88 cout << " NO direct road (O(log m) lookup)\n";
89
90 cout << "\nKEY BENEFIT: Without index, would iterate through all arcs of source node\n";
91 cout << " With index: Direct O(log m) binary search tree lookup\n\n";
92 }
93
94 // =========================================================================
95 // EXAMPLE 2: Weighted Graph Queries
96 // =========================================================================
97 {
98 cout << "--- Example 2: Querying Arc Weights ---\n\n";
99
101 GT g;
103
104 // Build network topology
105 auto server1 = g.insert_node("Server1");
106 auto server2 = g.insert_node("Server2");
107 auto server3 = g.insert_node("Server3");
108 auto router = g.insert_node("Router");
109
110 cout << "Network topology with bandwidth (Gbps):\n";
111
112 // Add connections with bandwidth (directed)
113 arc_idx.insert_in_graph(server1, router, 10.0);
114 arc_idx.insert_in_graph(server2, router, 10.0);
115 arc_idx.insert_in_graph(server3, router, 10.0);
116
117 cout << " All servers connected to router at 10 Gbps\n\n";
118
119 // Query specific connections
120 cout << "Checking connection bandwidth:\n";
121 auto link1 = arc_idx.search(server1, router);
122 if (link1)
123 cout << " Server1 -> Router: " << link1->get_info() << " Gbps\n";
124
125 auto link2 = arc_idx.search(server2, router);
126 if (link2)
127 cout << " Server2 -> Router: " << link2->get_info() << " Gbps\n";
128
129 // Check if direct server-to-server link exists
130 auto direct = arc_idx.search(server1, server2);
131 if (direct)
132 cout << " Server1 -> Server2: Direct link\n";
133 else
134 cout << " Server1 -> Server2: No direct link (must route through router)\n";
135
136 cout << "\nAPPLICATION: Network topology queries, routing decisions\n\n";
137 }
138
139 // =========================================================================
140 // EXAMPLE 3: Detecting Parallel Arcs
141 // =========================================================================
142 {
143 cout << "--- Example 3: Parallel Arc Detection ---\n\n";
144
146 GT g;
148
149 auto cityA = g.insert_node("City A");
150 auto cityB = g.insert_node("City B");
151
152 cout << "Transportation network between two cities:\n";
153
154 // Insert first arc
155 arc_idx.insert_in_graph(cityA, cityB, "Highway");
156 cout << " Added: Highway\n";
157
158 // Check before adding another
159 if (arc_idx.search(cityA, cityB))
160 {
161 cout << " WARNING: Arc A->B already exists!\n";
162 cout << " Cannot add parallel arc with IndexArc (simple graph assumption)\n";
163 }
164
165 cout << "\nIMPORTANT: IndexArc assumes SIMPLE GRAPH (no parallel arcs)\n";
166 cout << " One arc per (source, target) pair\n";
167 cout << " Use multi-graph if parallel arcs needed\n\n";
168 }
169
170 // =========================================================================
171 // EXAMPLE 4: Performance Comparison
172 // =========================================================================
173 {
174 cout << "--- Example 4: Performance Analysis ---\n\n";
175
177 GT g;
179
180 const int N = 20; // nodes
181 cout << "Creating dense graph: " << N << " nodes...\n";
182
183 // Create nodes
185 for (int i = 0; i < N; ++i)
187
188 // Create dense connections (directed, avoid duplicates)
189 int arc_count = 0;
190 for (int i = 0; i < N; ++i)
191 for (int j = i + 1; j < N; ++j) // j > i to avoid duplicates
192 if ((i + j) % 2 == 0)
193 {
194 arc_idx.insert_in_graph(nodes[i], nodes[j], i * 10 + j);
195 arc_count++;
196 }
197
198 cout << " Nodes: " << N << "\n";
199 cout << " Arcs: " << arc_count << "\n";
200 cout << " Average degree: " << (arc_count / N) << "\n\n";
201
202 cout << "SEARCH COMPLEXITY:\n\n";
203
204 cout << "Without Index (iterate outgoing arcs):\n";
205 cout << " Best: O(1) - arc is first\n";
206 cout << " Average: O(deg/2) - scan half of arcs\n";
207 cout << " Worst: O(deg) - scan all arcs\n";
208 cout << " For degree=" << (arc_count/N) << ": ~" << (arc_count/N/2) << " comparisons\n\n";
209
210 cout << "With IndexArc:\n";
211 cout << " All cases: O(log m) - binary search tree\n";
212 cout << " For m=" << arc_count << ": ~" << (int)log2(arc_count) << " comparisons\n\n";
213
214 double speedup = (arc_count / N / 2.0) / log2(arc_count);
215 cout << "SPEEDUP: ~" << (int)speedup << "x faster for arc queries!\n\n";
216 }
217
218 // =========================================================================
219 // EXAMPLE 5: Dynamic Updates
220 // =========================================================================
221 {
222 cout << "--- Example 5: Dynamic Arc Management ---\n\n";
223
225 GT g;
227
228 auto a = g.insert_node("A");
229 auto b = g.insert_node("B");
230 auto c = g.insert_node("C");
231
232 cout << "Building graph dynamically...\n";
233
234 // Add arcs
235 arc_idx.insert_in_graph(a, b, 10);
236 arc_idx.insert_in_graph(b, c, 20);
237 cout << " Added: A->B(10), B->C(20)\n";
238
239 // Query
240 auto arc_ab = arc_idx.search(a, b);
241 if (arc_ab)
242 cout << " Found arc A->B with weight " << arc_ab->get_info() << "\n";
243
244 // Add more arcs
245 arc_idx.insert_in_graph(a, c, 30);
246 cout << " Added: A->C(30)\n";
247
248 // All arcs remain searchable in O(log m)
249 cout << "\nIndex automatically maintains balance\n";
250 cout << "All arc queries remain O(log m) after updates\n\n";
251 }
252
253 cout << "=== SUMMARY: IndexArc Best Practices ===\n";
254 cout << "\n1. WHEN TO USE:\n";
255 cout << " ✓ Dense graphs (high average degree)\n";
256 cout << " ✓ Frequent 'does arc exist?' queries\n";
257 cout << " ✓ Need arc weight/data lookup\n";
258 cout << " ✓ Adjacency matrix-like access pattern\n";
259 cout << "\n2. DESIGN PATTERNS:\n";
260 cout << " - Road networks: Query route existence\n";
261 cout << " - Social graphs: Check friendship status\n";
262 cout << " - Network topology: Verify link existence\n";
263 cout << " - Dependency graphs: Check direct dependency\n";
264 cout << "\n3. LIMITATIONS:\n";
265 cout << " ✗ Assumes SIMPLE GRAPH (no parallel arcs)\n";
266 cout << " ✗ Extra memory for index: O(m)\n";
267 cout << " ✗ Slightly slower insertions: O(log m) vs O(1)\n";
268 cout << "\n4. PERFORMANCE:\n";
269 cout << " Without index: O(degree) arc iteration\n";
270 cout << " With index: O(log m) tree lookup\n";
271 cout << " Speedup: degree / log(m) times faster\n";
272 cout << "\n5. COMPLEXITY SUMMARY:\n";
273 cout << " Insert arc: O(log m) - add to tree\n";
274 cout << " Search arc: O(log m) - tree lookup\n";
275 cout << " Remove arc: O(log m) - tree deletion\n";
276 cout << " Memory: O(m) - tree overhead\n";
277 cout << "\n6. BEST PRACTICES:\n";
278 cout << " - Use with IndexNode for complete indexing\n";
279 cout << " - Check arc existence before insert\n";
280 cout << " - Ideal for graphs with many arcs per node\n";
281 cout << " - Not needed for sparse graphs (low degree)\n";
282
283 return 0;
284}
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
Index for fast arc lookup by its endpoint nodes.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:524
#define N
Definition fib.C:294
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_log2_function > > log2(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4064
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
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.
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:222
Generic graph and digraph implementations.
Arc indexing for fast lookup by endpoint nodes.
int main()