-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathanomaly.cpp
More file actions
100 lines (93 loc) · 2.99 KB
/
anomaly.cpp
File metadata and controls
100 lines (93 loc) · 2.99 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
// anomaly.cpp
// handles the driver performance index calculations and related checks
#include "anomaly.h"
#include <iostream>
#include <iomanip>
#include <unordered_map>
std::unordered_map<int, double> buildDriverAverages(const std::vector<LapRecord>& allRecords)
{
// first pass: go through and total lap times + count laps per driver
std::unordered_map<int, long long> lapTimeSum;
std::unordered_map<int, int> lapCount;
for (const auto& rec : allRecords)
{
lapTimeSum[rec.driverId] += rec.milliseconds;
lapCount[rec.driverId]++;
}
// second pass: go through and get the average from total and count
std::unordered_map<int, double> driverAvgs;
for (const auto& entry : lapTimeSum)
{
int driverId = entry.first;
double avgMs = (double)entry.second / lapCount[driverId];
driverAvgs[driverId] = avgMs;
}
return driverAvgs;
}
AnomalyResult checkLapAnomaly (
int lapTimeMs,
int driverId,
const std::unordered_map<int,
double>& driverAvgs
) {
AnomalyResult result;
result.isFlagged = false;
result.pctDeviation = 0.0;
result.label = "NORMAL";
// if no average exists for this driver just leave it as normal
if (driverAvgs.find(driverId) == driverAvgs.end())
{
result.label = "NO DATA";
return result;
}
double avgMs = driverAvgs.at(driverId);
// difference from avg (positive slower, negative faster)
result.pctDeviation = (lapTimeMs - avgMs) / avgMs;
if (result.pctDeviation >= INCIDENT_THRESHOLD)
{
result.isFlagged = true;
result.label = "** INCIDENT **";
}
else if (result.pctDeviation >= SLOW_LAP_THRESHOLD)
{
result.isFlagged = true;
result.label = "SLOW LAP";
}
else if (result.pctDeviation <= -FAST_LAP_THRESHOLD)
{
result.isFlagged = true;
result.label = "FAST LAP";
}
return result;
}
std::vector<LapRecord> findFlaggedLapsForDriver (
int driverId,
const std::vector<LapRecord>& allRecords,
const std::unordered_map<int, double>& driverAvgs
) {
std::vector<LapRecord> flaggedOnes;
for (const auto& rec : allRecords)
{
if (rec.driverId != driverId)
continue;
AnomalyResult check = checkLapAnomaly (
rec.milliseconds,
rec.driverId,
driverAvgs);
if (check.isFlagged)
flaggedOnes.push_back(rec);
}
return flaggedOnes;
}
void printAnomalyInfo (
const AnomalyResult& result,
int lapTimeMs,
double driverAvgMs
) {
double pctDisplay = result.pctDeviation * 100.0;
std::cout << " Driver avg: " << std::fixed << std::setprecision(0) << driverAvgMs << " ms" << std::endl;
std::cout << " This lap: " << lapTimeMs << " ms" << std::endl;
std::cout << " Deviation: " << std::showpos << std::setprecision(1) << pctDisplay << "%" << std::noshowpos << std::endl;
std::cout << " Status: " << result.label << std::endl;
}
// anomaly.cpp