Пример #1
0
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()
Пример #2
0
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()
Пример #3
0
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)
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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
Пример #7
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]