diff --git a/src/algorithm.c b/src/algorithm.c index a0d964d..333c82d 100644 --- a/src/algorithm.c +++ b/src/algorithm.c @@ -80,7 +80,7 @@ int get_fst_offset(creneau* edt, date d) { return (date_dist(edt[0].date, d)); } -/* Feuille morte : +/* Feuilles mortes (--> ligne WYSI (727)) : bool is_allowed_MP2I(creneau* edt, int len_edt, int grp, date end) { bool debug = false; @@ -732,16 +732,54 @@ void add_colle(creneau* edt, colleur* chads, int grp, int id_edt, int id_chad) { edt[id_edt].namelen = chads[id_chad].namelen; str_copy(chads[id_chad].name, chads[id_chad].namelen, edt[id_edt].name); edt[id_edt].mat = chads[id_chad].mat; + //printf("%s %d\n", chads[id_chad].name, chads[id_chad].namelen); //printf("{%d %s %d %d %d}\n", edt[id_edt].group, edt[id_edt].name, edt[id_edt].namelen, (int)(edt[id_edt].mat), id_edt); } void remove_colle(creneau* edt, int id_edt) { edt[id_edt].group = 0; - str_copy("none", 4, edt[id_edt].name); edt[id_edt].namelen = 0; + str_copy("none", 4, edt[id_edt].name); edt[id_edt].mat = NOTHING; } +void move_colle(creneau* edt, int len_edt, int id_src, int id_dest) { + if((id_src < len_edt && id_src >= 0 && id_dest < len_edt && id_dest >= 0) == false) { + printf("Bad\n"); + exit(1); + } + + edt[id_dest].group = edt[id_src].group; + edt[id_dest].namelen = edt[id_src].namelen; + str_copy(edt[id_src].name, edt[id_src].namelen, edt[id_dest].name); + edt[id_dest].mat = edt[id_src].mat; + + remove_colle(edt, id_src); +} + +void swap_colle(creneau* edt, int len_edt, int id_src, int id_dest) { + // BROKEN + if((id_src < len_edt && id_dest < len_edt) == false) { + printf("Bad\n"); + exit(1); + } + int dest_grp = edt[id_dest].group; + + edt[id_dest].group = edt[id_src].group; + + //printf("%d %d\n", edt[id_src].group, dest_grp); + edt[id_src].group = edt[id_src].group; +} + +int mem_id(creneau* edt, int len_edt, int grp, char* colleur, int offset) { + for(int i = offset; i < len_edt; i++) { + if(edt[i].group == grp && str_equal(edt[i].name, colleur)) { + return i; + } + } + return -1; +} + bool is_overlap(creneau* edt, int len_edt, int id) { // detect if a colleur has 2 colles at the same time int k = 1; while(id+k < len_edt && is_equal_date(edt[id].date, edt[id+k].date)) { @@ -1022,7 +1060,7 @@ int max(int x, int y) { return y; } -int score(creneau* edt, int len_edt, int grp) { +int score(creneau* edt, int len_edt, int grp, int n_weeks) { int score = 100; int dist = 0; @@ -1034,7 +1072,6 @@ int score(creneau* edt, int len_edt, int grp) { score -= 4; } /*if(str_equal(edt[i].name, edt[j].name)) { - printf("%d\n", dist); score -= max(0, 28-dist); }*/ if(dist == 7 && edt[i].date.hour == edt[j].date.hour) { @@ -1047,9 +1084,210 @@ int score(creneau* edt, int len_edt, int grp) { } } + char** met = malloc(sizeof(char*)*3*n_weeks); + int p = 0; + for(int i = 0; i < len_edt; i++) { + //printf("%d\n", i); + if(edt[i].group == grp) { + met[p] = malloc(sizeof(char)*30); + str_copy(edt[i].name, edt[i].namelen, met[p]); + for(int k = p-1; k >= 0; k--) { + if(str_equal(met[k], met[p])) { + switch(edt[i].mat) { + case MATH: + score -= 15; + break; + case PHYSICS: + score -= 15; + break; + case ENGLISH: + score -= 15; + break; + default: + break; + } + } + } + p++; + } + } + + for(int f = 0; f < p; f++) { + free(met[f]); + } + free(met); return score; } +int get_colleur_id(colleur* dudes, int n_dudes, char* target) { + for(int i = 0; i < n_dudes; i++) { + if(str_equal(dudes[i].name, target)) { + return i; + } + } + return -1; +} + +char* get_name_from_id(colleur* dudes, int n_dudes, int id) { + for(int i = 0; i < n_dudes; i++) { + if(id == dudes[i].id) { + //printf("{%s}", dudes[i].name); + return dudes[i].name; + } + } + return "none"; +} + +topic get_mat_from_id(colleur* dudes, int n_dudes, int id) { + for(int i = 0; i < n_dudes; i++) { + if(id == dudes[i].id) { + return dudes[i].mat; + } + } + return NOTHING; +} + +int** generate_matrix(int lines, int columns, int def) { + int** mat = malloc(sizeof(int*)*lines); + for(int i = 0; i < lines; i++) { + mat[i] = malloc(sizeof(int)*columns); + for(int j = 0; j < columns; j++) { + mat[i][j] = def; + } + } + return mat; +} + +void destroy_matrix(int** m, int li) { + for(int i = 0; i < li; i++) { + free(m[i]); + } + free(m); +} + +bool retreive_indexes(creneau* edt, int len_edt, int* p1, int* p2, int g1, int g2, char* n1, char* n2, int n_weeks) { + int* indexes_1 = malloc(sizeof(int)*n_weeks); + int* indexes_2 = malloc(sizeof(int)*n_weeks); + int ptr_1 = 0; + int ptr_2 = 0; + + for(int i = 0; i < len_edt; i++) { + //printf("%d\n", i); + if(edt[i].group == g1 && str_equal(edt[i].name, n1)) { + indexes_1[ptr_1] = i; + ptr_1++; + } else if(edt[i].group == g2 && str_equal(edt[i].name, n2)) { + indexes_2[ptr_2] = i; + ptr_2++; + } + } + + //print_arr(indexes_1, ptr_1); + //print_arr(indexes_2, ptr_2); + + int j = 0; + for(int i = 0; i < ptr_1; i++) { + if(j >= ptr_2) { + free(indexes_1); + free(indexes_2); + return false; + } else { + //printf("{%d %d}\n", i, j); + int friday_1 = get_next_friday(edt, len_edt, edt[indexes_1[i]].date); + int friday_2 = get_next_friday(edt, len_edt, edt[indexes_2[j]].date); + if(friday_1 == friday_2) { + *p1 = indexes_1[i]; + *p2 = indexes_2[j]; + + free(indexes_1); + free(indexes_2); + return true; + } else { + if(friday_1 > friday_2) { + i--; + j++; + } + } + } + } + + free(indexes_1); + free(indexes_2); + return false; +} + +void occurencies(creneau* edt, int len_edt, colleur* dudes, int n_groups, int n_colleurs, int n_weeks) { + //printf("{%d}\n", n_groups); + int max_occ = 1; + int** res = generate_matrix(n_groups, n_colleurs, 0); + + for(int c = 0; c < len_edt; c++) { + if(edt[c].group != 0) { + res[edt[c].group-1][get_colleur_id(dudes, n_colleurs, edt[c].name)] += 1; + } + } + + /*for(int k = 0; k < n_groups; k++) { + printf("Group %d : ", k+1); + print_arr(res[k], n_colleurs); + } + printf("\n"); // caused a minor panic */ + + bool halt = false; + for(int it = 0; it < 3; it++) { + for(int grp = 0; grp < n_groups; grp++) { + for(int dud = 0; dud < n_colleurs; dud++) { + if(res[grp][dud] > max_occ) { + for(int grp2 = 0; grp2 < n_groups*(1-halt); grp2++) { + if(grp2 != grp) { + for(int dud2 = 0; dud2 < n_colleurs*(1-halt); dud2++) { + if(dud2 != dud && res[grp2][dud2] > max_occ && res[grp][dud2] < max_occ && res[grp2][dud] < max_occ && get_mat_from_id(dudes, n_colleurs, dud) == get_mat_from_id(dudes, n_colleurs, dud2)) { + + int id_src; + int id_dest; + if(retreive_indexes(edt, len_edt, &id_src, &id_dest, grp+1, grp2+1, get_name_from_id(dudes, n_colleurs, dud), get_name_from_id(dudes, n_colleurs, dud2), n_weeks)) {; + // RESOLVED : both colles need to be the same week + + if(id_src < 0 || id_dest < 0 || id_src >= len_edt || id_dest >= len_edt) { + printf("Uh oh (%d %d)\n", id_src, id_dest); + exit(1); + } + + res[grp][dud] -= 1; + res[grp2][dud2] -= 1; + res[grp2][dud] += 1; + res[grp][dud2] += 1; + + //printf("%d %d | ", edt[id_src].group, edt[id_dest].group); + edt[id_src].group += edt[id_dest].group; + edt[id_dest].group = edt[id_src].group - edt[id_dest].group; + edt[id_src].group -= edt[id_dest].group; + //printf("%d %d\n", edt[id_src].group, edt[id_dest].group); + + //printf("[%d %d - %d] <==> [%d %d - %d]\n", grp+1, id_src, edt[id_src].group, grp2+1, id_dest, edt[id_dest].group); + halt = true; + dud--; + } + } + } + } + } + } + halt = false; + } + } + } + + /* + for(int k = 0; k < n_groups; k++) { + printf("Group %d : ", k+1); + print_arr(res[k], n_colleurs); + } + printf("\n");*/ + + destroy_matrix(res, n_groups); +} + void aux_2(creneau* edt, int len_edt, colleur* chads, int len_chads, int n_groups, int n_weeks, int n_sim, char* outname) { int start = time(NULL); int* weeks_len = malloc(sizeof(int)*n_weeks); @@ -1068,16 +1306,6 @@ void aux_2(creneau* edt, int len_edt, colleur* chads, int len_chads, int n_group int* group_stats = malloc(sizeof(int)*n_groups); int* group_temp = malloc(sizeof(int)*n_groups); - /* - print_one_week(edt, len_edt, edt[0].date); - printf("\n"); - print_one_week(edt, len_edt, edt[19].date); - printf("\n"); - print_one_week(edt, len_edt, edt[38].date); - printf("\n"); - print_one_week(edt, len_edt, edt[57].date); - */ - int max_score = -900000; int global_min = 0; int global_skipped = 0; @@ -1106,9 +1334,10 @@ void aux_2(creneau* edt, int len_edt, colleur* chads, int len_chads, int n_group //add_colles_for_group_MP2I(weeks_len, edt, len_edt, chads, len_chads, n_weeks, i+1, (topic)(2+i%2), i%4, i%6, &skipped); add_colles_for_group_MP2I(weeks_len, edt, len_edt, chads, len_chads, n_weeks, i+1, (topic)(2+i%2), i%3, -20, &skipped); } + occurencies(edt, len_edt, chads, n_groups, len_chads, n_weeks); for(int i = 0; i < n_groups; i++) { //printf("Score for group %d : %d\n", i+1, score(edt, len_edt, i+1)); - temp = score(edt, len_edt, i+1); + temp = score(edt, len_edt, i+1, n_weeks); local_score += temp; group_temp[i] = temp; if(local_min > temp) { diff --git a/src/algorithm.h b/src/algorithm.h index 3956f0a..69dae0a 100644 --- a/src/algorithm.h +++ b/src/algorithm.h @@ -40,7 +40,13 @@ colleur *get_colleurs(colleur *cl, int len_cl, date d, int *how_many); void add_colle(creneau *edt, colleur *chads, int grp, int id_edt, int id_chad); -void remove_coll(creneau *edt, int id_edt); +void remove_colle(creneau *edt, int id_edt); + +void move_colle(creneau* edt, int len_edt, int id_src, int id_dest); + +void swap_colle(creneau* edt, int len_edt, int id_src, int id_dest); + +int mem_id(creneau* edt, int len_edt, int grp, char* colleur, int offset); bool is_overlap(creneau *edt, int len_edt, int id); @@ -52,7 +58,21 @@ void add_colles_for_group_MP2I(int *weeks_len, creneau *edt, int len_edt, colleu void write_to_file(char *filename, creneau *edt, int len_edt); -int score(creneau *edt, int len_edt, int grp); +int score(creneau *edt, int len_edt, int grp, int n_weeks); + +int get_colleur_id(colleur* dudes, int n_dudes, char* target); + +char* get_name_from_id(colleur* dudes, int n_dudes, int id); + +topic get_mat_from_id(colleur* dudes, int n_dudes, int id); + +int** generate_matrix(int lines, int columns, int def); + +void destroy_matrix(int** m, int li); + +bool retreive_indexes(creneau* edt, int len_edt, int* p1, int* p2, int g1, int g2, char* n1, char* n2, int n_weeks); + +void occurencies(creneau* edt, int len_edt, colleur* dudes, int n_groups, int n_colleurs, int n_weeks); void aux_2(creneau *edt, int len_edt, colleur *chads, int len_chads, int n_groups, int n_weeks, int n_sim, char *outname);