overall better generation

This commit is contained in:
alexandre 2024-04-21 23:05:07 +02:00
parent 283d6ffd8a
commit 202b5ffc32
2 changed files with 266 additions and 17 deletions

View File

@ -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) {

View File

@ -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);