implement dfs

This commit is contained in:
AustrianToast 2024-10-11 00:09:26 +02:00
parent cb5561b35b
commit e5ddece861
Signed by: AustrianToast
GPG Key ID: 1B4D0AAF6E558816
7 changed files with 649 additions and 109 deletions

BIN
gmon.out Normal file

Binary file not shown.

296
graph.c
View File

@ -1,3 +1,4 @@
#include "graph.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
@ -12,27 +13,13 @@ void random_adjacency(const uint64_t vertex_count, uint64_t matrix[vertex_count]
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (column_index == row_index) {
matrix[row_index][column_index] = 0;
continue;
} else {
matrix[row_index][column_index] = rand() % 2;
}
matrix[row_index][column_index] = rand() % 2;
}
}
}
void dfs(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count], const uint64_t vertex, int visited[vertex_count]) {
visited[vertex] = 1;
for (uint64_t neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
continue;
}
if (visited[neighbor_vertex]) {
continue;
}
dfs(vertex_count, adjacency_matrix, neighbor_vertex, visited);
}
}
void calculate_distance_matrix(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count], uint64_t distance_matrix[vertex_count][vertex_count]) {
uint64_t power_matrix[vertex_count][vertex_count];
uint64_t temp_power_matrix[vertex_count][vertex_count];
@ -115,9 +102,7 @@ uint64_t get_diameter(const uint64_t vertex_count, const uint64_t eccentricities
}
void get_centre(const uint64_t vertex_count, const uint64_t eccentricities[vertex_count], const uint64_t radius, uint64_t centre[vertex_count]) {
for (uint64_t index = 0; index < vertex_count; index++) {
centre[index] = 0;
}
memset(centre, 0, vertex_count * sizeof(uint64_t));
for (uint64_t index = 0; index < vertex_count; index++) {
if (eccentricities[index] == radius) {
@ -155,29 +140,15 @@ void calculate_path_matrix(const uint64_t vertex_count, const uint64_t adjacency
}
}
int contains_component(const uint64_t vertex_count, const uint64_t components[vertex_count][vertex_count], const uint64_t component[vertex_count]) {
for (uint64_t index = 0; index < vertex_count; index++) {
if (memcmp(components[index], component, sizeof(components[index])) == 0) {
return 1;
}
}
return 0;
}
void find_components_basic(const uint64_t vertex_count, const uint64_t path_matrix[vertex_count][vertex_count], uint64_t components[vertex_count][vertex_count]) {
uint64_t component[vertex_count];
int contains_component;
memset(components, 0, vertex_count * vertex_count * sizeof(uint64_t));
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
components[row_index][column_index] = UINT64_MAX;
}
}
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
for (uint64_t index = 0; index < vertex_count; index++) {
component[index] = UINT64_MAX;
}
memset(component, 0, vertex_count * sizeof(uint64_t));
contains_component = 0;
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (path_matrix[row_index][column_index] == 1) {
@ -185,9 +156,55 @@ void find_components_basic(const uint64_t vertex_count, const uint64_t path_matr
}
}
if (!contains_component(vertex_count, components, component)) {
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
components[row_index][column_index] = component[column_index];
for (uint64_t index = 0; index < vertex_count; index++) {
if (memcmp(components[index], component, vertex_count * sizeof(uint64_t)) == 0) {
contains_component = 1;
}
}
if (!contains_component) {
for (uint64_t index = 0; index < vertex_count; index++) {
components[row_index][index] = component[index];
}
}
}
}
void dfs(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count], const uint64_t vertex, uint64_t visited[vertex_count]) {
visited[vertex] = 1;
for (uint64_t neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
continue;
}
if (visited[neighbor_vertex]) {
continue;
}
dfs(vertex_count, adjacency_matrix, neighbor_vertex, visited);
}
}
void find_components_dfs(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count], uint64_t components[vertex_count][vertex_count]) {
uint64_t component[vertex_count];
int contains_component = 0;
memset(components, 0, vertex_count * vertex_count * sizeof(uint64_t));
for (uint64_t vertex = 0; vertex < vertex_count; vertex++) {
memset(component, 0, vertex_count * sizeof(uint64_t));
contains_component = 0;
dfs(vertex_count, adjacency_matrix, vertex, component);
for (uint64_t index = 0; index < vertex_count; index++) {
if (memcmp(components[index], component, vertex_count * sizeof(uint64_t)) == 0) {
contains_component = 1;
}
}
if (!contains_component) {
for (uint64_t index = 0; index < vertex_count; index++) {
components[vertex][index] = component[index];
}
}
}
@ -198,7 +215,7 @@ uint64_t amount_of_components(const uint64_t vertex_count, const uint64_t compon
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != UINT64_MAX) {
if (components[row_index][column_index] != 0) {
amount_of_components++;
break;
}
@ -210,7 +227,7 @@ uint64_t amount_of_components(const uint64_t vertex_count, const uint64_t compon
int contains_bridge(const uint64_t vertex_count, const uint64_t bridges[vertex_count][2], const uint64_t bridge[2]) {
for (uint64_t index = 0; index < vertex_count; index++) {
if (memcmp(bridges[index], bridge, sizeof(bridges[index])) == 0) {
if (memcmp(bridges[index], bridge, 2 * sizeof(uint64_t)) == 0) {
return 1;
}
}
@ -225,10 +242,7 @@ void find_bridges_basic(const uint64_t vertex_count, const uint64_t adjacency_ma
uint64_t temp_components[vertex_count][vertex_count];
uint64_t bridge[2];
for (uint64_t index = 0; index < vertex_count; index++) {
bridges[index][0] = UINT64_MAX;
bridges[index][1] = UINT64_MAX;
}
memset(bridges, 0, vertex_count * 2 * sizeof(uint64_t));
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
@ -252,17 +266,102 @@ void find_bridges_basic(const uint64_t vertex_count, const uint64_t adjacency_ma
calculate_path_matrix(vertex_count, temp_adjacency_matrix, path_matrix);
find_components_basic(vertex_count, path_matrix, temp_components);
if (amount_of_components(vertex_count, temp_components) <= amount_of_components(vertex_count, components)) {
bridge[0] = UINT64_MAX;
bridge[1] = UINT64_MAX;
}
if (!contains_bridge(vertex_count, bridges, bridge)) {
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) && !contains_bridge(vertex_count, bridges, bridge)) {
bridges[row_index][0] = bridge[0];
bridges[row_index][1] = bridge[1];
}
}
}
print_matrix(vertex_count, 2, bridges);
}
void find_bridges_dfs_v1(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count], uint64_t bridges[vertex_count][2]) {
uint64_t temp_adjacency_matrix[vertex_count][vertex_count];
uint64_t temp_components[vertex_count][vertex_count];
uint64_t bridge[2];
memset(bridges, 0, vertex_count * 2 * sizeof(uint64_t));
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (row_index == column_index) {
continue;
}
if (column_index < row_index) {
bridge[0] = column_index + 1;
bridge[1] = row_index + 1;
} else {
bridge[0] = row_index + 1;
bridge[1] = column_index + 1;
}
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(uint64_t));
temp_adjacency_matrix[row_index][column_index] = 0;
temp_adjacency_matrix[column_index][row_index] = 0;
find_components_dfs(vertex_count, temp_adjacency_matrix, temp_components);
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) && !contains_bridge(vertex_count, bridges, bridge)) {
bridges[row_index][0] = bridge[0];
bridges[row_index][1] = bridge[1];
}
}
}
}
void dfs_bridges(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count], const uint64_t vertex, const uint64_t parent_vertex, uint64_t visited[vertex_count],
uint64_t current_time, uint64_t discovery_time[vertex_count], uint64_t lowest_time[vertex_count], uint64_t bridges[vertex_count][2]) {
current_time++;
visited[vertex] = 1;
discovery_time[vertex] = current_time;
lowest_time[vertex] = current_time;
for (uint64_t neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
continue;
}
if (parent_vertex != neighbor_vertex && visited[neighbor_vertex]) {
if (lowest_time[vertex] > discovery_time[neighbor_vertex]) {
lowest_time[vertex] = discovery_time[neighbor_vertex];
}
continue;
}
if (visited[neighbor_vertex]) {
continue;
}
dfs_bridges(vertex_count, adjacency_matrix, neighbor_vertex, vertex, visited, current_time, discovery_time, lowest_time, bridges);
if (lowest_time[vertex] > lowest_time[neighbor_vertex]) {
lowest_time[vertex] = lowest_time[neighbor_vertex];
}
if (discovery_time[vertex] < lowest_time[neighbor_vertex]) {
bridges[neighbor_vertex][0] = vertex + 1;
bridges[neighbor_vertex][1] = neighbor_vertex + 1;
}
}
}
void find_bridges_dfs_v2(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count], uint64_t bridges[vertex_count][2]) {
uint64_t visited[vertex_count];
uint64_t current_time = 0;
uint64_t discovery_time[vertex_count];
uint64_t lowest_time[vertex_count];
memset(bridges, 0, vertex_count * 2 * sizeof(uint64_t));
memset(visited, 0, vertex_count * sizeof(uint64_t));
memset(discovery_time, 0, vertex_count * sizeof(uint64_t));
memset(lowest_time, 0, vertex_count * sizeof(uint64_t));
for (uint64_t vertex = 0; vertex < vertex_count; vertex++) {
if (!visited[vertex]) {
dfs_bridges(vertex_count, adjacency_matrix, vertex, UINT64_MAX, visited, current_time, discovery_time, lowest_time, bridges);
}
}
}
void find_articulations_basic(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count],
@ -271,9 +370,7 @@ void find_articulations_basic(const uint64_t vertex_count, const uint64_t adjace
uint64_t temp_adjacency_matrix[vertex_count][vertex_count];
uint64_t temp_components[vertex_count][vertex_count];
for (uint64_t index = 0; index < vertex_count; index++) {
articulations[index] = UINT64_MAX;
}
memset(articulations, 0, vertex_count * sizeof(uint64_t));
for (uint64_t i = 0; i < vertex_count; i++) {
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(uint64_t));
@ -295,3 +392,90 @@ void find_articulations_basic(const uint64_t vertex_count, const uint64_t adjace
}
}
}
void find_articulations_dfs_v1(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count], uint64_t articulations[vertex_count]) {
uint64_t temp_adjacency_matrix[vertex_count][vertex_count];
uint64_t temp_components[vertex_count][vertex_count];
memset(articulations, 0, vertex_count * sizeof(uint64_t));
for (uint64_t i = 0; i < vertex_count; i++) {
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(uint64_t));
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
temp_adjacency_matrix[row_index][i] = 0;
temp_adjacency_matrix[i][column_index] = 0;
}
}
find_components_dfs(vertex_count, temp_adjacency_matrix, temp_components);
// the + 1 is needed because I am not removing the vertex, I am just removing all of its edges
// removing all of its edges, means it itself becomes a component, which needs to be accounted for
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) + 1) {
articulations[i] = i + 1;
}
}
}
void dfs_articulations(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count], const uint64_t vertex, const uint64_t parent_vertex,
uint64_t visited[vertex_count], uint64_t current_time, uint64_t discovery_time[vertex_count], uint64_t lowest_time[vertex_count],
uint64_t articulations[vertex_count]) {
current_time++;
visited[vertex] = 1;
discovery_time[vertex] = current_time;
lowest_time[vertex] = current_time;
uint64_t child_count = 0;
uint64_t is_articulation = 0;
for (uint64_t neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
continue;
}
if (visited[neighbor_vertex]) {
if (lowest_time[vertex] > discovery_time[neighbor_vertex]) {
lowest_time[vertex] = discovery_time[neighbor_vertex];
}
continue;
}
child_count++;
dfs_articulations(vertex_count, adjacency_matrix, neighbor_vertex, vertex, visited, current_time, discovery_time, lowest_time, articulations);
if (lowest_time[vertex] > lowest_time[neighbor_vertex]) {
lowest_time[vertex] = lowest_time[neighbor_vertex];
}
if (parent_vertex != UINT64_MAX && discovery_time[vertex] <= lowest_time[neighbor_vertex]) {
is_articulation = 1;
}
}
if (parent_vertex == UINT64_MAX && child_count > 1) {
is_articulation = 1;
}
if (is_articulation) {
articulations[vertex] = vertex + 1;
}
}
void find_articulations_dfs_v2(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count], uint64_t articulations[vertex_count]) {
uint64_t visited[vertex_count];
uint64_t current_time = 0;
uint64_t discovery_time[vertex_count];
uint64_t lowest_time[vertex_count];
memset(articulations, 0, vertex_count * sizeof(uint64_t));
memset(visited, 0, vertex_count * sizeof(uint64_t));
memset(discovery_time, 0, vertex_count * sizeof(uint64_t));
memset(lowest_time, 0, vertex_count * sizeof(uint64_t));
for (uint64_t vertex = 0; vertex < vertex_count; vertex++) {
if (!visited[vertex]) {
dfs_articulations(vertex_count, adjacency_matrix, vertex, UINT64_MAX, visited, current_time, discovery_time, lowest_time, articulations);
}
}
}

