1st major update

- length of colles can now be configured
- added .csv printing
- some bug fixes
This commit is contained in:
alexandre 2024-04-13 11:20:02 +02:00
parent ec09ea2330
commit 3499ee60e4
5 changed files with 119 additions and 54 deletions

View File

@ -701,7 +701,9 @@ void generate_colles_v1(creneau* edt, int len_edt, colleur* chads, int n_chads,
printf("It's over\n");
}
*/
// ----------------------------------------------------- //
// ------------------| NEW ALGORITHM |------------------ //
// ----------------------------------------------------- //
void add_colle(creneau* edt, colleur* chads, int grp, int id_edt, int id_chad) {
edt[id_edt].group = grp;
str_copy(chads[id_chad].name, chads[id_chad].namelen, edt[id_edt].name);
@ -711,7 +713,7 @@ void add_colle(creneau* edt, colleur* chads, int grp, int id_edt, int id_chad) {
void remove_colle(creneau* edt, int id_edt) {
edt[id_edt].group = 0;
str_copy("", 0, edt[id_edt].name);
str_copy("none", 4, edt[id_edt].name);
edt[id_edt].namelen = 0;
edt[id_edt].mat = NOTHING;
}
@ -734,24 +736,30 @@ bool is_overlap(creneau* edt, int len_edt, int id) {
return false;
}
void add_colles_for_group_MP2I(int* weeks_len, creneau* edt, colleur* chads, int len_chads, int n_weeks, int grp, topic start_rotation, int mth) {
void add_colles_for_group_MP2I(int* weeks_len, creneau* edt, int len_edt, colleur* chads, int len_chads, int n_weeks, int grp, topic start_rotation, int mth) {
topic rotation = start_rotation;
int math = mth;
int r;
int k = 0; //offset
int halt = 0;
bool found;
int r; // randomize the 1st date
int k = 0; // offset
int halt = 0; // timeout in case a colle cannot be placed
bool found; // interrupt in case a valid colle has been found
int remaining_to_add = 0;
colleur* dudes = malloc(sizeof(colleur)*2);
int len_dudes = 0;
int remaining_to_add = 0; /* self-explainatory
please note that this also tells what colle to add :
1 = physics/english colle
2 = math
3 (not implemented) = info
*/
colleur* dudes = malloc(sizeof(colleur)*2); // used to import colleurs available for a creneau
int len_dudes = 0; // length of colleur*
int* perm = malloc(sizeof(int)*30);
int len_perm = 0;
int* perm = malloc(sizeof(int)*30); // randomize who to pick
int len_perm = 0; // length of int*
for(int week = 0; week < n_weeks; week++) {
int weeklen = weeks_len[week];
// update what colles to add
if(math == 0) {
math = 3;
@ -766,40 +774,59 @@ void add_colles_for_group_MP2I(int* weeks_len, creneau* edt, colleur* chads, int
rotation = ENGLISH;
}
r = rand()%16;
// initialize/reset variables
r = rand()%weeklen;
halt = 0;
found = false;
// if there is a math colle to add, enter this loop
while(remaining_to_add == 2) {
if(edt[k+r%16].group == 0) {
if(edt[k+r%weeklen].group == 0 && edt[k+r%weeklen].length == 1) {
// if creneau is empty
// import all colleurs available
free(dudes);
dudes = get_colleurs(chads, len_chads, edt[k+r%16].date, &len_dudes);
dudes = get_colleurs(chads, len_chads, edt[k+r%weeklen].date, &len_dudes);
len_perm = len_dudes;
// if there are colleurs available
if(len_dudes != 0) {
// randomize the order of colleurs
generate_random_perm(perm, len_perm);
// for each one of them, add his colle for selected group pf and only if
// - he is a MATH colleur
// - he does not have another colle at the same time (is_overlap)
// if a colle has been addded, interrupt the for andwhile loops
for(int dude = 0; dude < len_perm*(1-found); dude++) {
if(chads[perm[dude]].mat == MATH) {
add_colle(edt, chads, grp, k+r%16, perm[dude]);
found = true;
remaining_to_add--;
add_colle(edt, chads, grp, k+r%weeklen, perm[dude]);
if(is_overlap(edt, len_edt, k+r%weeklen)) {
remove_colle(edt, k+r%weeklen);
} else {
found = true;
remaining_to_add--;
}
}
}
}
}
if(!found && halt > weeks_len[week]) {
if(!found && halt > weeklen) {
remaining_to_add--;
printf("Warning : skipping math colle for week %d and group %d\n", week+1, grp);
}
r++;
halt++;
}
// reset the variables
r = rand()%16;
found = false;
halt = 0;
// do it again for physics/english colles
while(remaining_to_add == 1) {
if(edt[k+r%16].group == 0) {
if(edt[k+r%weeklen].group == 0 && edt[k+r%weeklen].length == 1) {
dudes = get_colleurs(chads, len_chads, edt[k+r%16].date, &len_dudes);
len_perm = len_dudes;
if(len_dudes != 0) {
@ -824,12 +851,40 @@ void add_colles_for_group_MP2I(int* weeks_len, creneau* edt, colleur* chads, int
k += weeks_len[week];
remaining_to_add = 0;
}
// avoid memory loss
free(perm);
free(dudes);
}
void write_to_file(char* filename, creneau* edt, int len_edt) {
FILE* ptr = fopen(filename, "w");
fprintf(ptr, "hour,day,month,year,length,group,colleur,matiere\n");
for(int i = 0; i < len_edt; i++) {
fprintf(ptr, "%d,%d,%d,%d,%d,%d,%s,", edt[i].date.hour, edt[i].date.day, edt[i].date.month, edt[i].date.year, edt[i].length, edt[i].group, edt[i].name);
if(edt[i].mat == NOTHING) {
fprintf(ptr, "none");
} else if(edt[i].mat == MATH) {
fprintf(ptr, "Maths");
} else if(edt[i].mat == PHYSICS) {
fprintf(ptr, "Physique");
} else if(edt[i].mat == ENGLISH) {
fprintf(ptr, "Anglais");
} else if(edt[i].mat == INFO) {
fprintf(ptr, "Info");
} else if(edt[i].mat == FRENCH) {
fprintf(ptr, "Français");
} else {
fprintf(ptr, "Unknown");
}
fprintf(ptr, "\n");
}
fclose(ptr);
}
void aux_2(creneau* edt, int len_edt, colleur* chads, int len_chads, int n_groups, int n_weeks) {
int* weeks_len = malloc(sizeof(int)*n_weeks);
// this list is used to tell the above code what index of edt it has to go to search for a colle
int ptr = 0;
int current = 1;
for(int k = 1; k < len_edt; k++) {
@ -842,7 +897,8 @@ void aux_2(creneau* edt, int len_edt, colleur* chads, int len_chads, int n_group
}
for(int i = 0; i < n_groups; i++) {
add_colles_for_group_MP2I(weeks_len, edt, chads, len_chads, n_weeks, i+1, (topic)(2+i%2), i%4);
printf("Adding colles for group %d...\n", i+1);
add_colles_for_group_MP2I(weeks_len, edt, len_edt, chads, len_chads, n_weeks, i+1, (topic)(2+i%2), i%4);
}
print_one_week(edt, len_edt, edt[0].date);
@ -852,6 +908,9 @@ void aux_2(creneau* edt, int len_edt, colleur* chads, int len_chads, int n_group
print_one_week(edt, len_edt, edt[32].date);
printf("\n");
print_one_week(edt, len_edt, edt[48].date);
write_to_file("output.csv", edt, len_edt);
printf("Completed\n");
}

View File

@ -260,7 +260,7 @@ void print_one_week(creneau* edt, int len_creneau, date start) { /*
// print the corresponding week
while(i < len_creneau && (date_dist(start, edt[i].date) < 7)) {
printf("Colle at [%d-%d-%d] (%dh) with group ", edt[i].date.day, edt[i].date.month, edt[i].date.year, edt[i].date.hour);
printf("Colle at [%d-%d-%d] (%dh for %dh) with group ", edt[i].date.day, edt[i].date.month, edt[i].date.year, edt[i].date.hour, edt[i].length);
if(edt[i].group == 0) {
printf("NONE ");
} else {

View File

@ -4,6 +4,9 @@
17 6 2 2024
18 6 2 2024
14 7 2 2024
14 7 2 2024+
14 7 2 2024+
14 7 2 2024+
15 7 2 2024
16 7 2 2024
17 7 2 2024
@ -20,6 +23,9 @@
17 13 2 2024
18 13 2 2024
14 14 2 2024
14 14 2 2024+
14 14 2 2024+
14 14 2 2024+
15 14 2 2024
16 14 2 2024
17 14 2 2024
@ -36,6 +42,9 @@
17 20 2 2024
18 20 2 2024
14 21 2 2024
14 21 2 2024+
14 21 2 2024+
14 21 2 2024+
15 21 2 2024
16 21 2 2024
17 21 2 2024
@ -52,6 +61,9 @@
17 27 2 2024
18 27 2 2024
14 28 2 2024
14 28 2 2024+
14 28 2 2024+
14 28 2 2024+
15 28 2 2024
16 28 2 2024
17 28 2 2024
@ -62,3 +74,4 @@
16 1 3 2024
17 1 3 2024
18 1 3 2024
$

29
main.c
View File

@ -6,40 +6,19 @@ int main() {
printf("Starting\n");
srand(time(NULL));
creneau* edt = import_creneaux("file.txt", 64);
int len_creneau = 64;
creneau* edt = import_creneaux("file.txt", 76);
int len_creneau = 76;
colleur* dudes = import_colleurs("some_data.txt", 12, 64);
colleur* dudes = import_colleurs("some_data.txt", 12, 68);
int n_colleurs = 12;
//printf("%d %d %d %d\n", edt[10].date.hour, edt[10].date.day, edt[10].date.month, edt[10].date.year);
//printf("%d\n", date_dist(d1, d1));
//printf("%d %d %d %d\n", edt[70].date.hour, edt[70].date.day, edt[70].date.month, edt[70].date.year);
//print_one_week(rend, edt, 112, d1);
/*edt[8].group = 1;
edt[8].mat = MATH;
edt[9].group = 1;
edt[9].mat = PHYSICS;
edt[23].group = 1;
edt[23].mat = ENGLISH;
edt[41].group = 1;
edt[41].mat = PHYSICS;
edt[57].group = 1;
edt[57].mat = ENGLISH;
edt[58].group = 1;
edt[58].mat = MATH;
if(is_allowed_MP2I(edt,len_creneau, 1, edt[60].date, 'i')) {
printf("True\n");
}*/
// {char* name; int namelen; topic mat; date* disp; int n_disp;} colleur;
/*int* a = malloc(sizeof(int)*10);
generate_random_perm(a, 10);
print_arr(a, 10);*/
aux_2(edt, len_creneau, dudes, n_colleurs, 9, 4);
aux_2(edt, len_creneau, dudes, n_colleurs, 7, 4);
//generate_colles_v1(edt, len_creneau, dudes, n_colleurs, 9, 4);
//generate_colles_v1(edt, len_creneau, dudes, n_colleurs, 15, 4);

View File

@ -11,7 +11,11 @@ typedef enum topic {NOTHING, MATH, PHYSICS, ENGLISH, FRENCH, INFO} topic;
typedef struct date {int hour; int day; int month; int year;} date; /* format is {hour, day, month, year} */
// nothing to say here
typedef struct creneau {date date; int group; char* name; int namelen; topic mat;} creneau;
typedef struct room {char building; int id;} room;
// rooms
// building can be C, M, R or V
typedef struct creneau {int length; date date; int group; char* name; int namelen; topic mat; room salle;} creneau;
// one créneau de colle
// /!\ creneau has to be sorted by ascending dates
// with edt being a creneau*, it is required to have edt[0] be a Monday and edt[len(edt)-1] has to be a Friday
@ -89,18 +93,28 @@ creneau* import_creneaux(char* filename, int size) {
buffer += (int)(c) - 48;
} else {
if(to_fill == 0) {
//printf("%d\n", i);
edt[i].date.hour = buffer;
edt[i].group = 0;
edt[i].name = malloc(sizeof(char)*35);
edt[i].name[0] = '\0';
edt[i].namelen = 0;
edt[i].name[0] = 'n';
edt[i].name[1] = 'o';
edt[i].name[2] = 'n';
edt[i].name[3] = 'e';
edt[i].name[4] = '\0';
edt[i].namelen = 4;
edt[i].mat = NOTHING;
edt[i].salle.building = 'N';
edt[i].salle.id = 0;
edt[i].length = 1;
} else if(to_fill == 1) {
edt[i].date.day = buffer;
} else if(to_fill == 2) {
edt[i].date.month = buffer;
} else {
} else if(to_fill == 3) {
edt[i].date.year = buffer;
} else {
edt[i].length++;
}
to_fill++;
buffer = 0;