half-hardcoded work
This commit is contained in:
parent
54120ceade
commit
f58ba0f37d
@ -24,58 +24,187 @@ param H{p in P, j in J} default 0, binary;
|
||||
param C{p in P, j in J} default 1, binary;
|
||||
|
||||
/* How many jobs need to be done on what day */
|
||||
param R{j in J, d in D}, integer, >= 0;
|
||||
param R{d in D, j in J}, integer, >= 0;
|
||||
|
||||
/* hardcoded */
|
||||
param Q{p in P, j in J, d in D}, default 0, binary;
|
||||
|
||||
/* workload */
|
||||
param Wl{j in J}, integer, >= 0;
|
||||
|
||||
param max_load{p in P, d in D}, default 1, integer;
|
||||
|
||||
/* Person p is allocated to do job j on day d */
|
||||
var A{p in P, j in J, d in D}, binary;
|
||||
|
||||
var error{p in P}, integer, >= 0;
|
||||
|
||||
s.t. hardcode{p in P, j in J, d in D}: A[p,j,d] >= Q[p,j,d];
|
||||
|
||||
/* A person only has one task per day, at most */
|
||||
s.t. max_load_person{p in P, d in D}: sum{j in J} A[p,j,d] <= 1;
|
||||
s.t. max_load_person{p in P, d in D}: sum{j in J} A[p,j,d] <= max_load[p,d];
|
||||
|
||||
/* A person has at least D-1 tasks */
|
||||
s.t. min_load_person{p in P}: sum{j in J, d in D} A[p,j,d] >= D_count-1;
|
||||
#s.t. min_load_person{p in P}: sum{j in J, d in D} A[p,j,d] >= min_load[p];
|
||||
|
||||
/* A person does not perform the same job on all days */
|
||||
s.t. duplicate_jobs{p in P, j in J}: sum{d in D} A[p,j,d] <= D_count-1;
|
||||
|
||||
/* Each task is allocated */
|
||||
s.t. all_allocated{j in J, d in D}: sum{p in P} A[p,j,d] == R[j, d];
|
||||
s.t. all_allocated{j in J, d in D}: sum{p in P} A[p,j,d] == R[d, j];
|
||||
|
||||
/* A person only performs what (s)he is capable of */
|
||||
s.t. capability_person{p in P, j in J, d in D}: A[p,j,d] <= C[p,j];
|
||||
|
||||
/* Maximize enjoyment */
|
||||
maximize enjoyment: sum{p in P, d in D, j in J} A[p,j,d] * (L[p, j] * WL - H[p, j] * WH);
|
||||
s.t. error_lt{p in P}: error[p] >= ((sum{j in J, d in D} A[p,j,d] * Wl[j]) - 4);
|
||||
s.t. error_gt{p in P}: error[p] >= 4 - (sum{j in J, d in D} A[p,j,d] * Wl[j]);
|
||||
|
||||
/* Maximize enjoyment */
|
||||
# minimize error_diff: sum{p in P} error[p];
|
||||
maximize enjoyment: (sum{p in P, d in D, j in J} A[p,j,d] * (L[p, j] * WL - H[p, j] * WH)) - sum{p in P} error[p];
|
||||
solve;
|
||||
|
||||
printf "Sum %d\n", enjoyment;
|
||||
printf{p in P, d in D, j in J : A[p,j,d] > 0} "%d %d %d %d\n", p, d, j, A[p,j,d] * (L[p, j] * WL - H[p, j] * WH);
|
||||
printf "Sum %d\n", (sum{p in P, d in D, j in J} A[p,j,d] * (L[p, j] * WL - H[p, j] * WH));
|
||||
printf "p d j W l\n";
|
||||
printf ">>>>\n";
|
||||
printf{p in P, d in D, j in J : A[p,j,d] > 0} "%d %d %d %d %d\n", p, d, j, A[p,j,d] * (L[p, j] * WL - H[p, j] * WH), Wl[j];
|
||||
printf "<<<<\n";
|
||||
printf "workloads\n";
|
||||
printf "p l\n";
|
||||
printf{p in P} "%d %d\n", p, abs((sum{j in J, d in D : A[p,j,d] > 0} Wl[j]) - ((sum{d in D, j in J} Wl[j] * R[d,j]) / P_count));
|
||||
printf "workload_dev: %d\n", sum{p in P} abs((sum{j in J, d in D : A[p,j,d] > 0} Wl[j]) - ((sum{d in D, j in J} Wl[j] * R[d,j]) / P_count))^2;
|
||||
|
||||
data;
|
||||
|
||||
/* Test example */
|
||||
|
||||
param P_count := 3;
|
||||
param J_count := 2;
|
||||
param D_count := 2;
|
||||
param WL := 3;
|
||||
param WH := 9;
|
||||
param P_count := 44;
|
||||
param J_count := 11;
|
||||
param D_count := 3;
|
||||
param WL := 1;
|
||||
param WH := 3;
|
||||
param Wl := 1 4, 2 4, 3 2, 4 2, 5 4, 6 3, 7 2, 8 1, 9 1, 10 2, 11 2;
|
||||
# de pol-parameter
|
||||
param max_load := 25,1,2; # 12,1,0 12,2,0 12,3,0;
|
||||
param R : 1 2 3 4 5 6 7 8 9 10 11 :=
|
||||
1 1 3 0 0 1 3 4 6 2 5 0
|
||||
2 1 0 6 4 1 3 4 6 2 5 5
|
||||
3 1 0 0 0 1 3 4 6 2 5 5;
|
||||
/* AUTOGEN STARTS HERE */
|
||||
param L : 5 6 7 8 9 10 :=
|
||||
1 0 1 0 1 0 0
|
||||
2 0 0 1 1 0 1
|
||||
3 0 0 1 0 0 1
|
||||
6 0 1 0 0 0 1
|
||||
7 0 0 0 1 0 1
|
||||
8 0 1 0 0 1 0
|
||||
9 0 1 1 0 0 1
|
||||
11 1 0 0 1 0 0
|
||||
13 0 1 0 0 1 0
|
||||
14 0 1 0 0 0 1
|
||||
16 0 1 0 0 0 0
|
||||
18 1 0 0 0 0 0
|
||||
19 0 0 1 0 1 1
|
||||
20 0 0 0 0 0 1
|
||||
21 0 0 0 1 1 0
|
||||
22 0 1 1 0 0 1
|
||||
23 0 1 0 1 0 0
|
||||
24 0 0 0 0 1 0
|
||||
25 1 0 0 0 0 0
|
||||
26 0 1 1 0 0 1
|
||||
27 0 1 0 0 0 1
|
||||
28 0 1 0 1 0 0
|
||||
29 0 0 1 1 0 0
|
||||
30 0 1 1 0 0 0
|
||||
31 0 1 0 0 0 0
|
||||
32 0 0 1 0 1 1
|
||||
34 0 0 0 0 1 1
|
||||
35 0 1 0 1 1 0
|
||||
36 0 1 0 0 0 1
|
||||
38 0 0 1 0 1 1
|
||||
39 0 0 1 0 0 1
|
||||
40 0 1 0 0 0 1
|
||||
41 0 1 1 0 0 1
|
||||
43 0 1 0 0 0 0
|
||||
44 0 0 0 1 0 0;
|
||||
param H : 6 7 8 9 10 :=
|
||||
1 0 0 0 0 1
|
||||
2 1 0 0 1 0
|
||||
6 0 1 0 0 0
|
||||
7 0 1 0 0 0
|
||||
8 0 1 1 0 0
|
||||
9 0 0 1 0 0
|
||||
11 0 1 0 1 0
|
||||
13 0 1 1 0 0
|
||||
14 0 0 1 1 0
|
||||
16 0 0 0 0 1
|
||||
18 0 1 0 0 1
|
||||
19 1 0 1 0 0
|
||||
21 1 1 0 0 0
|
||||
22 0 0 1 1 0
|
||||
23 0 1 0 0 0
|
||||
24 0 0 1 0 0
|
||||
25 0 1 0 0 0
|
||||
26 0 0 1 0 0
|
||||
27 0 0 1 0 0
|
||||
28 0 1 0 1 0
|
||||
29 0 0 0 0 1
|
||||
30 0 0 0 1 0
|
||||
31 0 0 0 1 0
|
||||
32 1 0 1 0 0
|
||||
34 0 0 1 0 0
|
||||
35 0 1 0 0 1
|
||||
36 0 1 0 1 0
|
||||
38 1 0 1 0 0
|
||||
39 1 0 1 0 0
|
||||
40 0 0 0 1 0
|
||||
41 0 0 1 1 0;
|
||||
param C : 1 2 3 5 6 9 :=
|
||||
1 0 0 0 0 1 0
|
||||
2 0 1 0 0 0 0
|
||||
3 0 0 0 0 0 0
|
||||
4 1 0 0 0 0 0
|
||||
5 1 0 1 0 0 0
|
||||
6 0 1 0 0 1 0
|
||||
7 0 0 0 0 0 0
|
||||
8 0 0 0 0 1 1
|
||||
9 1 0 0 0 1 0
|
||||
10 0 0 0 0 0 0
|
||||
11 0 0 0 1 0 0
|
||||
12 1 0 0 0 0 0
|
||||
13 1 0 0 0 1 1
|
||||
14 0 0 0 0 1 0
|
||||
15 0 0 0 0 0 0
|
||||
16 0 0 0 0 1 0
|
||||
17 0 0 0 0 0 0
|
||||
18 0 0 0 1 0 0
|
||||
19 0 0 0 0 0 1
|
||||
20 0 0 0 0 0 0
|
||||
21 0 0 1 0 0 1
|
||||
22 0 0 0 0 1 0
|
||||
23 0 0 0 0 1 0
|
||||
24 0 0 1 0 0 1
|
||||
25 0 1 0 1 0 0
|
||||
26 0 0 0 0 1 0
|
||||
27 0 0 0 0 1 0
|
||||
28 0 0 0 0 1 0
|
||||
29 0 0 0 0 0 0
|
||||
30 0 0 0 0 1 0
|
||||
31 0 0 1 0 1 0
|
||||
32 0 0 0 0 0 1
|
||||
33 0 0 0 0 0 0
|
||||
34 0 0 0 0 0 1
|
||||
35 0 0 0 0 1 1
|
||||
36 0 0 0 0 1 0
|
||||
37 0 0 0 0 0 0
|
||||
38 0 0 0 0 0 1
|
||||
39 0 0 0 0 0 0
|
||||
40 0 0 0 0 1 0
|
||||
41 0 0 0 0 1 0
|
||||
42 0 0 0 0 0 0
|
||||
43 0 0 1 0 1 0
|
||||
44 0 0 1 0 0 0;
|
||||
param Q := 5,1,1,1 25,5,1,1 18,5,2,1 11,5,3,1;
|
||||
|
||||
param L : 1 2 :=
|
||||
1 0 1
|
||||
2 1 0
|
||||
3 0 0;
|
||||
|
||||
param H : 1 2 :=
|
||||
1 1 0
|
||||
2 0 1
|
||||
3 0 1;
|
||||
|
||||
param R : 1 2 :=
|
||||
1 1 2
|
||||
2 2 1;
|
||||
|
||||
param C[3,2] := 0;
|
||||
|
||||
end;
|
112
process.py
Normal file
112
process.py
Normal file
@ -0,0 +1,112 @@
|
||||
|
||||
lovehate = dict((x.split('\t')[0].lower(), [q.strip() for q in x.split('\t')[1:]]) for x in open('table'))
|
||||
people = list(x.strip().lower() for x in open('people'))
|
||||
used = 0
|
||||
for person in people:
|
||||
try:
|
||||
assert(len(lovehate[person]) == 2)
|
||||
used += 1
|
||||
except KeyError:
|
||||
print("unable to match up", person)
|
||||
except AssertionError:
|
||||
print("wrong lovehate", person, lovehate[person])
|
||||
raise
|
||||
assert(used == len(lovehate.keys()))
|
||||
import yaml
|
||||
conf = yaml.load(open('tasks', 'r'))
|
||||
config = conf['config']
|
||||
tasks_dict = conf['tasks']
|
||||
# print(tasks_dict)
|
||||
tasks = list(tasks_dict.keys())
|
||||
tasksi = dict(((v,k) for k,v in enumerate(tasks)))
|
||||
peoplei = dict(((v,k) for k,v in enumerate(people)))
|
||||
tasksdesc = {
|
||||
"schoonmaken": ['schoonmaken'],
|
||||
"afwassen": ['afwassen'],
|
||||
"koken": ['koken', 'kookhulp'],
|
||||
"snackdealen": ['hapjes'],
|
||||
"ignore": ['(vega)', '(liever niet dezelfde maaltijd als het kan)', ''],
|
||||
"superkok": ['superkok'],
|
||||
"fotograferen": ['fotograferen', 'fototroep']
|
||||
}
|
||||
tasksdesci = {}
|
||||
import re
|
||||
for t,a in tasksdesc.items():
|
||||
for q in a: tasksdesci[q] = t
|
||||
loves_matrix = [[0] * len(tasks) for person in people]
|
||||
hates_matrix = [[0] * len(tasks) for person in people]
|
||||
capab_matrix = [[0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1] for person in people]
|
||||
def set_capab(person, task):
|
||||
capab_matrix[peoplei[person]][tasksi[task]] = 1
|
||||
cake_penalty = ["linda", "nanette", "alphacentauri", "obfusk (felix)", "tessa", "joshua"]
|
||||
for person,(loves, hates) in lovehate.items():
|
||||
loves = [tasksdesci[x] for x in re.split('[ ,/]+', loves) if tasksdesci[x] != 'ignore']
|
||||
hates = [tasksdesci[x] for x in re.split('[ ,/]+', hates) if tasksdesci[x] != 'ignore']
|
||||
for l in loves:
|
||||
loves_matrix[peoplei[person]][tasksi[l]] = 1
|
||||
set_capab(person, l)
|
||||
for h in hates: hates_matrix[peoplei[person]][tasksi[h]] = 1
|
||||
for person in cake_penalty:
|
||||
set_capab(person, "baktaarten")
|
||||
for person in ["macgyver", "colin", "petervdv"]:
|
||||
set_capab(person, "halen")
|
||||
set_capab("weasel", "hotemetoten")
|
||||
set_capab("yorick", "hotemetoten")
|
||||
set_capab("linda", "hotemetoten")
|
||||
#capab_matrix[peoplei["avel"]] = [0]*len(tasks)
|
||||
def col_all_zeros(ls, i, al=0):
|
||||
return all(x[i] == al for x in ls)
|
||||
def row_all_zeros(ls, i, al=0):
|
||||
return all(x == al for x in ls[i])
|
||||
def format_matrix(name, ls, default=0):
|
||||
nonzero_cols = [i+1 for i in range(len(ls[0])) if not col_all_zeros(ls, i, default)]
|
||||
nonzero_rows = [i+1 for i in range(len(ls)) if not row_all_zeros(ls, i, default)]
|
||||
print("param", name, ":", " ".join("{:2d}".format(x) for x in nonzero_cols), ":=")
|
||||
for r in nonzero_rows:
|
||||
print("{:9d}".format(r), end='')
|
||||
for c in nonzero_cols:
|
||||
print(" {:2d}".format(ls[r-1][c-1]), end='')
|
||||
print(';' if r == nonzero_rows[-1] else '')
|
||||
def format_dict(name, thing, default=None):
|
||||
print("param {} := {};".format(name, ", ".join(["{} {}".format(k, v) for k,v in thing.items() if v != default])))
|
||||
def format_param(name, val):
|
||||
print("param {} := {};".format(name, val))
|
||||
req_matrix = [[tasks_dict[t]['req'][d] for t in tasks] for d in range(config['days'])]
|
||||
from collections import defaultdict
|
||||
import sys
|
||||
if sys.argv[1] == 'in':
|
||||
format_matrix("L", loves_matrix)
|
||||
format_matrix("H", hates_matrix)
|
||||
format_matrix("C", capab_matrix, 1)
|
||||
format_matrix("R", req_matrix, None)
|
||||
# hardcode: superkoks, linda hotemetoot
|
||||
print("param Q := 5,1,1,1 25,5,1,1 18,5,2,1 11,5,3,1;")
|
||||
format_dict("Wl", {tasksi[t]+1: tasks_dict[t]['workload'] for t in tasks})
|
||||
format_param("D_count", config['days'])
|
||||
format_param("P_count", len(people))
|
||||
format_param("J_count", len(tasks))
|
||||
format_param("WL", config['weights']['likes'])
|
||||
format_param("WH", config['weights']['hates'])
|
||||
elif sys.argv[1] == 'out':
|
||||
flag=False
|
||||
ln = []
|
||||
for l in open('output'):
|
||||
if l == "<<<<\n":
|
||||
flag = False
|
||||
if flag:
|
||||
ln.append(map(int, l.strip().split()))
|
||||
if l == ">>>>\n":
|
||||
flag=True
|
||||
|
||||
assigned = defaultdict(lambda: [[], [], []]) # lambda: [("", 1, 0), ("", 1, 0), ("", 1, 0)])
|
||||
|
||||
for [p, d, j, W, l] in ln:
|
||||
assigned[people[p-1]][d-1].append((tasks[j-1], W, l))
|
||||
for p, (a, b, c) in assigned.items():
|
||||
q = lambda w: ",".join([x[0] + " <3" if x[1] else x[0] for x in w])
|
||||
v = lambda w: sum([x[1] for x in w]) if len(w) else 1
|
||||
l = lambda w: sum([x[2] for x in w])
|
||||
print("| {} || {} || {} || {} || {}||{}".format(p, q(a), q(b), q(c), v(a)+v(b)+v(c), l(a)+l(b)+l(c)))
|
||||
print("|-")
|
||||
else:
|
||||
print(sys.argv[0], "in|out")
|
Loading…
Reference in New Issue
Block a user