-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelper.c
158 lines (146 loc) · 4.64 KB
/
helper.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* =============================================================================
* helper.c Set of helper functions, mostly printing and
* array and list operations
* =============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "helper.h"
/* Print node labels for a graph.
* Parameters:
* graph - the graph in question
*/
void print_labels(Graph* graph) {
for (int i = 0; i < graph->nodeCount; i++) {
printf("%i : %s ", i, graph->nodeLabels[i]);
}
printf("---\n");
}
/* Print a graph.
* Parameters:
* graph - the graph in question
*/
void print_graph(Graph* graph) {
for (int i = 0; i < graph->nodeCount; i++) {
for (int j = 0; j < graph->nodeCount; j++) {
if (graph->connections[i][j] != 0) {
printf("%s <---> %s weight %i\n", graph->nodeLabels[i],
graph->nodeLabels[j], graph->connections[i][j]);
}
}
}
}
/* Print a graph in DOT format for easy visualisation.
* Parameters:
* graph - the graph in question
*/
void print_graph_DOT(Graph* graph) {
printf("digraph graphname {\n");
for (int i = 0; i < graph->nodeCount; i++) {
printf("\t%s\n", graph->nodeLabels[i]);
for (int j = 0; j < graph->nodeCount; j++) {
if (graph->connections[i][j] != 0
&& graph->connections[i][j] != INT_MAX) {
printf("\t\"%s\" -> \"%s\" [label=%i]\n", graph->nodeLabels[i],
graph->nodeLabels[j], graph->connections[i][j]);
}
}
}
printf("}\n");
}
/* Print a matrix with tab-seperation.
* N.B. Very large matrices will not fit on screen.
* Parameters:
* matrix - the matrix being printed
* rows - the number of rows
* cols - the number of columns
*/
void print_matrix(int** matrix, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%i\t", matrix[i][j]);
}
printf("\n");
}
}
/* Print a list of centres.
* Parameters:
* head - the head of the list of centres
* graph - the graph in question
*/
void print_centres(ListNode* head, Graph* graph) {
ListNode* node = head;
printf("Number of centres : %i\n", head->length);
while (node != NULL) {
int centreID = node->value;
printf("centre : %s @ %i\n", graph->nodeLabels[centreID], centreID);
node = node->next;
}
}
/* Free all elements of linked-list, including head.
* Parameters:
* head - the head of the list to be freed
*/
void free_list(ListNode* head) {
ListNode* node = head;
while (node != NULL) {
ListNode* tmp = node;
node = node->next;
free(tmp);
}
}
/* Get the maximum value in an array.
* Parameters:
* arr - the array being examined
* size - the size of the array
* Return:
* The largest value.
*/
int max_val(int* arr, int size) {
int champ = 0;
for (int i = 0; i < size; i++) {
if (arr[i] > champ) champ = arr[i];
}
return champ;
}
/* Partition the data for a given rank.
* Balances remainders so that the largest partitions are only one element
* larger than the smallest.
* Parameters:
* rank - the current rank (0 to size-1)
* size - the total number of ranks
* dataSize - the number of rows in the data
* start - out parameter holding the start of the partition, inclusive
* end - out parameter holding the end of the partition, inclusive
*/
void set_partition(int rank, int size, int dataSize, int* start, int* end) {
int count = dataSize / size;
int remainder = dataSize % size;
if (rank < remainder) {
// The first 'remainder' ranks get 'count + 1' tasks each
*start = rank * (count + 1);
*end = *start + count;
} else {
// The remaining 'size - remainder' ranks get 'count' task each
*start = rank * count + remainder;
*end = *start + (count - 1);
}
}
/* Get the rank owning the partition containing a given row.
* Parameters:
* i - the index of the row being looked-up
* size - the total number of ranks
* dataSize - the number of rows in the data
* Return:
* The rank owning the partition containing the row.
*/
int get_partition(int i, int size, int dataSize) {
int start, end;
for (int j = 0; j < size; j++) {
set_partition(j, size, dataSize, &start, &end);
if (0 <= i && i <= end) {
return j;
}
}
}