Add badness calculation

Current using the number of times someone is on-rota two days in a
row, multiplied by the standard deviation in the allocation
frequencies.
This commit is contained in:
Rhizome 2024-04-08 18:45:40 +01:00
parent 0e0a224f91
commit a9b310b557
2 changed files with 48 additions and 1 deletions

View File

@ -1,10 +1,13 @@
#include "rotagen.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#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");
}

View File

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