From a261c7bb3e1d2fdc2b8e976c51f58ef57b3261fc Mon Sep 17 00:00:00 2001 From: Alexandre Date: Sun, 8 Sep 2024 20:27:39 +0200 Subject: [PATCH] fixed long-lasting bug wuth date distances --- Makefile | 10 +++++-- src/algorithm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++----- src/algorithm.h | 6 +++++ src/structure.c | 1 + 4 files changed, 80 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 3423697..e715ae6 100755 --- a/Makefile +++ b/Makefile @@ -8,8 +8,14 @@ all: bin/colloscope test: bin/colloscope bin/colloscope -v S3-creneaux.txt 31 S3-colleurs.txt 16 7 15 3000 output-S3.csv 3 6 -mpi-all: bin/colloscope - bin/colloscope -v MPI-creneaux.txt 26 MPI-colleurs.txt 15 12 14 10000 output-MPI.csv 3 999999 +mpi-20: bin/colloscope + bin/colloscope -v MPI-creneaux.txt 26 MPI-colleurs.txt 15 20 14 2500 output-MPI.csv 3 999999 + +mpi-12: bin/colloscope + bin/colloscope -v MPI-creneaux.txt 26 MPI-colleurs.txt 15 12 14 7000 output-MPI.csv 3 999999 + +mpi-8: bin/colloscope + bin/colloscope -v MPI-creneaux.txt 26 MPI-colleurs.txt 15 8 14 10000 output-MPI.csv 3 999999 mem: bin/ valgrind --leak-check=full ./bin/colloscope -v S3-creneaux.txt 21 S3-colleurs.txt 16 7 15 100 output-S3.csv 3 6 diff --git a/src/algorithm.c b/src/algorithm.c index bd5531f..11c9682 100755 --- a/src/algorithm.c +++ b/src/algorithm.c @@ -26,7 +26,7 @@ #include "algorithm.h" bool is_equal_date(date d1, date d2) { - return (d1.hour == d2.hour && d1.day == d2.day && d2.month == d1.month && d2.year == d1.year); + return (d1.hour == d2.hour && d1.day == d2.day && d2.month == d1.month /*&& d2.year == d1.year*/); } int get_date_index(creneau* edt, int len_creneau, date d) { @@ -62,7 +62,7 @@ colleur* get_colleurs(colleur* cl, int len_cl, date d, int* how_many) { for(int j = 0; j < cl[i].n_disp; j++) { if(is_equal_date(cl[i].disp[j], d)) { if(ptr >= 30) { - //warn("Too many colleurs detected for a creneau\n"); + error("Too many colleurs detected for a creneau\n"); } res[ptr] = cl[i]; ptr++; @@ -390,6 +390,7 @@ void add_colles_for_group_MP2I(int* weeks_len, creneau* edt, int len_edt, colleu math_dude++; } } + for(int dude = 0; dude < len_perm*(1-found); dude++) { if(dudes[perm[dude]].mat == rotation && (!is_limiting_sames || occs[grp-1][perm[dude]] <= averages[perm[dude]]) && edt[k+r%weeklen].allow_grps[grp-1] == true) { add_colle(edt, dudes, grp, k+r%weeklen, perm[dude]); @@ -413,7 +414,7 @@ void add_colles_for_group_MP2I(int* weeks_len, creneau* edt, int len_edt, colleu if(!found && halt > 3*weeklen) { remaining_to_add--; *skip_count += 1; - //warn("skipping L2 colle for group %d (week %d)", grp, week); + //warn("skipping L2 colle for group %d (week %d after %d / %d spins)", grp, week, halt, weeklen); } else { if(halt > 2*weeklen) { is_limiting_sames = false ; @@ -472,7 +473,7 @@ int max(int x, int y) { int penalty_poly(int occ, int n_weeks) { if(occ == 0) { - return n_weeks*2; + return n_weeks*10; } return (occ-1)*(occ-1)*(occ-1); } @@ -623,7 +624,7 @@ void fill_zeroes(creneau* edt, int len_edt, colleur* colleurs, int len_colleurs, if( edt[edtptr2].group != gr1 +1 && // not the same group edt[edtptr2].mat == int_to_mat(colleurs, col1) && // same topic - str_equal(edt[edtptr2].name, colleurs[col1].name) && // colleur with 0 G1 colles + str_equal(edt[edtptr2].name, colleurs[col1].name) && // colleur with 0 G1 colles occs[edt[edtptr2].group-1][col1] > 1 && // G2 has some backup occs[edt[edtptr2].group-1][colleur_to_id(colleurs, len_colleurs, edt[edtptr1].name)] <= @@ -652,6 +653,55 @@ void fill_zeroes(creneau* edt, int len_edt, colleur* colleurs, int len_colleurs, } } +void deplete_most(creneau* edt, int len_edt, colleur* colleurs, int len_colleurs, int n_groups, int n_weeks, int weeklen, int** occs, int* averages) { + for(int gr1 = 0; gr1 < n_groups; gr1++) { + for(int col1 = 0; col1 < len_colleurs; col1++) { + char* researched_colleur = colleurs[col1].name ; + if(occs[gr1][col1] > averages[col1]) { + int halt = 0 ; + for(int week = 0; week < n_weeks*(1-halt); week++) { + int r1 = rand()%weeklen; + int count1 = 0 ; + while(!halt && count1 < weeklen) { + int edtptr1 = week*weeklen + (r1+count1)%weeklen; + if(edt[edtptr1].group == gr1 +1 && edt[edtptr1].mat == int_to_mat(colleurs, col1)) { + // search another + if(occs[gr1][colleur_to_id(colleurs, len_colleurs, edt[edtptr1].name)] > 1) { // G1 has enough colles with proposed_colleur + int r2 = rand()%weeklen; + int count2 = 0 ; + while(!halt && count2 < weeklen) { + int edtptr2 = week*weeklen + (r2+count2)%weeklen; + if( + edt[edtptr2].group != gr1 +1 && // not the same group + edt[edtptr2].mat == int_to_mat(colleurs, col1) && // same topic + str_equal(edt[edtptr2].name, colleurs[col1].name) && // colleur with too many G1 colles + + occs[edt[edtptr2].group-1][col1] <= averages[colleur_to_id(colleurs, len_colleurs, edt[edtptr2].name)] && // G2 has some backup + occs[edt[edtptr2].group-1][colleur_to_id(colleurs, len_colleurs, edt[edtptr1].name)] > 1// no overflow for G2 + ) { + halt = true ; + + occs[gr1][col1] -= 1; + occs[gr1][colleur_to_id(colleurs, len_colleurs, edt[edtptr1].name)] += 1; + + occs[edt[edtptr2].group-1][col1] += 1; + occs[edt[edtptr2].group-1][colleur_to_id(colleurs, len_colleurs, edt[edtptr1].name)] -= 1; + + edt[edtptr1].group = edt[edtptr2].group; + edt[edtptr2].group = gr1+1; + } + count2++; + } + } + } + count1++; + } + } + } + } + } +} + int** occurencies(creneau* edt, int len_edt, colleur* dudes, int n_groups, int n_colleurs, int n_weeks, bool is_debug) { int max_occ = 1; @@ -750,18 +800,22 @@ void aux_2(creneau* edt, int len_edt, colleur* chads, int len_chads, int n_group int start = time(NULL); int* weeks_len = malloc(sizeof(int)*n_weeks); + for(int i = 0; i < n_weeks; i++) { + weeks_len[i] = len_edt/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++) { + /*for(int k = 1; k < len_edt; k++) { if(date_dist(edt[k-1].date, edt[k].date) > 1 || k == len_edt-1) { weeks_len[ptr] = current + (k == len_edt - 1); current = 0; ptr++; } current++; - } + }*/ debug("---------------------- %d ----------------------", n_groups); + print_arr(weeks_len, n_weeks); int* group_stats = malloc(sizeof(int)*n_groups); int* group_temp = malloc(sizeof(int)*n_groups); @@ -817,6 +871,10 @@ void aux_2(creneau* edt, int len_edt, colleur* chads, int len_chads, int n_group } //int** temp_data = occurencies(edt, len_edt, chads, n_groups, len_chads, n_weeks, false); fill_zeroes(edt, len_edt, chads, len_chads, n_groups, n_weeks, len_edt/n_weeks, occs, averages); + deplete_most(edt, len_edt, chads, len_chads, n_groups, n_weeks, len_edt/n_weeks, occs, averages); + deplete_most(edt, len_edt, chads, len_chads, n_groups, n_weeks, len_edt/n_weeks, occs, averages); + deplete_most(edt, len_edt, chads, len_chads, n_groups, n_weeks, len_edt/n_weeks, occs, averages); + deplete_most(edt, len_edt, chads, len_chads, n_groups, n_weeks, len_edt/n_weeks, occs, averages); int** temp_data = occs; //int** temp_data = adjust(edt, len_edt, chads, n_groups, len_chads, n_weeks); for(int i = 0; i < n_groups; i++) { diff --git a/src/algorithm.h b/src/algorithm.h index 23c2713..cf636f6 100755 --- a/src/algorithm.h +++ b/src/algorithm.h @@ -72,6 +72,12 @@ 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); +topic int_to_mat(colleur* colleur, int id); + +void fill_zeroes(creneau* edt, int len_edt, colleur* colleurs, int len_colleurs, int n_groups, int n_weeks, int weeklen, int** occs, int* averages); + +void deplete_most(creneau* edt, int len_edt, colleur* colleurs, int len_colleurs, int n_groups, int n_weeks, int weeklen, int** occs, int* averages); + int** occurencies(creneau* edt, int len_edt, colleur* dudes, int n_groups, int n_colleurs, int n_weeks, bool is_debug); void copy_matrix(int** src, int lines, int col, int** dest); diff --git a/src/structure.c b/src/structure.c index 0c00fbe..725444d 100755 --- a/src/structure.c +++ b/src/structure.c @@ -30,6 +30,7 @@ //static int height = 900; int date_dist(date d1, date d2) { /* returns distance between d1 and d2 in days if d2 is sooner than d1, it will return -1 */ + // BROKEN (when dates have different year) if(d2.month == d1.month && d2.year == d1.year) { if(d2.day < d1.day) { return -1;