def save_solution_sorted(sln, f, wk): worker_assignment_map = {} for w in worker.workers: sorted_assignments = [(x[0], x[1], x[2]) for x in sln if x[2] == w.id and x[3] == wk] sorted_assignments.sort(key=lambda tup: worker.find_worker_by_id(tup[ 2]).sort_order * 100 + tup[1]) worker_assignment_map[w.id] = sorted_assignments sorted_workers = [(w.id, w.sort_order) for w in worker.workers] sorted_workers.sort(key=lambda tup: tup[1]) text_file = open(f, "w") for wtup in sorted_workers: wid = wtup[0] was = worker_assignment_map[wid] t = format_worker_comment_for_file(wid, was) text_file.write(t) for slot in was: t = format_slot_for_file(slot) text_file.write(t) text_file.write("\n") text_file.close()
def save_solution_sorted_old(sln, f): text_file = open(f, "w") sorted_assignments = [(x[0], x[1], x[2]) for x in sln if x[2] > 0] sorted_assignments.sort(key=lambda tup: worker.find_worker_by_id(tup[2]). sort_order * 100 + tup[1]) for slot in sorted_assignments: t = format_slot_comment_for_file(slot) text_file.write(t) t = format_slot_for_file(slot) text_file.write(t) text_file.close()
def format_worker_comment_for_file(wid, worker_assignments): # Prepare station data for comment sids = rmdups([int(slot[0]) for slot in worker_assignments]) sids.sort() ss = [] for sid in sids: s = station.find_station_by_id(sid) station_name = s.name ss.append("%1d=%s" % (sid, s.name)) stations_comment = ", ".join(ss) w = worker.find_worker_by_id(wid) worker_name = "%s %s" % (w.first_name, w.last_name) return "# %s\n# %s\n" % (worker_name, stations_comment)
def format_slot_comment_for_file(slot): s = station.find_station_by_id(int(slot[0])) station_name = s.name day_name = time.days_of_week[int(slot[1])] wid = int(slot[2]) worker_name = "OPEN" if wid > 0: w = worker.find_worker_by_id(int(slot[2])) worker_name = "%s %s" % (w.first_name, w.last_name) return "#%s,%s,%s\n" % (station_name, day_name, worker_name)
def get_worker_assignment_stats(sln, dow, wid): w = worker.find_worker_by_id(wid) slots_week = [slot for slot in sln if slot[2] == wid] slots_today = [slot for slot in sln if slot[2] == wid and slot[1] == dow] full_time = w.hours_per_week == 40 minutes_week = get_worker_minutes_in_schedule(slots_week)[wid] # HACK: adjust minutes_today by backing out the benefit days and hours per week minutes_today = get_worker_minutes_in_schedule(slots_today)[wid] minutes_today -= w.hours_per_week * 60 + len(w.benefit_days) * 8 * 60 fav_station = w.fav_station return (wid, slots_week, full_time, minutes_week, minutes_today, fav_station)
def valid_candidate(sln, sid, dow, wid, wk): # If the worker has a benefit day or comp time, consider invalid. w = worker.find_worker_by_id(wid) if dow in w.benefit_days: return False if dow in w.comp_days: return False # Get all the worker's assignments for the day. slots = find_slots_by_worker_id_and_dow(sln, wid, dow, wk) # print "worker's current assignments for dow", wid, dow, slots # If there aren't any, the worker is a valid candidate. # If there are assignments, find conflicting ones. The worker is a # valid candidate if there are no conflicting assignments. bad_slots = [ slot for slot in slots if not station.are_compatible_stations(sid, slot[0]) ] # print "bad_slots", bad_slots return len(bad_slots) == 0
def choose_candidate_ranked(sln, slot, sid, dow, candidates_by_station, wk): s = station.find_station_by_id(sid) print print "station", sid, s.name print "day of week", dow, time.days_of_week[dow] print "candidates_by_station[sid]", candidates_by_station[sid] candidates = [] for wid in candidates_by_station[sid]: print "considering worker", wid if valid_candidate(sln, sid, dow, wid, wk): print "worker is valid candidate" stats = get_worker_assignment_stats(sln, dow, wid, wk) print "worker stats" print " wid", stats[0] print " slots", stats[1] print " full_time", stats[2] print " minutes_week", stats[3] print " minutes_today", stats[4] print " fav_station", stats[5] # stats[0] = wid # [1] = slots for wid in sln # [2] = True if w is full time # [3] = assigned minutes for w in sln # [4] = assigned minutes for w in sln for dow # [5] = worker's favorite station same_assignment = len( [slot for slot in stats[1] if slot[0] == sid]) > 0 full_time = stats[2] minutes_week = stats[3] + s.get_station_duration() minutes_today = stats[4] + s.get_station_duration() # gaps = calculate_gaps(sln + [(sid, dow, wid)], wid, wk) # small_gaps = [g for g in gaps if g < 8] is_first_choice = stats[5] == sid is_only_choice = len(candidates_by_station[sid]) == 1 # If overtime and worker is not willing to do it, not a candidate. valid = True if minutes_week > 0: w = worker.find_worker_by_id(wid) valid = w.overtime_ok if valid: print "worker willing to work overtime" else: print "worker not willing to work overtime" # if valid: # if small_gaps: # print "successive assignments too close together" # valid = False # else: # print "successive assignments OK" if valid: r = calculate_rank(full_time, minutes_week, minutes_today, same_assignment, is_first_choice, is_only_choice) print "full_time", full_time print "minutes_week", minutes_week print "minutes_today", minutes_today print "same_assignment", same_assignment print "is_first_choice", is_first_choice print "is_only_choice", is_only_choice print "rank", r candidates.append((r, wid)) if len(candidates) == 0: print "no valid candidates" return 0 else: print "candidates", candidates candidates.sort candidates.sort(key=lambda tup: tup[0]) print "candidates, sorted", candidates return candidates[0][1]