Skip to content

Commit b99ae8d

Browse files
committed
Final code
1 parent c8c31b2 commit b99ae8d

6 files changed

Lines changed: 163 additions & 118 deletions

File tree

2/ford_fulkerson.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
#include <random>
33

44
void adjacency_matrix::fill_graph(
5-
size_t vertices,
6-
mdspan<capacity, std::extents<size_t, std::dynamic_extent, std::dynamic_extent>> graph,
7-
capacity max_capacity,
8-
double prob) {
5+
size_t vertices,
6+
mdspan<capacity, std::extents<size_t, std::dynamic_extent, std::dynamic_extent>> graph,
7+
capacity max_capacity,
8+
double prob) {
99
thread_local mt19937_64 rng(0);
1010

1111
uniform_int_distribution<capacity> capacity_dist(1, max_capacity);
@@ -18,4 +18,4 @@ double prob) {
1818
}
1919
}
2020
}
21-
}
21+
}

2/ford_fulkerson.hpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@ using capacity = int16_t;
1616

1717
namespace adjacency_matrix {
1818

19-
void fill_graph(
20-
size_t vertices,
21-
mdspan<capacity, std::extents<size_t, std::dynamic_extent, std::dynamic_extent>> graph,
22-
capacity max_capacity,
23-
double prob);
19+
using Graph = mdspan<capacity, std::extents<size_t, std::dynamic_extent, std::dynamic_extent>>;
20+
21+
void fill_graph(size_t vertices, Graph graph, capacity max_capacity, double prob);
22+
23+
void fill_graph_with_fixed_max_flow(size_t vertices,
24+
Graph graph,
25+
capacity max_capacity,
26+
double prob);
2427

2528
class FordFulkerson {
2629
public:
@@ -68,11 +71,11 @@ class FordFulkerson {
6871

6972
vector<capacity> raw_graph;
7073
size_t vertices;
71-
mdspan<capacity, std::extents<size_t, std::dynamic_extent, std::dynamic_extent>> graph;
74+
Graph graph;
7275
vector<uint32_t> parent;
73-
vector<bool> visited;
74-
int64_t touched_vertices = 1;
75-
int64_t touched_edges = 1;
76+
vector<uint8_t> visited;
77+
uint64_t touched_vertices = 1;
78+
uint64_t touched_edges = 1;
7679
};
7780

7881
class FordFulkersonDFS final : public FordFulkerson {

2/mount_graphs.py

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,101 @@
11
import pandas as pd
2+
from scipy.stats import linregress
23
import matplotlib.pyplot as plt
34

4-
if __name__ == "__main__":
5-
df = pd.read_csv("edge_stats.csv")
5+
out_directory = "graphs"
66

7+
def draw_edges(df, col, label):
78
x = df["edges"]
9+
y = df[f"{col} time (ms)"]
10+
plt.scatter(x, y, label=label)
811

9-
plt.scatter(x, df["dfs time (ms)"], label="DFS")
10-
plt.scatter(x, df["bfs time (ms)"], label="BFS")
11-
plt.scatter(x, df["fat time (ms)"], label="Fattest path")
12+
slope, intercept, r_value, p_value, std_err = linregress(x, y)
13+
plt.plot(x, intercept + slope * x, 'r', label=f"Regressão linear (r={round(r_value,2)})")
1214

13-
plt.xlabel("Edge amount")
14-
plt.ylabel("Time (ms)")
15+
plt.xlabel("Quantidade de arestas")
16+
plt.ylabel("Tempo (ms)")
1517
plt.legend()
1618

17-
plt.savefig("edge_x_time_edges.png", format="png")
19+
plt.savefig(f"{out_directory}/edge_x_time_{col}.eps")
1820
plt.clf()
1921

20-
plt.scatter(x, df["dfs vertices"], label="DFS")
21-
plt.scatter(x, df["bfs vertices"], label="BFS")
22-
plt.scatter(x, df["fat vertices"], label="Fattest path")
22+
y = df[f"{col} vertices"]
23+
plt.scatter(x, y, label=label)
2324

24-
plt.xlabel("Edge amount")
25-
plt.ylabel("Vertices touched")
25+
slope, intercept, r_value, p_value, std_err = linregress(x, y)
26+
plt.plot(x, intercept + slope * x, 'r', label=f"Regressão linear (r={round(r_value,2)})")
27+
28+
plt.xlabel("Quantidade de arestas")
29+
plt.ylabel("Vértices tocados")
2630
plt.legend()
2731

28-
plt.savefig("vertices_touched_edges.png", format="png")
32+
plt.savefig(f"{out_directory}/vertices_touched_edges_{col}.eps")
2933
plt.clf()
3034

31-
plt.scatter(x, df["dfs edges"], label="DFS")
32-
plt.scatter(x, df["bfs edges"], label="BFS")
33-
plt.scatter(x, df["fat edges"], label="Fattest path")
35+
y = df[f"{col} edges"]
36+
plt.scatter(x, y, label=label)
3437

35-
plt.xlabel("Edge amount")
36-
plt.ylabel("Edges touched")
38+
slope, intercept, r_value, p_value, std_err = linregress(x, y)
39+
plt.plot(x, intercept + slope * x, 'r', label=f"Regressão linear (r={round(r_value,2)})")
40+
41+
plt.xlabel("Quantidade de arestas")
42+
plt.ylabel("Arestas tocadas")
3743
plt.legend()
3844

39-
plt.savefig("edges_touched_edges.png", format="png")
45+
plt.savefig(f"{out_directory}/edges_touched_edges_{col}.eps")
4046
plt.clf()
4147

42-
df = pd.read_csv("max_flow_stats.csv")
43-
48+
def draw_flow(df, col, label):
4449
x = df["max_flow"]
50+
y = df[f"{col} time (ms)"]
51+
plt.scatter(x, y, label=label)
4552

46-
plt.scatter(x, df["dfs time (ms)"], label="DFS")
47-
plt.scatter(x, df["bfs time (ms)"], label="BFS")
48-
plt.scatter(x, df["fat time (ms)"], label="Fattest path")
53+
slope, intercept, r_value, p_value, std_err = linregress(x, y)
54+
plt.plot(x, intercept + slope * x, 'r', label=f"Regressão linear (r={round(r_value,2)})")
4955

50-
plt.xlabel("Edge amount")
56+
plt.xlabel("Max flow")
5157
plt.ylabel("Time (ms)")
5258
plt.legend()
5359

54-
plt.savefig("edge_x_time_max_flow.png", format="png")
60+
plt.savefig(f"{out_directory}/max_flow_x_time_{col}.eps")
5561
plt.clf()
5662

57-
plt.scatter(x, df["dfs vertices"], label="DFS")
58-
plt.scatter(x, df["bfs vertices"], label="BFS")
59-
plt.scatter(x, df["fat vertices"], label="Fattest path")
63+
y = df[f"{col} vertices"]
64+
plt.scatter(x, y, label=label)
65+
66+
slope, intercept, r_value, p_value, std_err = linregress(x, y)
67+
plt.plot(x, intercept + slope * x, 'r', label=f"Regressão linear (r={round(r_value,2)})")
6068

61-
plt.xlabel("Edge amount")
69+
plt.xlabel("Max flow")
6270
plt.ylabel("Vertices touched")
6371
plt.legend()
6472

65-
plt.savefig("vertices_touched_max_flow.png", format="png")
73+
plt.savefig(f"{out_directory}/vertices_touched_max_flow_{col}.eps")
6674
plt.clf()
6775

68-
plt.scatter(x, df["dfs edges"], label="DFS")
69-
plt.scatter(x, df["bfs edges"], label="BFS")
70-
plt.scatter(x, df["fat edges"], label="Fattest path")
76+
y = df[f"{col} edges"]
77+
plt.scatter(x, y, label=label)
7178

72-
plt.xlabel("Edge amount")
79+
slope, intercept, r_value, p_value, std_err = linregress(x, y)
80+
plt.plot(x, intercept + slope * x, 'r', label=f"Regressão linear (r={round(r_value,2)})")
81+
82+
plt.xlabel("Max flow")
7383
plt.ylabel("Edges touched")
7484
plt.legend()
7585

76-
plt.savefig("edges_touched_max_flow.png", format="png")
86+
plt.savefig(f"{out_directory}/edges_touched_max_flow_{col}.eps")
7787
plt.clf()
7888

89+
if __name__ == "__main__":
90+
df = pd.read_csv("edge_stats.csv")
91+
92+
samples = {"dfs": "DFS", "bfs": "BFS", "fat": "Fattest Path"}
93+
94+
95+
for col, label in samples.items():
96+
draw_edges(df, col, label)
97+
98+
df = pd.read_csv("max_flow_stats.csv")
99+
100+
for col, label in samples.items():
101+
draw_flow(df, col, label)

2/test_capacity.cpp

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,79 @@
22
#include <chrono>
33

44
#include <iostream>
5-
#include <random>
65
#include <syncstream>
76
#include <vector>
87

98
#include "ford_fulkerson.hpp"
109

1110
using namespace std;
1211

13-
int main() {
14-
constexpr size_t VERTICE = 5'000;
15-
constexpr size_t CAPACITY_AMOUNT = 10;
16-
constexpr int REPETITIONS = 3;
17-
vector max_capacities = {128};
12+
constexpr int CAPACITY_AMOUNT = 20;
13+
constexpr capacity MAX_CAPACITY = numeric_limits<capacity>::max() / (CAPACITY_AMOUNT - 1);
1814

19-
for (size_t i = 1; i < CAPACITY_AMOUNT; ++i) {
20-
max_capacities.push_back(max_capacities[0] * (i + 1));
15+
namespace {
16+
void increase_capacity(adjacency_matrix::Graph graph, int a) {
17+
if (a == 0) {
18+
return;
19+
}
20+
21+
size_t vertices = graph.extent(0);
22+
for (size_t i = 0; i < vertices; ++i) {
23+
for (size_t j = i + 1; j < vertices; ++j) {
24+
if (graph[i, j] > 0) {
25+
graph[i, j] += MAX_CAPACITY * a;
26+
}
27+
}
2128
}
29+
}
30+
}
31+
32+
int main() {
33+
constexpr size_t VERTEX = 10'000;
34+
constexpr int REPETITIONS = 3;
2235

2336
cout << "max_flow,dfs vertices,dfs edges,dfs time (ms),bfs vertices,bfs "
2437
"edges,bfs time (ms),fat vertices,fat edges,fat time (ms)\n";
2538

26-
#pragma omp parallel for collapse(2)
27-
for (int i = 0; i < max_capacities.size(); ++i) {
28-
for (int j = 0; j < REPETITIONS; ++j) {
29-
double max_capacity = max_capacities[i];
30-
const uint32_t s = 0;
31-
const uint32_t t = VERTICE - 1;
39+
vector<capacity> raw_graph(VERTEX * VERTEX);
40+
const mdspan graph(raw_graph.data(), VERTEX, VERTEX);
3241

33-
vector<capacity> raw_graph(VERTICE * VERTICE);
34-
const mdspan graph(raw_graph.data(), VERTICE, VERTICE);
42+
constexpr double edge_prob = 0.5;
3543

36-
constexpr double edge_prob = 0.5;
37-
constexpr size_t max_edges = VERTICE * (VERTICE - 1);
44+
adjacency_matrix::fill_graph(VERTEX, graph, MAX_CAPACITY, edge_prob);
45+
46+
for (size_t i = 0; i < (VERTEX - 1); ++i) {
47+
graph[i, i + 1] = MAX_CAPACITY;
48+
}
3849

39-
adjacency_matrix::fill_graph(VERTICE, graph, max_capacity, edge_prob);
50+
#pragma omp parallel for
51+
for (int i = 0; i < CAPACITY_AMOUNT; ++i) {
52+
vector<capacity> raw_graph_i(raw_graph);
53+
const mdspan graph_i(raw_graph_i.data(), VERTEX, VERTEX);
54+
55+
increase_capacity(graph_i, i);
56+
57+
for (int j = 0; j < REPETITIONS; ++j) {
58+
const uint32_t s = 0;
59+
const uint32_t t = VERTEX - 1;
4060

4161
auto dfs_start = chrono::high_resolution_clock::now();
4262

43-
adjacency_matrix::FordFulkersonDFS dfs_instance(raw_graph, VERTICE);
63+
adjacency_matrix::FordFulkersonDFS dfs_instance(raw_graph_i, VERTEX);
4464

4565
auto max_flow = dfs_instance.max_flow(s, t);
4666

4767
auto bfs_start = chrono::high_resolution_clock::now();
4868
chrono::duration dfs_duration = bfs_start - dfs_start;
4969

50-
adjacency_matrix::FordFulkersonBFS bfs_instance(raw_graph, VERTICE);
70+
adjacency_matrix::FordFulkersonBFS bfs_instance(raw_graph_i, VERTEX);
5171

5272
bfs_instance.max_flow(s, t);
5373

5474
auto fat_start = chrono::high_resolution_clock::now();
5575
chrono::duration bfs_duration = fat_start - bfs_start;
5676

57-
adjacency_matrix::FordFulkersonFattestPath fattest_path_instance(raw_graph, VERTICE);
77+
adjacency_matrix::FordFulkersonFattestPath fattest_path_instance(raw_graph_i, VERTEX);
5878

5979
fattest_path_instance.max_flow(s, t);
6080

@@ -64,7 +84,7 @@ int main() {
6484

6585
osyncstream so(cout);
6686

67-
so << VERTICE << ',' << max_flow << ',' << dfs_instance.touched_vertices << ','
87+
so << max_flow << ',' << dfs_instance.touched_vertices << ','
6888
<< dfs_instance.touched_edges << ',' << dfs_duration.count() << ','
6989
<< bfs_instance.touched_vertices << ',' << bfs_instance.touched_edges << ','
7090
<< bfs_duration.count() << ',' << fattest_path_instance.touched_vertices << ','

0 commit comments

Comments
 (0)