#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 word[256] = {0}; char ch; while((ch = fgetc(fp)) != EOF) { if(ch != ' ' && ch != ',' && ch != '"' && ch != '\n' && ch != '[' && ch != ']' && ch != '!' && ch != '?' && ch != '.') { word[strlen(word)] = tolower(ch); continue; } if(strlen(word) == 0) goto manage_cur_item; int item = ITEMS; for(int i = 0; i < ITEMS; i++) { if(strcmp(word, item_names[i]) == 0) item = i; } if(item == ITEMS) { ITEMS++; strcpy(item_names[item], word); } if(cur_item != -1) items_seen[cur_item][item]++; cur_item = item; manage_cur_item: if(ch == '\n' || ch == '[' || ch == ']' || ch == '!' || ch == '?' || ch == '.') cur_item = -1; memset(word, 0, sizeof(word)); } fclose(fp); for(int i = 0; i < ITEMS; i++) { int all = 0; for(int j = 0; j < ITEMS; j++) all += items_seen[i][j]; if(all == 0) continue; 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 printf("%s ", item_names[cur_item]); #endif #ifdef SAVE_TO_FILE_ON_WALK fprintf(fp, "%s ", item_names[cur_item]); #endif items_seen[cur_item]++; int ni = walk_step(cur_item); cur_item = ni; if(ni == -1) { cur_item = rand() % ITEMS; #ifdef PRINT_ON_WALK printf("\n"); #endif #ifdef SAVE_TO_FILE_ON_WALK fprintf(fp, "\n"); #endif } } #ifdef PRINT_ON_WALK printf("\n"); #endif #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