-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVisualization.cpp
More file actions
161 lines (138 loc) · 6.8 KB
/
Copy pathVisualization.cpp
File metadata and controls
161 lines (138 loc) · 6.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "Visualization.h"
#include "Colors.h"
#include "RiskUtil.h"
#include <iostream>
#include <iomanip>
#include <algorithm>
// -----------------------------------------------------------------------------
// Banner
// -----------------------------------------------------------------------------
void Visualization::printBanner() {
std::cout << CLR_BORDER << R"(
+==============================================================+
| MILITARY LOGISTICS & TACTICAL NETWORK OPTIMIZER |
| Graph Algorithm Suite |
| C++ Implementation | Strategic Command |
+==============================================================+
)" << CLR_RESET;
}
// -----------------------------------------------------------------------------
// Network - formatted adjacency list
// -----------------------------------------------------------------------------
void Visualization::printNetwork(const Graph& g) {
if (g.empty()) { std::cout << " (no network loaded)\n"; return; }
std::cout << "\n " << CLR_BORDER << "TACTICAL NETWORK - Adjacency List" << CLR_RESET << "\n";
RiskUtil::printLegend();
std::cout << " " << CLR_BORDER << std::string(60, '=') << CLR_RESET << "\n";
for (int u = 0; u < g.n; u++) {
std::cout << "\n [" << std::setw(2) << u << "] "
<< CLR_BASE << g.getName(u) << CLR_RESET << "\n";
if (g.adj[u].empty()) {
std::cout << " (no outgoing routes)\n";
} else {
for (const auto& e : g.adj[u]) {
int v = e.to, w = e.weight, r = e.risk;
const char* rc = RiskUtil::color(r);
std::cout << " " << rc << "->" << CLR_RESET
<< " [" << std::setw(2) << v << "] "
<< CLR_BASE << std::left << std::setw(22) << g.getName(v)
<< CLR_RESET << std::right
<< " (dist: " << std::setw(4) << w << ", "
<< rc << "risk: " << std::setw(2) << r << " " << RiskUtil::label(r)
<< CLR_RESET << ")\n";
}
}
}
std::cout << " " << CLR_BORDER << std::string(60, '=') << CLR_RESET << "\n";
}
// -----------------------------------------------------------------------------
// Adjacency Matrix
// -----------------------------------------------------------------------------
void Visualization::printAdjMatrix(const Graph& g) {
if (g.empty()) { std::cout << " (no network loaded)\n"; return; }
int n = g.n;
if (n > 20) {
std::cout << " (matrix display skipped - graph has " << n
<< " nodes; limit is 20)\n";
return;
}
auto mat = g.getAdjMatrix();
std::cout << "\n " << CLR_BORDER << "ADJACENCY MATRIX (INF = no direct route)" << CLR_RESET << "\n";
std::cout << " " << CLR_BORDER << std::string(10 + 7 * n, '-') << CLR_RESET << "\n";
// Column headers
std::cout << " " << std::setw(8) << " ";
for (int v = 0; v < n; v++)
std::cout << std::setw(7) << ("[" + std::to_string(v) + "]");
std::cout << "\n " << CLR_BORDER << std::string(8 + 7 * n, '-') << CLR_RESET << "\n";
for (int u = 0; u < n; u++) {
std::cout << " [" << std::setw(2) << u << "] ";
for (int v = 0; v < n; v++) {
if (mat[u][v] >= INF)
std::cout << std::setw(7) << "INF";
else if (u == v)
std::cout << std::setw(7) << " 0";
else
std::cout << std::setw(7) << mat[u][v];
}
std::cout << " " << CLR_BASE << g.getName(u) << CLR_RESET << "\n";
}
std::cout << " " << CLR_BORDER << std::string(10 + 7 * n, '-') << CLR_RESET << "\n";
}
// -----------------------------------------------------------------------------
// ASCII Map - each route shown as [From] ---> [To] with its weight
// -----------------------------------------------------------------------------
void Visualization::printASCIIMap(const Graph& g) {
if (g.empty()) { std::cout << " (no network loaded)\n"; return; }
std::cout << CLR_BORDER << "=== ASCII NETWORK MAP ===" << CLR_RESET << "\n";
RiskUtil::printLegend();
for (int u = 0; u < g.n; u++) {
for (const auto& e : g.adj[u]) {
int v = e.to, w = e.weight, r = e.risk;
const char* rc = RiskUtil::color(r);
std::cout << "[" << CLR_BASE << g.getName(u) << CLR_RESET << "] "
<< rc << "---(d:" << w << " r:" << r << " " << RiskUtil::label(r)
<< ")--->" << CLR_RESET
<< " [" << CLR_BASE << g.getName(v) << CLR_RESET << "]\n";
}
}
}
// -----------------------------------------------------------------------------
// Statistics
// -----------------------------------------------------------------------------
void Visualization::printStats(const Graph& g) {
if (g.empty()) { std::cout << " (no network loaded)\n"; return; }
int totalEdges = static_cast<int>(g.edgeList.size());
int minW = INF, maxW = 0, sumW = 0;
int minR = 11, maxR = 0, sumR = 0;
for (const Edge& e : g.edgeList) {
minW = std::min(minW, e.weight);
maxW = std::max(maxW, e.weight);
sumW += e.weight;
minR = std::min(minR, e.risk);
maxR = std::max(maxR, e.risk);
sumR += e.risk;
}
int busiest = 0;
for (int u = 1; u < g.n; u++)
if (g.adj[u].size() > g.adj[busiest].size()) busiest = u;
std::cout << "\n " << CLR_BORDER << "NETWORK STATISTICS" << CLR_RESET << "\n";
std::cout << " " << CLR_BORDER << std::string(50, '=') << CLR_RESET << "\n";
std::cout << " Total bases (nodes) : " << g.n << "\n";
std::cout << " Total routes (edges) : " << totalEdges << "\n";
std::cout << " Network type : "
<< (g.directed ? "Directed" : "Undirected") << "\n";
std::cout << " Most connected base : " << CLR_BASE << g.getName(busiest) << CLR_RESET
<< " (" << g.adj[busiest].size() << " connections)\n";
if (totalEdges > 0) {
std::cout << " Min route distance : " << minW << "\n";
std::cout << " Max route distance : " << maxW << "\n";
std::cout << " Avg route distance : " << sumW / totalEdges << "\n";
std::cout << " Total network cost : " << sumW << "\n";
std::cout << " Min route risk : " << RiskUtil::color(minR) << minR
<< " (" << RiskUtil::label(minR) << ")" << CLR_RESET << "\n";
std::cout << " Max route risk : " << RiskUtil::color(maxR) << maxR
<< " (" << RiskUtil::label(maxR) << ")" << CLR_RESET << "\n";
std::cout << " Avg route risk : " << sumR / totalEdges << "\n";
}
std::cout << " " << CLR_BORDER << std::string(50, '=') << CLR_RESET << "\n";
}