Last active
November 23, 2015 14:29
-
-
Save vincevargadev/46f90677bf3819081d10 to your computer and use it in GitHub Desktop.
Read adjacency matrix and linearise network representation.
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> | |
/* FYI: C is new for me and don't consider anything you see here as good practice. | |
* Your feedback is welcome. | |
*/ | |
#include "asciialerts.h" | |
/* Read adjacency list. PS: I see file and variable names like this in C, so I tried to name my files to look more encrypted for the lulz. */ | |
#include "radjlist.h" | |
/* Linearise adjacency list */ | |
#include "linadjacency.h" | |
/* Some manual tests */ | |
#include "tests.h" | |
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[]) { | |
welcomeScreen(); | |
char *filename; | |
int dbg, TOTAL_NODES, TOTAL_EDGES, **network, **network_weight, *lin_position, *lin_network, *lin_network_weight, arg_fail, read_in_fail, lin_fail ; | |
arg_fail = parseArguments(argc, argv, &filename, &dbg); | |
if (arg_fail) { skull(); return EXIT_FAILURE; } | |
readWeightedAdjacencyList(argc, argv, filename, dbg, &TOTAL_NODES, &TOTAL_EDGES, &network, &network_weight); | |
read_in_fail = testVaryingLengthNetworkRepresenation(filename, network, network_weight, dbg); | |
if (read_in_fail) { skull(); return EXIT_FAILURE; } | |
lineariseNetwork(TOTAL_NODES, TOTAL_EDGES, network, network_weight, &lin_position, &lin_network, &lin_network_weight, dbg); | |
lin_fail = testLinearisedNetworkRepresentation(filename, lin_position, lin_network, lin_network_weight, dbg); | |
if (lin_fail) { skull(); return EXIT_FAILURE; } | |
happyMan(); | |
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
/* Ascii art to make coding more fun */ | |
void happyMan (void) { | |
printf("\nYAY, SUCCESS\n"); | |
printf("\\o/\n"); | |
printf(" | \n"); | |
printf("/ \\\n\n"); | |
} | |
void skull(void) { | |
printf("\n _____\n"); | |
printf("/ \\\n"); | |
printf("| o O |\n"); | |
printf("\\ ^ /\n"); | |
printf(" ||||| \n\n"); | |
} | |
void loading (void) { | |
// source: http://ascii.co.uk/art/hourglass | |
printf("\n+=====+\n"); | |
printf("|(.;.)|\n"); | |
printf("| )Y( |\n"); | |
printf("|(.:.)|\n"); | |
printf("+=====+\n\n"); | |
} | |
void welcomeScreen (void) { | |
// source: http://ascii.co.uk/art/dogs | |
printf("\nGET THE DACHSHUND PARTY STARTED\n=\\_____| =\\_____/ =\\_____,\n"); | |
printf(" \" \" \" \" \" \"\n"); | |
} |
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
void allocateLinearisedNetworkArrays ( | |
int TOTAL_NODES, | |
int TOTAL_EDGES, | |
int **lin_position, | |
int **lin_network, | |
int **lin_network_weight | |
) { | |
*lin_position = (int *) malloc(TOTAL_NODES * sizeof(int)); | |
*lin_network = (int *) malloc((TOTAL_NODES + TOTAL_EDGES)* sizeof(int)); | |
*lin_network_weight = (int *) malloc((TOTAL_NODES + TOTAL_EDGES)* sizeof(int)); | |
} | |
void lineariseNetworkMatrix ( | |
int ** network, | |
int * lin_position, | |
int * lin_network, | |
int TOTAL_NODES, | |
int TOTAL_EDGES | |
) { | |
int current_position = 0; | |
for (int i_node = 0; i_node < TOTAL_NODES; i_node++) { | |
for (int j_edge = 0; j_edge <= network[i_node][0]; j_edge++){ | |
if (j_edge == 0) { | |
lin_position[i_node] = current_position; | |
} | |
lin_network[current_position] = network[i_node][j_edge]; | |
current_position = current_position + 1; | |
} | |
} | |
} | |
void printLinearisedNetwork ( | |
int * lin_position, | |
int * lin_network, | |
int TOTAL_NODES, | |
int TOTAL_EDGES | |
) { | |
int len_correction = 1; | |
int len = TOTAL_NODES + TOTAL_EDGES - len_correction; | |
int j_node = 0; | |
for (int i_pos = 0; i_pos < len; i_pos++) { | |
if (lin_position[j_node] == i_pos){ | |
printf("\nNode %d\t Count: ", j_node); | |
j_node++; | |
} | |
printf("%d\t", lin_network[i_pos]); | |
} | |
printf("\n"); | |
} | |
void lineariseNetwork( | |
int TOTAL_NODES, | |
int TOTAL_EDGES, | |
int **network, | |
int **network_weight, | |
int **lin_position, | |
int **lin_network, | |
int **lin_network_weight, | |
int dbg | |
) { | |
if (dbg) { printf("\n** ALLOCATE SPACE FOR LINEARISED NETWORK ARRAYS...\n"); } | |
allocateLinearisedNetworkArrays(TOTAL_NODES, TOTAL_EDGES, lin_position, lin_network, lin_network_weight); | |
if (dbg) { printf("\n** LINEARISE NETWORK MATRICES...\n"); } | |
lineariseNetworkMatrix(network, *lin_position, *lin_network, TOTAL_NODES, TOTAL_EDGES); | |
lineariseNetworkMatrix(network_weight, *lin_position, *lin_network_weight, TOTAL_NODES, TOTAL_EDGES); | |
if (dbg == 2) { printf("Linearised Network"); printLinearisedNetwork(*lin_position, *lin_network, TOTAL_NODES, TOTAL_EDGES); printf("Linearised Network WEIGHT"); printLinearisedNetwork(*lin_position, *lin_network_weight, TOTAL_NODES, TOTAL_EDGES); } | |
} |
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
GET THE DACHSHUND PARTY STARTED | |
=\_____| =\_____/ =\_____, | |
" " " " " " | |
DEBUG MODE ON. YOU'LL SEE EXPLAINING TEXTS AS THE PROGRAM RUNS. | |
Weighted adjacency list source filename: xample.dat | |
** GET EDGE AND NODE COUNT OF THE SYSTEM... | |
Network from to weight: | |
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 | |
Node count: 7 | |
Edge count: 10 | |
** GET EDGE COUNT ARRAY... | |
Edge count array: 0->0 1->3 2->2 3->2 4->2 5->1 6->0 | |
** ALLOCATE MEMORY FOR NETWORK REPRESENATION... | |
** FILL NETWORK REPRESENTATION... | |
Varying-length Network | |
Node 0 Count: 0 | |
Node 1 Count: 3 2 3 6 | |
Node 2 Count: 2 3 5 | |
Node 3 Count: 2 4 5 | |
Node 4 Count: 2 5 6 | |
Node 5 Count: 1 6 | |
Node 6 Count: 0 | |
Varying-length Network WEIGHT | |
Node 0 Count: 0 | |
Node 1 Count: 3 5 4 2 | |
Node 2 Count: 2 7 9 | |
Node 3 Count: 2 2 1 | |
Node 4 Count: 2 14 3 | |
Node 5 Count: 1 1 | |
Node 6 Count: 0 | |
** TEST VARYING-LENGTH NETWORK REPRESENTATION... | |
OK: testXampleVLNR | |
** ALLOCATE SPACE FOR LINEARISED NETWORK ARRAYS... | |
** LINEARISE NETWORK MATRICES... | |
Linearised Network | |
Node 0 Count: 0 | |
Node 1 Count: 3 2 3 6 | |
Node 2 Count: 2 3 5 | |
Node 3 Count: 2 4 5 | |
Node 4 Count: 2 5 6 | |
Node 5 Count: 1 6 | |
Linearised Network WEIGHT | |
Node 0 Count: 0 | |
Node 1 Count: 3 5 4 2 | |
Node 2 Count: 2 7 9 | |
Node 3 Count: 2 2 1 | |
Node 4 Count: 2 14 3 | |
Node 5 Count: 1 1 | |
OK: testXampleLinNwR | |
YAY, SUCCESS | |
\o/ | |
| | |
/ \ | |
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
/* See my previous gist: https://gist.github.com/vargavince91/3d33f97511609b3cd191 */ | |
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_EDGES = *TOTAL_EDGES + 1; | |
*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; | |
} | |
void readWeightedAdjacencyList ( | |
int argc, | |
char **argv, | |
char *filename, | |
int dbg, | |
int *TOTAL_NODES, | |
int *TOTAL_EDGES, | |
int ***network, | |
int ***network_weight | |
) { | |
int i, *EDGE_COUNT_ARRAY; | |
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); } | |
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"); } | |
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); } | |
} |
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
/* Some hacky tests to make sure the network we use in the code | |
* is the same as defined in the .dat source file. */ | |
int testXampleVLNR (int **network, int **network_weight, int dbg) { | |
int correct = 1; | |
if (dbg) { 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_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); | |
if (correct) { | |
if (dbg) { printf("OK: testXampleVLNR\n"); } | |
return EXIT_SUCCESS; | |
} else { | |
fprintf(stderr, "ERROR: testXampleVLNR!\n"); | |
return EXIT_FAILURE; | |
} | |
} | |
int testXampleLinNwR(int *lin_position, int *lin_network, int *lin_network_weight, int dbg) { | |
int correct = 1; | |
correct = correct && lin_network[lin_position[2]+1] == 3; | |
correct = correct && lin_network[lin_position[2]] == 2; | |
correct = correct && lin_network[lin_position[6]] == 0; | |
correct = correct && lin_network[lin_position[5]+1] == 6; | |
correct = correct && lin_network_weight[lin_position[2]+1] == 7; | |
correct = correct && lin_network_weight[lin_position[2]] == 2; | |
correct = correct && lin_network_weight[lin_position[6]] == 0; | |
correct = correct && lin_network_weight[lin_position[5]+1] == 1; | |
if (correct) { | |
if (dbg) { printf("OK: testXampleLinNwR\n"); } | |
return EXIT_SUCCESS; | |
} else { | |
fprintf(stderr, "ERROR: testXampleLinNwR!\n"); | |
return EXIT_FAILURE; | |
} | |
} | |
int testVaryingLengthNetworkRepresenation( | |
char *filename, | |
int **network, | |
int **network_weight, | |
int dbg | |
) { | |
if (!strcmp(filename,"xample.dat")) { | |
return testXampleVLNR(network, network_weight, dbg); | |
} | |
if(dbg){ printf("WARNING: No tests available for this file!\n"); return 0; } | |
} | |
int testLinearisedNetworkRepresentation( | |
char *filename, | |
int *lin_position, | |
int *lin_network, | |
int *lin_network_weight, | |
int dbg | |
) { | |
if (!strcmp(filename,"xample.dat")) { | |
return testXampleLinNwR(lin_position, lin_network, lin_network_weight, dbg); | |
} | |
if(dbg){ printf("WARNING: No tests available for this file!\n"); return 0; } | |
} |
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