/* Program to discover a process model from an event log.
Skeleton program written by Artem Polyvyanyy, artem.polyvyanyy@unimelb.edu.au,
August 2022, with the intention that it be modified by students
to add functionality, as required by the assignment specification.
Student Authorship Declaration:
(1) I certify that except for the code provided in the initial skeleton file,
the program contained in this submission is completely my own individual
work, except where explicitly noted by further comments that provide details
otherwise. I understand that work that has been developed by another student,
or by me in collaboration with other students, or by non-students as a result
of request, solicitation, or payment, may not be submitted for assessment in
this subject. I understand that submitting for assessment work developed by
or in collaboration with other students or non-students constitutes Academic
Misconduct, and may be penalized by mark deductions, or by other penalties
determined via the University of Melbourne Academic Honesty Policy, as
described at https://academicintegrity.unimelb.edu.au.
(2) I also certify that I have not provided a copy of this work in either
softcopy or hardcopy or any other form to any other student, and nor will I
do so until after the marks are released. I understand that providing my work
to other students, regardless of my intention or any undertakings made to me
by that other student, is also Academic Misconduct.
(3) I further understand that providing a copy of the assignment specification
to any form of code authoring or assignment tutoring service, or drawing the
attention of others to such services and code that may have been made
available via such a service, may be regarded as Student General Misconduct
(interfering with the teaching activities of the University and/or inciting
others to commit Academic Misconduct). I understand that an allegation of
Student General Misconduct may arise regardless of whether or not I personally
make use of such solutions or sought benefit from such actions.
Signed by: [Enter your full name and student number here before submission]
Dated: [Enter the date that you "signed" the declaration]
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
/* #DEFINE'S -----------------------------------------------------------------*/
#define GOOD_LUCK "GOOD LUCK CLASS!!!\n" // good luck message
/* TYPE DEFINITIONS ----------------------------------------------------------*/
//typedef unsigned int action_t; // an action is identified by an integer
#define MAX_TRACES 10000
typedef struct event event_t; // an event ...
struct event { // ... is composed of ...
unsigned int actn; // ... an action that triggered it and ...
event_t *next; // ... a pointer to the next event in the trace
};
typedef struct { // a trace is a linked list of events
event_t *head; // a pointer to the first event in this trace
event_t *foot; // a pointer to the last event in this trace
int freq; // the number of times this trace was observed
int length;
} trace_t;
typedef struct { // an event log is an array of distinct traces
// sorted lexicographically
trace_t **trcs; // an array of traces
int trace_num; // the number of distinct traces in this log
int event_num; // the capacity of this event log as the number
// of distinct traces it can hold
int trace_total;
int event_total;
int all_event_freq[256];
char events[256];
} log_t;
typedef unsigned int **DF_t; // a directly follows relation over actions
/* WHERE IT ALL HAPPENS ------------------------------------------------------*/
log_t *malloc_log() {
log_t *log = (log_t *) malloc(sizeof(log_t));
log->event_num = 0;
log->trace_num = 0;
log->trace_total = 0;
log->event_total = 0;
log->trcs = (trace_t **) malloc(sizeof(trace_t *) * MAX_TRACES);
for (int i = 0; i < 256; i++)
log->all_event_freq[i] = 0;
return log;
}
void free_log(log_t *log) {
free(log->trcs);
free(log);
}
event_t *malloc_event(unsigned int actn) {
event_t *e = (event_t *) malloc(sizeof(event_t));
e->actn = actn;
e->next = NULL;
return e;
}
void free_event(event_t *t) {
free(t);
}
trace_t *malloc_tract(char *line) {
trace_t *t = (trace_t *) malloc(sizeof(trace_t));
t->freq = 1;
t->head = NULL;
t->foot = NULL;
t->length = 0;
event_t *p = NULL;
size_t size = strlen(line);
for (int i = 0; i < size; i += 2) {
event_t *tmp = malloc_event(line[i]);
t->length++;
if (t->head == NULL) {
t->head = tmp;
p = tmp;
} else {
p->next = tmp;
p = p->next;
t->foot = tmp;
}
}
return t;
}
void free_tract(trace_t *t) {
event_t *p = t->head;
while (p) {
event_t *n = p->next;
free_event(p);
p = n;
}
free(t);
}
void print_tract(trace_t *t) {
printf("freq: %d\n", t->freq);
event_t *p = t->head;
while (p) {
printf("%c,", p->actn);
p = p->next;
}
}
void convert_trace(trace_t *t, char *line) {
memset(line, '\0', strlen(line));
event_t *e = t->head;
int i = 0;
while (e) {
line[i++] = e->actn;
e = e->next;
}
}
bool is_same_trace(trace_t *t, char *line) {
if (t == NULL) return false;
event_t *p = t->head;
size_t size = strlen(line);
for (int i = 0; i < size; i += 2) {
if (p == NULL) return false;
if (line[i] != p->actn) return false;
p = p->next;
}
return p == NULL;
}
trace_t *find_exist_tract(log_t *log, char *line) {
for (int i = 0; i < log->trace_num; i++) {
if (is_same_trace(log->trcs[i], line)) {
return log->trcs[i];
}
}
return NULL;
}
void print_log(log_t *log) {
for (int i = 0; i < log->trace_num; i++) {
print_tract(log->trcs[i]);
printf("\n");
}
}
void read_file(FILE *fp, log_t *log) {
char line[BUFSIZ];
int no = 0;
while (fgets(line, BUFSIZ, fp) != NULL) {
size_t len = strlen(line);
if (line[len - 1] == '\n') line[len - 1] = '\0';
trace_t *t = find_exist_tract(log, line);
if (t == NULL) {
t = malloc_tract(line);
log->trcs[log->trace_num++] = t;
} else {
t->freq++;
}
event_t *e = t->head;
while (e) {
log->all_event_freq[e->actn]++;
e = e->next;
}
log->trace_total++;
log->event_total += t->length;
}
for (int i = 0; i < 256; i++) {
if (log->all_event_freq[i] == 0) continue;
log->events[log->event_num++] = i;
}
}
int sup_trace(trace_t *trace, unsigned int x, unsigned int y) {
event_t *e = trace->head;
int num = 0;
while (e != trace->foot) {
if (e->next != NULL && e->actn == x && e->next->actn == y) num += (trace->freq);
e = e->next;
}
return num;
}
int max(int a, int b ) {
return a > b ? a : b;
}
int sup(log_t *log, unsigned int x, unsigned int y) {
int num = 0;
for (int i = 0; i < log->trace_num; i++) {
num += sup_trace(log->trcs[i], x, y);
}
return num;
}
int pd(log_t *log, unsigned int x, unsigned int y) {
int m = 100 * abs(sup(log, x, y) - sup(log, y, x));
int n = max(sup(log, x, y), sup(log, y, x));
return m / n;
}
int w(log_t *log, unsigned int x, unsigned int y) {
return abs(50 - pd(log, x, y)) * max(sup(log, x, y), sup(log, y, x));
}
int main(int argc, char *argv[]) {
// printf(GOOD_LUCK); // print the "GOOD LUCK" message
FILE *fp = NULL;
if (argc == 2) {
fp = fopen("test0.txt", "r");
} else {
fp = stdin;
}
log_t *log = malloc_log();
read_file(fp, log);
printf("==STAGE 0============================\n");
printf("Number of distinct events: %d\n", log->event_num);
printf("Number of distinct traces: %d\n", log->trace_num);
printf("Total number of events: %d\n", log->event_total);
printf("Total number of traces: %d\n", log->trace_total);
int max = 0;
trace_t *t = NULL;
for (int i = 0; i < log->trace_num; i++) {
if (log->trcs[i]->freq > max) {
max = log->trcs[i]->freq;
t = log->trcs[i];
}
}
printf("Most frequent trace frequency: %d\n", t->freq);
char line[BUFSIZ];
convert_trace(t, line);
printf("%s\n", line);
for (int i = 0; i < 256; i++) {
if (log->all_event_freq[i] == 0) continue;
printf("%c = %d\n", i, log->all_event_freq[i]);
}
printf("==STAGE 1============================\n");
printf("\t\t");
for (int i = 0; i < log->event_num; i++) {
printf("%c\t", log->events[i]);
}
printf("\n");
for (int i = 0; i < log->event_num; i++) {
printf("\t%c\t", log->events[i]);
for (int j = 0; j < log->event_num; j++) {
int k = sup(log, log->events[i], log->events[j]);
printf("%d\t", k);
}
printf("\n");
}
printf("-------------------------------------\n");
return EXIT_SUCCESS; // remember, algorithms are fun!!!
}
【无标题】
于 2022-03-08 10:06:32 首次发布