-
Notifications
You must be signed in to change notification settings - Fork 0
/
Graph_DFS.cpp
125 lines (112 loc) · 3.91 KB
/
Graph_DFS.cpp
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
//
// Created by kamil on 04.12.16.
//
#include <iostream>
#include <algorithm>
#include "Graph_DFS.h"
Graph_DFS::Graph_DFS(std::vector<Segment>& segments, std::string filename) : Graph(segments, filename) {}
Graph_DFS::Graph_DFS(int V, int E, std::string filename) : Graph(V, E, filename) {}
void Graph_DFS::DFS(int v, int parent) {
marked[v] = true;
if (parent != -1)
path.push_back(parent);
std::vector<int>::iterator it = std::find(path.begin(),path.end(),v);
if (it != path.end()) {
std::vector<int> ancestors(it, path.end());
std::vector<int> p = normalize(ancestors);
std::vector<int> inv = invert(p);
if (is_new(p) && is_new(inv)) {
cycles.insert(p);
// for (auto& i : p) {
// outfile << i << " ";
// }
// outfile << std::endl;
}
}
else
for (auto& i : adj[v])
if (i != parent)
DFS(i, v);
path.pop_back();
}
void Graph_DFS::find_cycles() {
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
for (int i = 0; i < V; i++) {
if (!marked[i])
DFS(i, -1);
path.clear();
}
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
outfile << "No. vertices: " << this->V << std::endl;
outfile << "No. edges: " << this->E << std::endl;
outfile << "Polygons found: " << cycles.size() << std::endl;
outfile << "Elapsed time: " << elapsed_seconds.count() << std::endl;
}
std::vector<int> Graph_DFS::normalize(std::vector<int> path) {
std::vector<int>::iterator x = std::min_element(path.begin(),path.end());
std::vector<int> temp;
temp.reserve(path.size());
temp.insert(temp.end(),x,path.end());
temp.insert(temp.end(),path.begin(),x);
return temp;
}
std::vector<int> Graph_DFS::invert(std::vector<int> path) {
std::reverse(path.begin()+1,path.end());
return path;
}
bool Graph_DFS::is_new(std::vector<int>& path) {
return cycles.find(path) == cycles.end();
}
void Graph_DFS::get_statistics(int v, int e, int repetitions, std::string filename) {
std::map<long long,double> stats;
double q, t_median, T_median;
for (int i = 0; i < repetitions; i++) {
Graph_DFS g(v,e,filename);
run_repetition(g, stats);
}
std::map<long long,double>::iterator it = stats.begin();
for (int i = 0; i < stats.size()/2; i++, it++);
if (!(stats.size()%2)) {
t_median = (it->second + (--it)->second)/2;
T_median = (it->first + (++it)->first)/2 * (v + e);
}
else {
t_median = it->second;
T_median = it->first * (v + e);
}
std::cout << "STATS FOR PREDICTED COMPLEXITY O(L*(V+E))" << std::endl;
std::cout.width(15);
std::cout << std::left << "n = L*(V+E)";
std::cout.width(15);
std::cout << std::left << "t(n)";
std::cout.width(15);
std::cout << std::left << "q(n)" << std::endl;
for (auto& i : stats) {
q = i.second / (i.first*(v+e)) * T_median / t_median;
std::cout.width(15);
std::cout << std::left << i.first*(v+e);
std::cout.width(15);
std::cout << std::left << i.second;
std::cout.width(15);
std::cout << std::left << q << std::endl;
}
}
void Graph_DFS::run_repetition(Graph_DFS& g, std::map<long long,double>& stats) {
long long path_length_sum = 0;
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
for (int i = 0; i < g.V; i++) {
if (!g.marked[i]) {
g.DFS(i, -1);
g.path.clear();
}
}
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
for (auto& i : g.cycles) {
path_length_sum += i.size();
}
stats.insert(std::make_pair(path_length_sum,elapsed_seconds.count()));
}