44
graph.h
View File

@ -6,30 +6,21 @@
void random_adjacency(const uint64_t vertex_count,
uint64_t matrix[vertex_count][vertex_count]);
void dfs(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t vertex,
int visited[vertex_count]);
void calculate_distance_matrix(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
uint64_t distance_matrix[vertex_count][vertex_count]);
const uint64_t adjacency_matrix[vertex_count][vertex_count],
uint64_t distance_matrix[vertex_count][vertex_count]);
// returns 1 if it is a disconnected graph and just in case it was on purpose,
// all values in eccentricities will be set to UINT64_MAX
// returns 1 if it is a disconnected graph and sets all values in eccentricities to UINT64_MAX
int get_eccentricities(const uint64_t vertex_count,
const uint64_t distance_matrix[vertex_count][vertex_count],
uint64_t eccentricities[vertex_count]);
const uint64_t distance_matrix[vertex_count][vertex_count],
uint64_t eccentricities[vertex_count]);
// returns the radius or UINT64_MAX in case of a disconnected graph
uint64_t get_radius(const uint64_t vertex_count,
const uint64_t eccentricities[vertex_count]);
// returns the diameter or UINT64_MAX in case of a disconnected graph
uint64_t get_diameter(const uint64_t vertex_count,
const uint64_t eccentricities[vertex_count]);
// in case of a disconnected graph, all nodes will be inside centre
void get_centre(const uint64_t vertex_count,
const uint64_t eccentricities[vertex_count],
const uint64_t radius,
@ -39,19 +30,42 @@ void calculate_path_matrix(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
uint64_t path_matrix[vertex_count][vertex_count]);
// please do not use this yet as the output is currently almost unreadable
void find_components_basic(const uint64_t vertex_count,
const uint64_t path_matrix[vertex_count][vertex_count],
uint64_t components[vertex_count][vertex_count]);
void find_components_dfs(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
uint64_t components[vertex_count][vertex_count]);
void find_bridges_basic(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count],
uint64_t bridges[vertex_count][2]);
void find_bridges_dfs_v1(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count],
uint64_t bridges[vertex_count][2]);
void find_bridges_dfs_v2(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count],
uint64_t bridges[vertex_count][2]);
void find_articulations_basic(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count],
uint64_t articulations[vertex_count]);
void find_articulations_dfs_v1(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count],
uint64_t articulations[vertex_count]);
void find_articulations_dfs_v2(const uint64_t vertex_count,
const uint64_t adjacency_matrix[vertex_count][vertex_count],
const uint64_t components[vertex_count][vertex_count],
uint64_t articulations[vertex_count]);
#endif

