/** * @file generator.c * @date 2018-05-21 * * @brief Client program which generates solutions and submits them. */ #include "common.h" #include #include static const char *pname; static struct circ_buf *shared; struct sigaction sa; struct AdjListNode { int dest; struct AdjListNode *next; }; struct AdjList { struct AdjListNode *head; }; struct Graph { int V; struct AdjList *array; }; static struct Graph graph; static volatile sig_atomic_t quit = 0; static void sig_handler(int signum) { quit = 1; } void usage(void) { fprintf(stderr, "SYNOPSIS\n" "\tgenerator EDGE1...\n" "EXAMPLE\n" "\tgenerator 0-1 1-2 1-3 1-4 2-4 3-6 4-3 4-5 6-0\n"); exit(EXIT_FAILURE); } struct AdjListNode *newAdjListNode(int dest) { struct AdjListNode *newNode = malloc(sizeof(struct AdjListNode)); newNode->dest = dest; newNode->next = NULL; return newNode; } void createGraph(int V) { graph.V = V; graph.array = malloc(V * sizeof(struct AdjList)); for (int i = 0; i < V; i++) graph.array[i].head = NULL; } void addEdge(int src, int dest) { struct AdjListNode *newNode = newAdjListNode(dest); newNode->next = graph.array[src].head; graph.array[src].head = newNode; } int strToInt(char *str) { char *endptr; long val; val = strtol(str, &endptr, 10); if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0)) { perror(pname); return -2; } if (val < INT_MIN || val > INT_MAX) { fprintf(stderr, "[%s] Please choose a smaller node: ", pname); return -1; } return (int) val; } void parse(int argc, char *argv[]) { char *token; int V = 0; int src; int dest; int edges_counter = 0; int edges[(argc - 1) * 2]; for (int i = 1; i < argc; i++) { char const *edge = argv[i]; char *str, *orig_copy; str = orig_copy = strdup(edge); int count = 0; while ((token = strsep(&str, "-"))) { if (strcmp(token, edge) == 0 && str == NULL) { fprintf(stderr, "[%s] An edge consists of two " "nodes separated by a dash\n", pname); free(orig_copy); return; } if (count == 0) { src = strToInt(token); edges[edges_counter] = src; edges_counter++; if (src > V) V = src; } if (count == 1) { dest = strToInt(token); edges[edges_counter] = dest; edges_counter++; if (dest > V) V = dest; } if (count > 1) { fprintf(stderr, "[%s] An edge consists of two " "nodes separated by a dash\n", pname); free(orig_copy); return; } switch (src) { case -2: free(orig_copy); return; break; case -1: fprintf(stderr, "%s\n", edge); free(orig_copy); return; break; default: break; } count++; } free(orig_copy); } createGraph(V+1); for (int i = 0; i < (sizeof(edges) / sizeof(int)); i+=2) { addEdge(edges[i], edges[i+1]); } } void printGraph() { for (int v = 0; v < graph.V; v++) { struct AdjListNode* pCrawl = graph.array[v].head; printf("\n Adjacency list of vertex %d\n head ", v); while (pCrawl) { printf("-> %d", pCrawl->dest); pCrawl = pCrawl->next; } printf("\n"); } } void putItem(int itemValue) { shared->validItems++; shared->data[shared->tail] = itemValue; shared->tail = (shared->tail + 1) % MAX_ITEMS; } void cleanup() { for (int v = 0; v < graph.V; v++) { struct AdjListNode *pCrawl = graph.array[v].head; struct AdjListNode *tmp; while (pCrawl) { tmp = pCrawl; pCrawl = pCrawl->next; free(tmp); } } free(graph.array); } int findIndex(int array[], int value, int size) { int index = 0; while (index < size && array[index] != value) index++; return (index == size ? -1 : index); } void genSolution(int permutation[], int V, int *solution) { int r; // initialize array to indices for (int i = 0; i < V; i++) { permutation[i] = i; } // loop from end to start, choose random and switch // with number at current index. for (int i = (V - 1); i > 0; i--) { r = rand() % (i+1); int tmp = permutation[r]; permutation[r] = permutation[i]; permutation[i] = tmp; } int count = 0; for (int i = 0; i < MAX_ITEMS; i++) { solution[i] = -1; } for (int u = 0; u < V; u++) { int idx = findIndex(permutation, u, V); struct AdjListNode *pCrawl = graph.array[u].head; while (pCrawl) { int idx_v = findIndex(permutation, pCrawl->dest, V); if (idx > idx_v) { solution[count++] = u; solution[count++] = pCrawl->dest; if (count > MAX_ITEMS) return; break; } pCrawl = pCrawl->next; } } /* printf("["); for (int i = 0; i < (count - 1); i++) { printf("%d, ", solution[i]); } printf("%d]\n", solution[count-1]); */ } int main(int argc, char *argv[]) { if (argc == 1) usage(); pname = argv[0]; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &sig_handler; sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); /* int shmfd = shm_open(SHM_NAME, O_RDWR | O_CREAT, PERMISSION); if (shmfd == -1) { perror(pname); exit(EXIT_FAILURE); } shared = mmap(NULL, sizeof(*shared), PROT_WRITE, MAP_SHARED, shmfd, 0); if (shared == MAP_FAILED) { perror(pname); exit(EXIT_FAILURE); } sem_t *sFreeSpace = sem_open(SEM_FREE_SPACE, 0); sem_t *sUsedSpace = sem_open(SEM_USED_SPACE, 0); sem_t *sWriteEnd = sem_open(SEM_WRITE_END, O_CREAT, PERMISSION, 1); if (sFreeSpace == SEM_FAILED || sUsedSpace == SEM_FAILED || sWriteEnd == SEM_FAILED) { perror(pname); exit(EXIT_FAILURE); } */ parse(argc, argv); // seed differently for each process srand(time(NULL) * getpid()); int permutation[graph.V]; while (quit == 0) { for (int i = 0; i < 1000000; i++) { int solution[MAX_ITEMS]; genSolution(permutation, graph.V, solution); /* printf("["); int j; for (j = 0; j < (MAX_ITEMS - 2); j++) { if (solution[j+1] != -1) printf("%d, ", solution[j]); else break; } printf("%d]\n", solution[j]); */ } break; } cleanup(); return 0; }