#ifndef MARKOV_H #define MARKOV_H #include #include #include #include #include extern int ITEMS; extern double chain[][ITEM_CAP]; extern char item_names[][64]; void generate_chain(char *file_path) { FILE *fp = fopen(file_path, "r"); if(!fp) { fprintf(stderr, "ERROR: Could not open file %s\n", file_path); exit(EXIT_FAILURE); } int items_seen[ITEM_CAP][ITEM_CAP] = {0}; int cur_item = -1; char line[256] = {0}; while((fgets(line, sizeof(line), fp)) != NULL) { if(line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; int item = ITEMS; for(int i = 0; i < ITEMS; i++) { if(strcmp(line, item_names[i]) == 0) item = i; } if(item == ITEMS) { ITEMS++; strcpy(item_names[item], line); } if(cur_item != -1) items_seen[cur_item][item]++; cur_item = item; } fclose(fp); for(int i = 0; i < ITEMS; i++) { int all = 0; for(int j = 0; j < ITEMS; j++) all += items_seen[i][j]; for(int j = 0; j < ITEMS; j++) chain[i][j] = (double)items_seen[i][j]/all; } } int walk_step(int item) { int item_lim = 0; int r = rand(); for(int i = 0; i < ITEMS; i++) { item_lim += RAND_MAX * chain[item][i]; if(r <= item_lim) return i; } return -1; } void take_walk() { #ifdef SAVE_TO_FILE_ON_WALK FILE *fp = fopen(SAVE_TO_FILE_ON_WALK, "w"); if(!fp) { fprintf(stderr, "ERROR: Could not open file %s\n", SAVE_TO_FILE_ON_WALK); exit(EXIT_FAILURE); } #endif int items_seen[ITEM_CAP] = {0}; int cur_item = rand() % ITEMS; for(size_t i = 0; i < WALK_LEN; i++) { #ifdef PRINT_ON_WALK puts(item_names[cur_item]); #endif #ifdef SAVE_TO_FILE_ON_WALK fprintf(fp, "%s\n", item_names[cur_item]); #endif items_seen[cur_item]++; int ni = walk_step(cur_item); assert(ni != -1); cur_item = ni; } #ifdef SAVE_TO_FILE_ON_WALK fclose(fp); printf("Saved file with %d items at %s\n", WALK_LEN, SAVE_TO_FILE_ON_WALK); #endif #ifdef PRINT_ITEM_FREQUENCY puts("Item Frequency:"); for(int i = 0; i < ITEMS; i++) printf("%f %s\n", (double)items_seen[i]/WALK_LEN, item_names[i]); puts(""); #endif } void print_chain() { puts("Chain Matrix:"); for(int i = 0; i < ITEMS; i++) { printf("{"); for(int j = 0; j < ITEMS; j++) printf(" %f,", chain[i][j]); printf("}\n"); } puts(""); } #endif