Created
November 22, 2015 20:50
-
-
Save vincevargadev/3d33f97511609b3cd191 to your computer and use it in GitHub Desktop.
This short C program reads a weighted adjacency list into a weird format I can't describe in two words.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
/** | |
* This short C program reads a weighted adjacency list. | |
* | |
* Compile | |
* $ gcc readWeightedAdjacencyList.c -std=c99 -Wall -o readWeightedAdjacencyList.out | |
* | |
* Run | |
* first argument: input filename | |
* second argument: debug mode | |
* $ ./readWeightedAdjacencyList.out xample.dat 2 | |
* | |
* Input file format: | |
* column 1: from_node | |
* column 2: to_node | |
* column 3: weight | |
* | |
* The network representation ends up in the following format: | |
* network[n][m], where | |
* first parameter: nth node | |
* second parameter: | |
* if m == 0: | |
* edge count of nth node | |
* if m != 0 && m <= network[n][0]: | |
* the mth edge from nth node is network[m][n]th node | |
* | |
* If you wanted to read the adjacency list several times, | |
* you could save the intermediate results | |
* (TOTAL_NODES and EDGE_COUNT_ARRAY) | |
* and use them instead of recalculating every time. | |
*/ | |
void printNetworkMatrix ( | |
int ** network, | |
int * EDGE_COUNT_ARRAY, | |
int TOTAL_NODES | |
) { | |
printf("\n"); | |
for (int i = 0; i < TOTAL_NODES; i++) { | |
printf("Node %d\t", i); | |
printf("Count: %d\t", network[i][0]); | |
for (int j = 1; j < EDGE_COUNT_ARRAY[i]+1; j++){ | |
printf("%d\t", network[i][j]); | |
} | |
printf("\n"); | |
} | |
} | |
void fillNetworkMatrices ( | |
char *filename, | |
int ** network, | |
int ** network_weight | |
) { | |
int from_node, to_node, weight, i; | |
FILE *stream_file_pointer; | |
stream_file_pointer = fopen(filename, "r"); | |
while (fscanf(stream_file_pointer, "%d %d %d\n", &from_node, &to_node, &weight) > 0) { | |
i = network_weight[from_node][0] = network[from_node][0] = network[from_node][0] + 1; | |
network[from_node][i] = to_node; | |
network_weight[from_node][i] = weight; | |
} | |
} | |
void allocateNetworkMatrix ( | |
int *EDGE_COUNT_ARRAY, | |
int TOTAL_NODES, | |
int ***network | |
) { | |
*network = (int **) malloc(TOTAL_NODES * sizeof(int *)); | |
for (int i = 0; i < TOTAL_NODES; i++) { | |
network[0][i] = (int *) malloc((EDGE_COUNT_ARRAY[i]+1) * sizeof(int)); | |
network[0][i][0] = 0; // just to be sure to be sure | |
} | |
} | |
void getEdgeCountArray ( | |
char *filename, | |
int TOTAL_NODES, | |
int **EDGE_COUNT_ARRAY, | |
int dbg | |
) { | |
*EDGE_COUNT_ARRAY = (int *) calloc(TOTAL_NODES, sizeof(int)); | |
int from_node, to_node, weight; | |
FILE *stream_file_pointer; | |
stream_file_pointer = fopen(filename, "r"); | |
while (fscanf(stream_file_pointer, "%d %d %d\n", &from_node, &to_node, &weight) > 0) { | |
EDGE_COUNT_ARRAY[0][from_node] = EDGE_COUNT_ARRAY[0][from_node] + 1; | |
} | |
} | |
void getNetworkTotalCounts ( | |
char *filename, | |
int *TOTAL_NODES, | |
int *TOTAL_EDGES, | |
int dbg | |
) { | |
int from_node, to_node, weight; | |
*TOTAL_EDGES = 0; | |
*TOTAL_NODES = 0; | |
FILE *stream_file_pointer; | |
stream_file_pointer = fopen(filename, "r"); | |
if (dbg == 2) {printf("Network \tfrom\tto\tweight:\n");} | |
while (fscanf(stream_file_pointer, "%d %d %d\n", &from_node, &to_node, &weight) > 0) { | |
*TOTAL_EDGES = *TOTAL_EDGES + 1; | |
if (dbg == 2) {printf("\t\t%d\t%d\t%d\n", from_node, to_node, weight);} | |
if (from_node > *TOTAL_NODES) *TOTAL_NODES = from_node; | |
if (to_node > *TOTAL_NODES) *TOTAL_NODES = to_node; | |
} | |
*TOTAL_NODES = *TOTAL_NODES + 1; | |
} | |
int file_exists (char *filename) { | |
// http://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c-cross-platform | |
return access(filename, R_OK) != -1; | |
} | |
int parseArguments( | |
int argc, | |
char **argv, | |
char **filename, | |
int *dbg | |
) { | |
*dbg = 1; | |
if (argc > 2) { | |
*dbg = strtol(argv[2], NULL, 10); | |
} | |
if (*dbg) { | |
printf("DEBUG MODE ON. YOU'LL SEE EXPLAINING TEXTS AS THE PROGRAM RUNS.\n"); | |
} | |
*filename = argc > 1 ? argv[1] : "xample.dat"; | |
if (!file_exists(*filename)) { | |
fprintf(stderr, "ERROR: File doesn't exist: %s\n", *filename); | |
return EXIT_FAILURE; | |
} | |
if (*dbg) { | |
printf("Weighted adjacency list source filename: %s\n", *filename); | |
} | |
return EXIT_SUCCESS; | |
} | |
int main (int argc, char *argv[]) { | |
char *filename; | |
int dbg; | |
int i; | |
int arg_fail = parseArguments(argc, argv, &filename, &dbg); | |
if (arg_fail) { | |
return EXIT_FAILURE; | |
} | |
int TOTAL_NODES, TOTAL_EDGES; | |
if (dbg) { printf("\n** GET EDGE AND NODE COUNT OF THE SYSTEM...\n"); } | |
getNetworkTotalCounts(filename, &TOTAL_NODES, &TOTAL_EDGES, dbg); | |
if (dbg) { printf("Node count: %d\nEdge count: %d\n", TOTAL_NODES, TOTAL_EDGES); } | |
int *EDGE_COUNT_ARRAY; | |
if (dbg) { printf("\n** GET EDGE COUNT ARRAY...\n"); } | |
getEdgeCountArray(filename, TOTAL_NODES, &EDGE_COUNT_ARRAY, dbg); | |
if (dbg == 2) {printf("Edge count array: "); for (i = 0; i < TOTAL_NODES; i=i+1) {printf("%d->%d\t", i, EDGE_COUNT_ARRAY[i]);} printf("\n");} | |
if (dbg) { printf("\n** ALLOCATE MEMORY FOR NETWORK REPRESENATION...\n"); } | |
int **network; | |
int **network_weight; | |
allocateNetworkMatrix(EDGE_COUNT_ARRAY, TOTAL_NODES, &network); | |
allocateNetworkMatrix(EDGE_COUNT_ARRAY, TOTAL_NODES, &network_weight); | |
if (dbg) { printf("\n** FILL NETWORK REPRESENTATION...\n"); } | |
fillNetworkMatrices(filename, network, network_weight); | |
if (dbg == 2) { printf("Varying-length Network"); printNetworkMatrix(network, EDGE_COUNT_ARRAY, TOTAL_NODES); printf("Varying-length Network WEIGHT"); printNetworkMatrix(network_weight, EDGE_COUNT_ARRAY, TOTAL_NODES); } | |
if (!strcmp(filename,"xample.dat")) { | |
int correct = 1; | |
printf("\n** TEST VARYING-LENGTH NETWORK REPRESENTATION...\n"); | |
correct = correct && (network[2][1] == 3); | |
correct = correct && (network[2][0] == 2); | |
correct = correct && (network[6][0] == 0); | |
correct = correct && (network[5][1] == 6); | |
correct = correct && (network[6][0] == 0); | |
correct = correct && (network_weight[2][1] == 7); | |
correct = correct && (network_weight[2][0] == 2); | |
correct = correct && (network_weight[6][0] == 0); | |
correct = correct && (network_weight[5][1] == 1); | |
correct = correct && (network_weight[6][0] == 0); | |
if (!correct) { | |
fprintf(stderr, "ERROR: Test failed!\n"); | |
return EXIT_FAILURE; | |
} | |
} | |
printf("YAY, SUCCESS\n"); | |
return EXIT_SUCCESS; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 2 5 | |
1 3 4 | |
1 6 2 | |
2 3 7 | |
2 5 9 | |
3 4 2 | |
3 5 1 | |
4 5 14 | |
4 6 3 | |
5 6 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment