Beispiel #1
0
def valid_candidate_no_overtime(sln, sid, dow, wid, worker_min, wk):
    if valid_candidate(sln, sid, dow, wid, wk):
        s = station.find_station_by_id(sid)
        m = worker_min + s.get_station_duration()
        return m <= 0
    else:
        return False
Beispiel #2
0
def print_solution_by_tuple(sln):
    for x in sln:
        sid = x[0]
        dow = x[1]
        wid = x[2]

        s = station.find_station_by_id(sid)
        d = time.days_of_week[dow]
        w = worker.get_assignment_display_text(wid)

        print "%-10s %-2s %-10s" % (s.name, d, w)
Beispiel #3
0
def print_solution_by_tuple(sln, wk):
    sln2 = [slot for slot in sln if slot[3] == wk]
    for x in sln2:
        sid = x[0]
        dow = x[1]
        wid = x[2]

        s = station.find_station_by_id(sid)
        d = time.days_of_week[dow]
        w = worker.get_assignment_display_text(wid)

        print "%-10s %-2s %-10s" % (s.name, d, w)
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
0
def get_worker_minutes_in_schedule(sln):
    worker_minutes = {}
    for w in worker.workers:
        worker_minutes[
            w.id] = (-1) * w.hours_per_week * 60 + len(w.benefit_days) * 8 * 60

    for slot in sln:
        sid = slot[0]
        wid = slot[2]
        if wid > 0:
            s = station.find_station_by_id(sid)
            worker_minutes[wid] += s.get_station_duration()

    return worker_minutes
Beispiel #7
0
def assign_workers_to_only_capability(candidates_by_station, sln,
                                      choose_candidate, wk):
    new_sln = [t for t in sln if t[3] == wk]
    for w in worker.workers:
        slots = [slot for slot in sln if slot[2] == w.id if slot[3] == wk]
        ss = worker_capability.worker_stations_map[w.id]
        if len(ss) == 1:
            s = station.find_station_by_id(ss[0])
            only_candidate = {}
            only_candidate[s.id] = [w.id]
            for dow in range(len(time.days_of_week)):
                slot = find_slot_by_station_id_and_dow(new_sln, s.id, dow, wk)
                if slot[2] == 0:
                    new_slot = slot
                    wid = choose_candidate(new_sln, slot, s.id, dow,
                                           only_candidate, wk)
                    if wid > 0:
                        new_slot = (slot[0], slot[1], wid, slot[3])
                        ii = new_sln.index(slot)
                        new_sln[ii] = new_slot
    return new_sln
Beispiel #8
0
def calculate_gaps(sln, wid):
    # Get the worker's assignments.
    dow_stations = [(slot[1], slot[0]) for slot in sln if slot[2] == wid]

    # Sort by day of week then start_time.
    dow_stations.sort(key=lambda tup: tup[0] * 10000 + time.time_to_min(
        station.find_station_by_id(tup[1]).start_time))

    # Pair up successive assignments.
    pairs = zip(dow_stations, tail(dow_stations))

    # Discard pairs within same day.
    pairs2 = [p for p in pairs if p[0][0] != p[1][0]]

    # Extract stations from pairs.
    pairs3 = [(p[0][1], p[1][1]) for p in pairs2]

    # Compute the gaps between station pairs.
    gaps = map(station.get_station_gap_minutes, pairs3)

    return gaps
Beispiel #9
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]