170
main.c
View File

@ -1,11 +1,12 @@
#include "graph.h"
#include "matrix.h"
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void benchmark() {
void benchmark_gemm() {
const uint64_t vertex_count1 = 1024;
uint64_t (*matrix1)[vertex_count1] = malloc(vertex_count1 * vertex_count1 * sizeof(uint64_t));
@ -39,7 +40,47 @@ void benchmark() {
free(new_matrix);
}
void test_with_csv() {
void benchmark_find_components() {
const uint64_t vertex_count = 100;
uint64_t adjacency_matrix[vertex_count][vertex_count];
uint64_t components[vertex_count][vertex_count];
uint64_t path_matrix[vertex_count][vertex_count];
double elapsed_time = 0.0;
const uint64_t iterations = 100;
clock_t start_time;
for (uint64_t i = 0; i < iterations; i++) {
random_adjacency(vertex_count, adjacency_matrix);
start_time = clock();
calculate_path_matrix(vertex_count, adjacency_matrix, path_matrix);
find_components_basic(vertex_count, path_matrix, components);
elapsed_time += (double)(clock() - start_time) / CLOCKS_PER_SEC;
}
printf("%lu iterations of find_components_basic took roughly %f seconds\n", iterations, elapsed_time);
printf("An iteration of find_components_basic took on average roughly %f seconds\n", elapsed_time/iterations);
elapsed_time = 0.0;
for (uint64_t i = 0; i < iterations; i++) {
random_adjacency(vertex_count, adjacency_matrix);
start_time = clock();
find_components_dfs(vertex_count, adjacency_matrix, components);
elapsed_time += (double)(clock() - start_time) / CLOCKS_PER_SEC;
}
printf("%lu iterations of find_components_dfs took roughly %f seconds\n", iterations, elapsed_time);
printf("An iteration of find_components_dfs took on average roughly %f seconds\n", elapsed_time/iterations);
}
void test_with_basic() {
const uint64_t vertex_count = 24;
uint64_t adjacency_matrix[vertex_count][vertex_count];
uint64_t distance_matrix[vertex_count][vertex_count];
@ -53,6 +94,7 @@ void test_with_csv() {
if (read_csv("csv/24n.csv", vertex_count, vertex_count, adjacency_matrix) == 1) {
return;
}
calculate_distance_matrix(vertex_count, adjacency_matrix, distance_matrix);
get_eccentricities(vertex_count, distance_matrix, eccentricities);
radius = get_radius(vertex_count, eccentricities);
@ -91,7 +133,7 @@ void test_with_csv() {
int empty = 1;
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != UINT64_MAX) {
if (components[row_index][column_index] != 0) {
empty = 0;
}
}
@ -102,7 +144,7 @@ void test_with_csv() {
printf("\tComponent %lu: {", row_index + 1);
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != UINT64_MAX) {
if (components[row_index][column_index] != 0) {
printf("%lu, ", components[row_index][column_index]);
}
}
@ -111,44 +153,128 @@ void test_with_csv() {
puts("\nbridges:");
for (uint64_t index = 0; index < vertex_count; index++) {
if (bridges[index][0] != UINT64_MAX) {
if (bridges[index][0] != 0) {
printf("\tBridge %lu: {%lu, %lu}\n", index + 1, bridges[index][0], bridges[index][1]);
}
}
puts("\narticulations:");
for (uint64_t index = 0; index < vertex_count; index++) {
if (articulations[index] != UINT64_MAX) {
if (articulations[index] != 0) {
printf("\tVertex %lu\n", articulations[index]);
}
}
}
void test_dfs() {
const uint64_t vertex_count = 7;
void test_with_dfs() {
const uint64_t vertex_count = 24;
uint64_t adjacency_matrix[vertex_count][vertex_count];
int visited[vertex_count];
uint64_t distance_matrix[vertex_count][vertex_count];
uint64_t eccentricities[vertex_count];
uint64_t radius, diameter;
uint64_t centre[vertex_count];
uint64_t components[vertex_count][vertex_count];
uint64_t bridges[vertex_count][2];
uint64_t articulations[vertex_count];
if (read_csv("csv/7n.csv", vertex_count, vertex_count, adjacency_matrix) == 1) {
if (read_csv("csv/24n.csv", vertex_count, vertex_count, adjacency_matrix) == 1) {
return;
}
for (uint64_t vertex = 0; vertex < vertex_count; vertex++) {
for (uint64_t index = 0; index < vertex_count; index++) {
visited[index] = 0;
}
/*
const uint64_t vertex_count = 1500;
uint64_t (*adjacency_matrix)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(uint64_t));
uint64_t (*distance_matrix)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(uint64_t));
uint64_t *eccentricities = malloc(vertex_count * sizeof(uint64_t));
uint64_t radius, diameter;
uint64_t *centre = malloc(vertex_count * sizeof(uint64_t));
uint64_t (*components)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(uint64_t));
uint64_t (*bridges)[vertex_count] = malloc(vertex_count * 2 * sizeof(uint64_t));
uint64_t *articulations = malloc(vertex_count * sizeof(uint64_t));
dfs(vertex_count, adjacency_matrix, vertex, visited);
random_adjacency(vertex_count, adjacency_matrix);
*/
for (uint64_t index = 0; index < vertex_count; index++) {
printf("%d", visited[index]);
}
printf("\n");
calculate_distance_matrix(vertex_count, adjacency_matrix, distance_matrix);
get_eccentricities(vertex_count, distance_matrix, eccentricities);
radius = get_radius(vertex_count, eccentricities);
diameter = get_diameter(vertex_count, eccentricities);
get_centre(vertex_count, eccentricities, radius, centre);
find_components_dfs(vertex_count, adjacency_matrix, components);
find_bridges_dfs_v2(vertex_count, adjacency_matrix, components, bridges);
find_articulations_dfs_v2(vertex_count, adjacency_matrix, components, articulations);
puts("\nadjacency_matrix:");
print_matrix(vertex_count, vertex_count, adjacency_matrix);
puts("\ndistance_matrix:");
print_matrix(vertex_count, vertex_count, distance_matrix);
puts("\neccentricities:");
for (uint64_t index = 0; index < vertex_count; index++) {
printf("\tVertex %lu: %lu\n", index + 1, eccentricities[index]);
}
printf("\nradius: %lu", radius);
printf("\ndiameter: %lu", diameter);
puts("\ncentre:");
for (uint64_t index = 0; index < vertex_count; index++) {
if (centre[index] == 1) {
printf("\tVertex %lu\n", index + 1);
}
}
puts("\ncomponents:");
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
int empty = 1;
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != 0) {
empty = 0;
}
}
if (empty) {
continue;
}
printf("\tComponent %lu: {", row_index + 1);
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != 0) {
printf("%lu, ", column_index + 1);
}
}
puts("}");
}
uint64_t bridge_number = 1;
puts("\nbridges:");
for (uint64_t index = 0; index < vertex_count; index++) {
if (bridges[index][0] != 0) {
printf("\tBridge %lu: {%lu, %lu}\n", bridge_number, bridges[index][0], bridges[index][1]);
bridge_number++;
}
}
puts("\narticulations:");
for (uint64_t index = 0; index < vertex_count; index++) {
if (articulations[index] != 0) {
printf("\tVertex %lu\n", articulations[index]);
}
}
// free(adjacency_matrix);
// free(distance_matrix);
// free(eccentricities);
// free(centre);
// free(components);
// free(bridges);
// free(articulations);
}
int main(void) {
test_with_csv();
// test_dfs();
// benchmark();
// test_with_basic();
test_with_dfs();
// benchmark_gemm();
// benchmark_find_components();
}

View File

@ -14,13 +14,9 @@ void print_matrix(const uint64_t row_length, const uint64_t column_length, const
}
}
int gemm_basic(const uint64_t row_length1, const uint64_t column_length1, const uint64_t matrix1[row_length1][column_length1],
void gemm_basic(const uint64_t row_length1, const uint64_t column_length1, const uint64_t matrix1[row_length1][column_length1],
const uint64_t row_length2, const uint64_t column_length2, const uint64_t matrix2[row_length2][column_length2],
uint64_t output_matrix[row_length1][column_length2]) {
if (row_length1 != column_length2) {
return 1;
}
uint64_t sum;
for (uint64_t i = 0; i < row_length1; i++) {
@ -34,8 +30,6 @@ int gemm_basic(const uint64_t row_length1, const uint64_t column_length1, const
output_matrix[i][j] = sum;
}
}
return 0;
}
int read_csv(const char *file_name, const uint64_t row_length, const uint64_t column_length, uint64_t output_matrix[row_length][column_length]) {

View File

@ -10,16 +10,15 @@ void print_matrix(const uint64_t row_length,
/*
First two matrices will be multiplied and
restult will be written to output_matrix.
Matrix requirements are as specified in the parameters.
Function return 0 on success and 1 on failure.
Matrix size requirements are as specified in the parameters.
*/
int gemm_basic(const uint64_t row_length1,
const uint64_t column_length1,
const uint64_t matrix1[row_length1][column_length1],
const uint64_t row_length2,
const uint64_t column_length2,
const uint64_t matrix2[row_length2][column_length2],
uint64_t output_matrix[row_length1][column_length2]);
void gemm_basic(const uint64_t row_length1,
const uint64_t column_length1,
const uint64_t matrix1[row_length1][column_length1],
const uint64_t row_length2,
const uint64_t column_length2,
const uint64_t matrix2[row_length2][column_length2],
uint64_t output_matrix[row_length1][column_length2]);
int read_csv(char *file_name,
uint64_t row_length,

223
prof_output Normal file
View File

@ -0,0 +1,223 @@
Flat profile:
Each sample counts as 0.01 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 24 0.00 0.00 dfs
0.00 0.00 0.00 23 0.00 0.00 gemm_basic
0.00 0.00 0.00 2 0.00 0.00 print_matrix
0.00 0.00 0.00 1 0.00 0.00 calculate_distance_matrix
0.00 0.00 0.00 1 0.00 0.00 dfs_articulations
0.00 0.00 0.00 1 0.00 0.00 dfs_bridges
0.00 0.00 0.00 1 0.00 0.00 find_articulations_dfs_v2
0.00 0.00 0.00 1 0.00 0.00 find_bridges_dfs_v2
0.00 0.00 0.00 1 0.00 0.00 find_components_dfs
0.00 0.00 0.00 1 0.00 0.00 get_centre
0.00 0.00 0.00 1 0.00 0.00 get_diameter
0.00 0.00 0.00 1 0.00 0.00 get_eccentricities
0.00 0.00 0.00 1 0.00 0.00 get_radius
0.00 0.00 0.00 1 0.00 0.00 read_csv
0.00 0.00 0.00 1 0.00 0.00 test_with_dfs
% the percentage of the total running time of the
time program used by this function.
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
calls the number of times this function was invoked, if
this function is profiled, else blank.
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
Copyright (C) 2012-2024 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
Call graph (explanation follows)
granularity: each sample hit covers 2 byte(s) no time propagated
index % time self children called name
552 dfs [1]
0.00 0.00 24/24 find_components_dfs [9]
[1] 0.0 0.00 0.00 24+552 dfs [1]
552 dfs [1]
-----------------------------------------------
0.00 0.00 23/23 calculate_distance_matrix [4]
[2] 0.0 0.00 0.00 23 gemm_basic [2]
-----------------------------------------------
0.00 0.00 2/2 test_with_dfs [15]
[3] 0.0 0.00 0.00 2 print_matrix [3]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[4] 0.0 0.00 0.00 1 calculate_distance_matrix [4]
0.00 0.00 23/23 gemm_basic [2]
-----------------------------------------------
23 dfs_articulations [5]
0.00 0.00 1/1 find_articulations_dfs_v2 [7]
[5] 0.0 0.00 0.00 1+23 dfs_articulations [5]
23 dfs_articulations [5]
-----------------------------------------------
23 dfs_bridges [6]
0.00 0.00 1/1 find_bridges_dfs_v2 [8]
[6] 0.0 0.00 0.00 1+23 dfs_bridges [6]
23 dfs_bridges [6]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[7] 0.0 0.00 0.00 1 find_articulations_dfs_v2 [7]
0.00 0.00 1/1 dfs_articulations [5]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[8] 0.0 0.00 0.00 1 find_bridges_dfs_v2 [8]
0.00 0.00 1/1 dfs_bridges [6]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[9] 0.0 0.00 0.00 1 find_components_dfs [9]
0.00 0.00 24/24 dfs [1]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[10] 0.0 0.00 0.00 1 get_centre [10]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[11] 0.0 0.00 0.00 1 get_diameter [11]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[12] 0.0 0.00 0.00 1 get_eccentricities [12]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[13] 0.0 0.00 0.00 1 get_radius [13]
-----------------------------------------------
0.00 0.00 1/1 test_with_dfs [15]
[14] 0.0 0.00 0.00 1 read_csv [14]
-----------------------------------------------
0.00 0.00 1/1 main [29]
[15] 0.0 0.00 0.00 1 test_with_dfs [15]
0.00 0.00 2/2 print_matrix [3]
0.00 0.00 1/1 read_csv [14]
0.00 0.00 1/1 calculate_distance_matrix [4]
0.00 0.00 1/1 get_eccentricities [12]
0.00 0.00 1/1 get_radius [13]
0.00 0.00 1/1 get_diameter [11]
0.00 0.00 1/1 get_centre [10]
0.00 0.00 1/1 find_components_dfs [9]
0.00 0.00 1/1 find_bridges_dfs_v2 [8]
0.00 0.00 1/1 find_articulations_dfs_v2 [7]
-----------------------------------------------
This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.
Each entry in this table consists of several lines. The line with the
index number at the left hand margin lists the current function.
The lines above it list the functions that called this function,
and the lines below it list the functions this one called.
This line lists:
index A unique number given to each element of the table.
Index numbers are sorted numerically.
The index number is printed next to every function name so
it is easier to look up where the function is in the table.
% time This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.
self This is the total amount of time spent in this function.
children This is the total amount of time propagated into this
function by its children.
called This is the number of times the function was called.
If the function called itself recursively, the number
only includes non-recursive calls, and is followed by
a `+' and the number of recursive calls.
name The name of the current function. The index number is
printed after it. If the function is a member of a
cycle, the cycle number is printed between the
function's name and the index number.
For the function's parents, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the function into this parent.
children This is the amount of time that was propagated from
the function's children into this parent.
called This is the number of times this parent called the
function `/' the total number of times the function
was called. Recursive calls to the function are not
included in the number after the `/'.
name This is the name of the parent. The parent's index
number is printed after it. If the parent is a
member of a cycle, the cycle number is printed between
the name and the index number.
If the parents of the function cannot be determined, the word
`<spontaneous>' is printed in the `name' field, and all the other
fields are blank.
For the function's children, the fields have the following meanings:
self This is the amount of time that was propagated directly
from the child into the function.
children This is the amount of time that was propagated from the
child's children to the function.
called This is the number of times the function called
this child `/' the total number of times the child
was called. Recursive calls by the child are not
listed in the number after the `/'.
name This is the name of the child. The child's index
number is printed after it. If the child is a
member of a cycle, the cycle number is printed
between the name and the index number.
If there are any cycles (circles) in the call graph, there is an
entry for the cycle-as-a-whole. This entry shows who called the
cycle (as parents) and the members of the cycle (as children.)
The `+' recursive calls entry shows the number of function calls that
were internal to the cycle, and the calls entry for each member shows,
for that member, how many times it was called from other members of
the cycle.
Copyright (C) 2012-2024 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
Index by function name
[4] calculate_distance_matrix [8] find_bridges_dfs_v2 [12] get_eccentricities
[1] dfs [9] find_components_dfs [13] get_radius
[5] dfs_articulations [2] gemm_basic [3] print_matrix
[6] dfs_bridges [10] get_centre [14] read_csv
[7] find_articulations_dfs_v2 [11] get_diameter [15] test_with_dfs