weekend xii
This commit is contained in:
@@ -6,14 +6,23 @@ import re
|
||||
import subprocess
|
||||
from collections import OrderedDict
|
||||
import glpm
|
||||
conf = yaml.load(open('config.yaml', 'r'))
|
||||
config = conf['config']
|
||||
config['ignore'].append('')
|
||||
tasks = OrderedDict(conf['tasks'])
|
||||
index = lambda x: {v:k for k,v in enumerate(x)}
|
||||
daily_workloads = \
|
||||
[sum(task['workload'] * task['req'][d] for task in tasks.values()) for d in range(config['days'])]
|
||||
ALL_DAYS = set(range(config['days']))
|
||||
class Person(object):
|
||||
def __init__(self, conf={}):
|
||||
def __init__(self, conf={"dagen":ALL_DAYS}):
|
||||
self.can = set()
|
||||
self.loves = set()
|
||||
self.hates = set()
|
||||
self.does = set() # hardcoded
|
||||
self.has_prefs = False
|
||||
self.conf = conf
|
||||
self.conf['dagen'] = set(conf['dagen'])
|
||||
def vrolijkheid(self):
|
||||
res = config['days'] - len(self.does)
|
||||
for (d,t) in self.does:
|
||||
@@ -24,17 +33,15 @@ class Person(object):
|
||||
return res
|
||||
def workload(self, tasks):
|
||||
return sum(tasks[t]['workload'] for (d,t) in self.does)
|
||||
conf = yaml.load(open('config.yaml', 'r'))
|
||||
config = conf['config']
|
||||
config['ignore'].append('')
|
||||
tasks = OrderedDict(conf['tasks'])
|
||||
index = lambda x: {v:k for k,v in enumerate(x)}
|
||||
def cost(self, num_people):
|
||||
return round(sum((daily_workloads[d] for d in self.conf['dagen'])) / num_people)
|
||||
# probabilistic round: int(math.floor(x + random.random()))
|
||||
def read_people(conf_ppl):
|
||||
def isdict(x):
|
||||
return type(x) == dict
|
||||
people = OrderedDict()
|
||||
for x in conf_ppl:
|
||||
val = {}
|
||||
val = {"dagen": ALL_DAYS}
|
||||
if type(x) == dict:
|
||||
x,val = x.popitem()
|
||||
people[x.lower()] = Person(val)
|
||||
@@ -86,6 +93,7 @@ def matrices(people, tasks):
|
||||
tsk_idx = index(tasks)
|
||||
hardcode = {}
|
||||
max_loads = {}
|
||||
costs = {}
|
||||
for i,(person, p) in enumerate(people.items()):
|
||||
for t in p.loves: loves[i][tsk_idx[t]] = 1
|
||||
for t in p.hates: hates[i][tsk_idx[t]] = 1
|
||||
@@ -94,12 +102,16 @@ def matrices(people, tasks):
|
||||
if 'max_load' in p.conf: # max_load override for Pol
|
||||
for d,l in enumerate(p.conf['max_load']):
|
||||
max_loads[(i,d)] = l
|
||||
# filter days that the person does not exist
|
||||
for d in ALL_DAYS - p.conf['dagen']:
|
||||
max_loads[(i,d)] = 0
|
||||
costs[i] = p.cost(len(people))
|
||||
req = mat(range(config['days']), tasks)
|
||||
for di in range(config['days']):
|
||||
for ti,t in enumerate(tasks.values()):
|
||||
req[di][ti] = t['req'][di]
|
||||
workload = {tsk_idx[t]: tasks[t]['workload'] for t in tasks}
|
||||
return [loves, hates, capab, hardcode, max_loads, req, workload]
|
||||
return [loves, hates, capab, hardcode, max_loads, req, workload, costs]
|
||||
def read_assignment(file, people, tasks):
|
||||
def between_the_lines(f, a=">>>>\n", b="<<<<\n"):
|
||||
for l in f:
|
||||
@@ -115,7 +127,7 @@ def read_assignment(file, people, tasks):
|
||||
for [p,d,j,W,l] in between_the_lines(file):
|
||||
person_vl[p-1].does.add((d-1, task_nm[j-1]))
|
||||
def write_data(people, tasks, file=sys.stdout):
|
||||
[loves, hates, capab, hardcode, max_loads, req, workload] = matrices(people, tasks)
|
||||
[loves, hates, capab, hardcode, max_loads, req, workload, costs] = matrices(people, tasks)
|
||||
print(glpm.matrix("L", loves), file=file)
|
||||
print(glpm.matrix("H", hates), file=file)
|
||||
print(glpm.matrix("C", capab, 1), file=file)
|
||||
@@ -123,6 +135,7 @@ def write_data(people, tasks, file=sys.stdout):
|
||||
print(glpm.dict("Q", hardcode), file=file)
|
||||
print(glpm.dict("Wl", workload), file=file)
|
||||
print(glpm.dict("max_load", max_loads), file=file)
|
||||
print(glpm.dict("Costs", costs), file=file)
|
||||
print(glpm.param("D_count", config['days']), file=file)
|
||||
print(glpm.param("P_count", len(people)), file=file)
|
||||
print(glpm.param("J_count", len(tasks)), file=file)
|
||||
@@ -130,12 +143,12 @@ def write_data(people, tasks, file=sys.stdout):
|
||||
print(glpm.param("WH", config['weights']['hates']), file=file)
|
||||
def write_tasks(people, tasks, file=sys.stdout):
|
||||
for name, p in people.items():
|
||||
days = [[],[],[]]
|
||||
days = [[] for i in range(config['days'])]
|
||||
for (d,t) in p.does:
|
||||
days[d].append((t, t in p.loves))
|
||||
q = lambda w: ",".join([x[0] + " <3" if x[1] else x[0] for x in w])
|
||||
print("| {} || {} || {} || {} || {} || {}".format(name, *map(q, days), p.vrolijkheid(), p.workload(tasks)), file=file)
|
||||
# print("|-")
|
||||
days[d].append((t, t in p.loves, t in p.hates))
|
||||
q = lambda w: ",".join([t + (" <3" if l else "") + (" :(" if h else "") for (t,l,h) in w])
|
||||
print("| {} || {} || {} || {} || {} || {} || {}".format(name, *map(q, days), p.vrolijkheid(), p.workload(tasks)), file=file)
|
||||
print("|-")
|
||||
people = read_people(conf['people'])
|
||||
with open('prefs_table', 'r') as pref_file:
|
||||
read_prefs(pref_file, tasks, people)
|
||||
@@ -149,7 +162,7 @@ elif len(sys.argv)>1 and sys.argv[1] == 'out':
|
||||
else:
|
||||
with open('data', 'w') as out:
|
||||
write_data(people, tasks, file=out)
|
||||
subprocess.call(["glpsol", "--model", "model.glpm", "-d", "data", "--tmlim", "30", "--log", "output"], stdout=sys.stderr, stderr=sys.stdout)
|
||||
subprocess.call(["glpsol", "--model", "model.glpm", "-d", "data", "--tmlim", "15", "--log", "output"], stdout=sys.stderr, stderr=sys.stdout)
|
||||
with open('output', 'r') as file:
|
||||
read_assignment(file, people, tasks)
|
||||
write_tasks(people, tasks)
|
||||
|
||||
Reference in New Issue
Block a user