done with basic implementation

This commit is contained in:
AustrianToast 2024-10-10 00:44:00 +02:00
parent 21fb373f65
commit cb5561b35b
Signed by: AustrianToast
GPG Key ID: 1B4D0AAF6E558816
7 changed files with 191 additions and 83 deletions

View File

@ -1,5 +0,0 @@
0;0;1;1;0
0;0;1;1;0
1;1;0;1;0
1;1;1;0;1
0;0;0;1;0
1 0 0 1 1 0
2 0 0 1 1 0
3 1 1 0 1 0
4 1 1 1 0 1
5 0 0 0 1 0

143
graph.c
View File

@ -19,6 +19,20 @@ void random_adjacency(const uint64_t vertex_count, uint64_t matrix[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]) {
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];
@ -141,16 +155,39 @@ void calculate_path_matrix(const uint64_t vertex_count, const uint64_t adjacency
}
}
/* TODO
* Remove stupid solution for connected graph inside the if statement and implement an actual solution for checking of duplicate components
*/
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];
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 (path_matrix[row_index][column_index] == 1 && components[0][column_index] != column_index + 1) {
components[row_index][column_index] = column_index + 1;
} else {
components[row_index][column_index] = UINT64_MAX;
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;
}
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (path_matrix[row_index][column_index] == 1) {
component[column_index] = column_index + 1;
}
}
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];
}
}
}
@ -158,28 +195,40 @@ void find_components_basic(const uint64_t vertex_count, const uint64_t path_matr
uint64_t amount_of_components(const uint64_t vertex_count, const uint64_t components[vertex_count][vertex_count]) {
uint64_t amount_of_components = 0;
int is_valid_component = 0;
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) {
is_valid_component = 1;
amount_of_components++;
break;
}
}
if (is_valid_component) {
amount_of_components++;
}
}
return amount_of_components;
}
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) {
return 1;
}
}
return 0;
}
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]) {
uint64_t path_matrix[vertex_count][vertex_count];
uint64_t temp_adjacency_matrix[vertex_count][vertex_count];
calculate_path_matrix(vertex_count, temp_adjacency_matrix, path_matrix);
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;
}
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
@ -187,8 +236,13 @@ void find_bridges_basic(const uint64_t vertex_count, const uint64_t adjacency_ma
continue;
}
bridges[row_index][0] = UINT64_MAX;
bridges[row_index][1] = UINT64_MAX;
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));
@ -198,31 +252,46 @@ 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);
puts("temp_components:");
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
printf("\tComponent %lu: {", row_index + 1);
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
if (temp_components[row_index][column_index] != UINT64_MAX) {
printf("%lu, ", temp_components[row_index][column_index]);
}
}
puts("}");
if (amount_of_components(vertex_count, temp_components) <= amount_of_components(vertex_count, components)) {
bridge[0] = UINT64_MAX;
bridge[1] = UINT64_MAX;
}
puts("");
printf("amount_of_components: %lu\n", amount_of_components(vertex_count, temp_components));
// TODO
// I need a way to compare the amount of components
if (1) {
continue;
}
if (column_index < row_index) {
bridges[row_index][0] = column_index + 1;
bridges[row_index][1] = row_index + 1;
} else {
bridges[row_index][0] = row_index + 1;
bridges[row_index][1] = column_index + 1;
if (!contains_bridge(vertex_count, bridges, bridge)) {
bridges[row_index][0] = bridge[0];
bridges[row_index][1] = bridge[1];
}
}
}
}
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]) {
uint64_t path_matrix[vertex_count][vertex_count];
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;
}
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;
}
}
calculate_path_matrix(vertex_count, temp_adjacency_matrix, path_matrix);
find_components_basic(vertex_count, path_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;
}
}
}

10
graph.h
View File

@ -6,6 +6,11 @@
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]);
@ -44,4 +49,9 @@ void find_bridges_basic(const uint64_t 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]);
#endif

112
main.c
View File

