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:
parent
0e0a224f91
commit
a9b310b557
48
rotagen.c
48
rotagen.c
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user