Skip to content

Instantly share code, notes, and snippets.

@vincevargadev
Last active November 23, 2015 14:29
Show Gist options
  • Save vincevargadev/46f90677bf3819081d10 to your computer and use it in GitHub Desktop.
Save vincevargadev/46f90677bf3819081d10 to your computer and use it in GitHub Desktop.
Read adjacency matrix and linearise network representation.
#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;
}
/* 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");
}
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); }
}
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/
|
/ \
/* 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); }
}
/* 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; }
}
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