2024-09-26 14:32:20 +02:00
|
|
|
#include <stdint.h>
|
2024-10-04 16:46:40 +02:00
|
|
|
#include <stdio.h>
|
2024-10-09 15:35:17 +02:00
|
|
|
#include <string.h>
|
2024-09-26 14:32:20 +02:00
|
|
|
#include <time.h>
|
|
|
|
#include <stdlib.h>
|
2024-10-04 17:36:40 +02:00
|
|
|
#include "matrix.h"
|
2024-09-26 14:32:20 +02:00
|
|
|
|
2024-10-04 13:05:02 +02:00
|
|
|
void random_adjacency(const uint64_t vertex_count, uint64_t matrix[vertex_count][vertex_count]) {
|
2024-09-26 14:32:20 +02:00
|
|
|
srand(time(NULL));
|
|
|
|
|
2024-10-07 09:03:29 +02:00
|
|
|
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
|
|
|
|
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
|
2024-10-04 17:36:40 +02:00
|
|
|
if (column_index == row_index) {
|
2024-10-04 01:03:39 +02:00
|
|
|
matrix[row_index][column_index] = 0;
|
2024-09-26 14:32:20 +02:00
|
|
|
continue;
|
|
|
|
}
|
2024-10-07 09:03:29 +02:00
|
|
|
matrix[row_index][column_index] = rand() % 2;
|
2024-09-26 14:32:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-10-04 13:05:02 +02:00
|
|
|
|
2024-10-04 17:36:40 +02:00
|
|
|
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];
|
2024-10-07 09:03:29 +02:00
|
|
|
uint64_t temp_power_matrix[vertex_count][vertex_count];
|
2024-10-09 15:35:17 +02:00
|
|
|
memcpy(power_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(uint64_t));
|
2024-10-04 17:36:40 +02:00
|
|
|
|
2024-10-07 09:03:29 +02:00
|
|
|
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) {
|
2024-10-04 17:36:40 +02:00
|
|
|
distance_matrix[row_index][column_index] = 0;
|
|
|
|
} else if (adjacency_matrix[row_index][column_index] == 1) {
|
|
|
|
distance_matrix[row_index][column_index] = 1;
|
|
|
|
} else {
|
|
|
|
distance_matrix[row_index][column_index] = UINT64_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-07 09:03:29 +02:00
|
|
|
for(uint64_t k = 2; k <= vertex_count; k++) {
|
2024-10-09 15:35:17 +02:00
|
|
|
memcpy(temp_power_matrix, power_matrix, vertex_count * vertex_count * sizeof(uint64_t));
|
2024-10-08 23:29:02 +02:00
|
|
|
gemm_basic(vertex_count, vertex_count, adjacency_matrix, vertex_count, vertex_count, temp_power_matrix, power_matrix);
|
2024-10-04 17:36:40 +02:00
|
|
|
|
2024-10-07 09:03:29 +02:00
|
|
|
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
|
|
|
|
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
|
2024-10-04 17:36:40 +02:00
|
|
|
if (power_matrix[row_index][column_index] != 0 && distance_matrix[row_index][column_index] == UINT64_MAX) {
|
|
|
|
distance_matrix[row_index][column_index] = k;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-09 01:42:55 +02:00
|
|
|
int get_eccentricities(const uint64_t vertex_count, const uint64_t distance_matrix[vertex_count][vertex_count], uint64_t eccentricities[vertex_count]) {
|
|
|
|
uint64_t eccentricity;
|
|
|
|
|
|
|
|
// set all eccentricities to infinity in case this is a disconnected graph
|
|
|
|
for (uint64_t index = 0; index < vertex_count; index++) {
|
|
|
|
eccentricities[index] = UINT64_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint64_t row_index = 0; row_index < vertex_count; row_index++) {
|
|
|
|
eccentricity = 0;
|
|
|
|
|
|
|
|
for (uint64_t column_index = 0; column_index < vertex_count; column_index++) {
|
|
|
|
if (distance_matrix[row_index][column_index] > eccentricity) {
|
|
|
|
eccentricity = distance_matrix[row_index][column_index];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// in case of a disconnected graph
|
|
|
|
if (eccentricity == 0) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
eccentricities[row_index] = eccentricity;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t get_radius(const uint64_t vertex_count, const uint64_t eccentricities[vertex_count]) {
|
|
|
|
uint64_t radius = UINT64_MAX;
|
|
|
|
|
|
|
|
for (uint64_t index = 0; index < vertex_count; index++) {
|
|
|
|
if (eccentricities[index] < radius) {
|
|
|
|
radius = eccentricities[index];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return radius;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t get_diameter(const uint64_t vertex_count, const uint64_t eccentricities[vertex_count]) {
|
|
|
|
uint64_t diamter = 0;
|
|
|
|
|
|
|
|
for (uint64_t index = 0; index < vertex_count; index++) {
|
|
|
|
if (eccentricities[index] > diamter) {
|
|
|
|
diamter = eccentricities[index];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return diamter;
|
2024-10-04 13:05:02 +02:00
|
|
|
}
|
2024-10-09 01:42:55 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint64_t index = 0; index < vertex_count; index++) {
|
|
|
|
if (eccentricities[index] == radius) {
|
|
|
|
centre[index] = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-09 15:35:17 +02:00
|
|
|
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]) {
|
|
|
|
uint64_t power_matrix[vertex_count][vertex_count];
|
|
|
|
uint64_t temp_power_matrix[vertex_count][vertex_count];
|
|
|
|
memcpy(power_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++) {
|
|
|
|
if (row_index == column_index || adjacency_matrix[row_index][column_index] == 1) {
|
|
|
|
path_matrix[row_index][column_index] = 1;
|
|
|
|
} else {
|
|
|
|
path_matrix[row_index][column_index] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(uint64_t k = 2; k <= vertex_count; k++) {
|
|
|
|
memcpy(temp_power_matrix, power_matrix, vertex_count * vertex_count * sizeof(uint64_t));
|
|
|
|
gemm_basic(vertex_count, vertex_count, adjacency_matrix, vertex_count, vertex_count, temp_power_matrix, power_matrix);
|
|
|
|
|
|
|
|
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 (power_matrix[row_index][column_index] != 0) {
|
|
|
|
path_matrix[row_index][column_index] = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO
|
|
|
|
* Remove stupid solution for connected graph inside the if statement and implement an actual solution for checking of duplicate components
|
|
|
|
*/
|
|
|
|
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]) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2024-10-09 01:42:55 +02:00
|
|
|
|
2024-10-09 15:35:17 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (is_valid_component) {
|
|
|
|
amount_of_components++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return amount_of_components;
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
bridges[row_index][0] = UINT64_MAX;
|
|
|
|
bridges[row_index][1] = UINT64_MAX;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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("}");
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|