@ -39,8 +39,8 @@ void benchmark() {
free(new_matrix);
}
void test() {
const uint64_t vertex_count = 5;
void test_with_csv() {
const uint64_t vertex_count = 24;
uint64_t adjacency_matrix[vertex_count][vertex_count];
uint64_t distance_matrix[vertex_count][vertex_count];
uint64_t path_matrix[vertex_count][vertex_count];
@ -48,51 +48,58 @@ void test() {
uint64_t radius, diameter, centre[vertex_count];
uint64_t components[vertex_count][vertex_count];
uint64_t bridges[vertex_count][2];
uint64_t articulations[vertex_count];
read_csv("csv/graph.csv", vertex_count, vertex_count, adjacency_matrix);
puts("G:");
print_matrix(vertex_count, vertex_count, adjacency_matrix);
puts("");
calculate_distance_matrix(vertex_count, adjacency_matrix, distance_matrix);
puts("distance_matrix:");
print_matrix(vertex_count, vertex_count, distance_matrix);
puts("");
get_eccentricities(vertex_count, distance_matrix, eccentricities);
puts("eccentricities:");
for (uint64_t index = 0; index < vertex_count; index++) {
printf("\tVertex %lu: %lu\n", index + 1, eccentricities[index]);
if (read_csv("csv/24n.csv", vertex_count, vertex_count, adjacency_matrix) == 1) {
return;
}
puts("");
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);
calculate_path_matrix(vertex_count, adjacency_matrix, path_matrix);
find_components_basic(vertex_count, path_matrix, components);
find_bridges_basic(vertex_count, adjacency_matrix, components, bridges);
find_articulations_basic(vertex_count, adjacency_matrix, components, articulations);
printf("radius: %lu\n", radius);
printf("diameter: %lu\n", diameter);
puts("centre:");
puts("adjacency_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("");
calculate_path_matrix(vertex_count, adjacency_matrix, path_matrix);
puts("path_matrix:");
puts("\npath_matrix:");
print_matrix(vertex_count, vertex_count, path_matrix);
puts("");
find_components_basic(vertex_count, path_matrix, components);
puts("components:");
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] != UINT64_MAX) {
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] != UINT64_MAX) {
@ -101,20 +108,47 @@ void test() {
}
puts("}");
}
puts("");
find_bridges_basic(vertex_count, path_matrix, components, bridges);
puts("bridges:");
puts("\nbridges:");
for (uint64_t index = 0; index < vertex_count; index++) {
if (bridges[index][0] != UINT64_MAX) {
printf("\tBridge %lu: {%lu, %lu}", index + 1, bridges[index][0], bridges[index][1]);
printf("\tBridge %lu: {%lu, %lu}\n", index + 1, bridges[index][0], bridges[index][1]);
}
}
puts("");
puts("\narticulations:");
for (uint64_t index = 0; index < vertex_count; index++) {
if (articulations[index] != UINT64_MAX) {
printf("\tVertex %lu\n", articulations[index]);
}
}
}
void test_dfs() {
const uint64_t vertex_count = 7;
uint64_t adjacency_matrix[vertex_count][vertex_count];
int visited[vertex_count];
if (read_csv("csv/7n.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;
}
dfs(vertex_count, adjacency_matrix, vertex, visited);
for (uint64_t index = 0; index < vertex_count; index++) {
printf("%d", visited[index]);
}
printf("\n");
}
}
int main(void) {
test();
test_with_csv();
// test_dfs();
// benchmark();
}

View File

@ -27,7 +27,7 @@ int gemm_basic(const uint64_t row_length1, const uint64_t column_length1, const
for (uint64_t j = 0; j < column_length2; j++) {
sum = 0;
for (uint64_t k = 0; k <row_length1; k++) {
for (uint64_t k = 0; k < row_length1; k++) {
sum += matrix1[i][k] * matrix2[k][j];
}
@ -40,7 +40,7 @@ int gemm_basic(const uint64_t row_length1, const uint64_t column_length1, const
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]) {
FILE *file_ptr;
uint64_t bufsize = row_length*2; // have to account for delimiters
uint64_t bufsize = row_length*2+1; // have to account for delimiters
char buffer[bufsize];
char *value, *file_line;
uint64_t row_index = 0, column_index = 0;