|
| 1 | +#include <electrostatic/electronetsoft/algorithm/arithmos/graph/prim.h> |
| 2 | + |
| 3 | +static inline int prim_init(prim_structure *p_struct, int start) { |
| 4 | + if (p_struct == NULL || p_struct->matrix == NULL || p_struct->pd_path == NULL || |
| 5 | + p_struct->pd_path->edges == NULL) { |
| 6 | + fprintf(stdout, "prim_init: Not Passed Sanity checks!\n"); |
| 7 | + return -1; |
| 8 | + } |
| 9 | + fprintf(stdout, "prim_init: Passed Sanity checks!\n"); |
| 10 | + fprintf(stdout, "prim_init: First item %p\n", |
| 11 | + p_struct->matrix->cells[start][1]); |
| 12 | + for (int i = 0; i < p_struct->cell_length; i++) { |
| 13 | + // deep copy the relations with the first vertex! |
| 14 | + // leave the nullary edges uninitialized! |
| 15 | + if (p_struct->matrix->cells[start][i] != NULL) { |
| 16 | + p_struct->pd_path->edges[i] = p_struct->matrix->cells[start][i]; |
| 17 | + } |
| 18 | + if (p_struct->processors != NULL && |
| 19 | + p_struct->processors->initializing_vertices_processor != NULL) { |
| 20 | + p_struct->processors->initializing_vertices_processor(p_struct); |
| 21 | + } |
| 22 | + fprintf(stdout, "prim_init: Processing for initialization!\n"); |
| 23 | + } |
| 24 | + return 0; |
| 25 | +} |
| 26 | + |
| 27 | +static inline int prim_get_lesser(prim_structure *p_struct, int base_position, edge_path *out) { |
| 28 | + if (p_struct == NULL || p_struct->matrix == NULL || p_struct->pd_path == NULL || |
| 29 | + p_struct->pd_path->edges == NULL) { |
| 30 | + return -1; |
| 31 | + } |
| 32 | + int lesser_position = base_position; |
| 33 | + int edge_index = -1; |
| 34 | + fprintf(stdout, "prim_get_lesser: Passed Sanity checks!\n"); |
| 35 | + |
| 36 | + for (int e = 0; e < p_struct->cell_length; e++) { |
| 37 | + // skip the traversed edge |
| 38 | + if (p_struct->pd_path->edges[e] == NULL || p_struct->pd_path->edges[e]->is_traversed) { |
| 39 | + continue; |
| 40 | + } |
| 41 | + fprintf(stdout, "prim_get_lesser: Processing: %s\n", |
| 42 | + (const char *)p_struct->pd_path->edges[e]->metadata); |
| 43 | + |
| 44 | + if (p_struct->pd_path->edges[e]->length < lesser_position) { |
| 45 | + lesser_position = p_struct->pd_path->edges[e]->length; |
| 46 | + edge_index = e; |
| 47 | + if (p_struct->processors != NULL && |
| 48 | + p_struct->processors->lesser_vertex_retrieval_processor != NULL) { |
| 49 | + p_struct->processors->lesser_vertex_retrieval_processor(p_struct, out, e); |
| 50 | + } |
| 51 | + } |
| 52 | + fprintf(stdout, "prim_get_lesser: Processing lesser distance algorithm!\n"); |
| 53 | + } |
| 54 | + if (edge_index != -1) { |
| 55 | + p_struct->pd_path->edges[edge_index]->is_traversed = 1; |
| 56 | + out->edges[out->count] = p_struct->pd_path->edges[edge_index]; |
| 57 | + out->count += 1; |
| 58 | + if (p_struct->processors != NULL && |
| 59 | + p_struct->processors->on_lesser_vertex_found != NULL) { |
| 60 | + p_struct->processors->on_lesser_vertex_found(p_struct, out); |
| 61 | + } |
| 62 | + fprintf(stdout, "prim_get_lesser: Lesser path found!\n"); |
| 63 | + } |
| 64 | + return edge_index; |
| 65 | +} |
| 66 | + |
| 67 | +// erroneous |
| 68 | +static inline uint8_t prim_update_path_from_edge(prim_structure *p_struct, |
| 69 | + int edge_index) { |
| 70 | + if (p_struct == NULL || p_struct->matrix == NULL || |
| 71 | + p_struct->matrix->cells == NULL || p_struct->pd_path == NULL || |
| 72 | + p_struct->pd_path->edges == NULL) { |
| 73 | + return 0; |
| 74 | + } |
| 75 | + fprintf(stdout, "prim_update_path_from_edge: Passed Sanity checks with %d!\n", |
| 76 | + edge_index); |
| 77 | + |
| 78 | + for (int v = 0; v < p_struct->matrix->cell_length; v++) { |
| 79 | + if (p_struct->matrix->cells[edge_index][v] == NULL) { |
| 80 | + continue; |
| 81 | + } |
| 82 | + |
| 83 | + // update the position-dependent list if the old edge was not reachable, but |
| 84 | + // now available! OR if it was available, but now available with a lesser |
| 85 | + // distance |
| 86 | + if (p_struct->pd_path->edges[v] == NULL || |
| 87 | + (!p_struct->pd_path->edges[v]->is_traversed && |
| 88 | + p_struct->matrix->cells[edge_index][v]->length < p_struct->pd_path->edges[v]->length)) { |
| 89 | + p_struct->pd_path->edges[v] = p_struct->matrix->cells[edge_index][v]; |
| 90 | + if (p_struct->processors != NULL && |
| 91 | + p_struct->processors->update_path_processor != NULL) { |
| 92 | + p_struct->processors->update_path_processor(p_struct); |
| 93 | + } |
| 94 | + fprintf(stdout, "prim_update_path_from_edge: Updated paths!\n"); |
| 95 | + } |
| 96 | + } |
| 97 | + return 0; |
| 98 | +} |
| 99 | + |
| 100 | +static inline void graph_edge_print(edge_path *path, edge *p_edge, int index) { |
| 101 | + if (p_edge == NULL) { |
| 102 | + return; |
| 103 | + } |
| 104 | + fprintf(stdout, "PD List element = (%d, %s, %d, is_traversed: %d)\n", index, |
| 105 | + (const char *) p_edge->metadata, p_edge->length, p_edge->is_traversed); |
| 106 | +} |
| 107 | + |
| 108 | +uint8_t prim_start(prim_structure *p_struct, int start, int end, |
| 109 | + edge_path *out) { |
| 110 | + if (p_struct == NULL || out == NULL) { |
| 111 | + return 1; |
| 112 | + } |
| 113 | + p_struct->pd_path = calloc(1, sizeof (edge_path)); |
| 114 | + p_struct->pd_path->edges = calloc(p_struct->cell_length, sizeof(edge *)); |
| 115 | + p_struct->pd_path->count = p_struct->cell_length; |
| 116 | + |
| 117 | + prim_init(p_struct, start); |
| 118 | + for (int v = 0; v < p_struct->matrix->cell_length; v++) { |
| 119 | + int edge_index = prim_get_lesser(p_struct, __INFINITY, out); |
| 120 | + if (edge_index == end) { |
| 121 | + break; |
| 122 | + } |
| 123 | + prim_update_path_from_edge(p_struct, edge_index); |
| 124 | + } |
| 125 | + return 0; |
| 126 | +} |
| 127 | + |
| 128 | +uint8_t prim_destroy(prim_structure *p_struct) { |
| 129 | + if (p_struct == NULL || p_struct->pd_path == NULL) { |
| 130 | + return 1; |
| 131 | + } |
| 132 | + |
| 133 | + if (p_struct->processors != NULL && |
| 134 | + p_struct->processors->prim_destroy_processor != NULL) { |
| 135 | + p_struct->processors->prim_destroy_processor(p_struct); |
| 136 | + } |
| 137 | + |
| 138 | + free(p_struct->pd_path->edges); |
| 139 | + p_struct->pd_path->edges = NULL; |
| 140 | + |
| 141 | + free(p_struct->pd_path); |
| 142 | + p_struct->pd_path = NULL; |
| 143 | +} |
0 commit comments