Skip to content

Instantly share code, notes, and snippets.

@vincevargadev
Created November 22, 2015 20:50
Show Gist options
  • Save vincevargadev/3d33f97511609b3cd191 to your computer and use it in GitHub Desktop.
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.
#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;
}
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