diff --git a/rotagen.c b/rotagen.c index 91d9563..7a544c0 100644 --- a/rotagen.c +++ b/rotagen.c @@ -1,10 +1,13 @@ #include "rotagen.h" +#include #include #include +#include #include #define POOL_SIZE 0x1000 +#define MAX_PEOPLE 32 /* Hard-coded test data. */ static const char *people[] = { @@ -75,6 +78,9 @@ int main(void) generate_rota(rota); print_rota(rota); + const int badness = rota_badness(rota); + printf("Badness: %d\n", badness); + return 0; } @@ -135,14 +141,54 @@ bool satisfies_slot_constraints(const struct slot_result *result) return true; } +int rota_badness(const struct slot_result *rota) +{ + int freqs[MAX_PEOPLE]; + memset(freqs, 0, sizeof(freqs)); + for (int slot = 0; slot < num_slots; ++slot) { + for (int job = 0; job < num_jobs; ++job) + ++freqs[rota[slot].allocations[job].person]; + } + const int total = num_slots * num_jobs; + int sum = 0; + double ps[MAX_PEOPLE]; + for (int i = 0; i < num_people; ++i) { + ps[i] = (double)freqs[i] / total; + sum += freqs[i]; + } + const double mean = (double)sum / total; + double variance = 0; + for (int i = 0; i < num_people; ++i) { + const double x = ps[i] - mean; + variance += x * x; + } + variance /= num_people; + const double stddev = sqrt(variance); + + int adjacency_score = 0; + for (int i = 0; i < num_slots; ++i) { + for (int j = 0; j < num_jobs; ++j) { + const int p = rota[i].allocations[j].person; + for (int k = 0; k < num_jobs; ++k) { + if (p == rota[i].allocations[k].person) + ++adjacency_score; + } + } + } + + return adjacency_score * stddev; +} + void print_rota(const struct slot_result *rota) { for (int slot = 0; slot < num_slots; ++slot) { + printf("----------------------------------------\n"); for (int job = 0; job < num_jobs; ++job) { - printf("%s\t%s\t%s\n", + printf("%s\t%s\t\t%s\n", job == 0 ? slots[slot] : " ", jobs[job], people[rota[slot].allocations[job].person]); } } + printf("----------------------------------------\n"); } diff --git a/rotagen.h b/rotagen.h index 863c731..e52eb11 100644 --- a/rotagen.h +++ b/rotagen.h @@ -33,6 +33,7 @@ void generate_rota(struct slot_result *rota_out); void generate_allocation(int slot, int job, struct allocation *allocation_out); bool satisfies_allocation_constraints(const struct allocation *allocation); bool satisfies_slot_constraints(const struct slot_result *slot); +int rota_badness(const struct slot_result *rota); void print_rota(const struct slot_result *rota); #endif