예제 #1
0
def create_random_timetable(n_classes, n_days, n_slots, n_maxlecsperslot,
                            req_all):
    timetable_np = np.empty(
        (n_classes, n_days, n_slots, n_maxlecsperslot)) * np.nan
    theory_roomgroup = np.zeros((n_days, n_slots))
    lab_roomgroup = np.zeros((n_days, n_slots))
    req_all['isAssigned'] = False
    f_batch_can_overlap = da.initialize('batchcanoverlap').astype(int)
    batch_sets = get_groups_of_batches(f_batch_can_overlap)
    max_tries = n_days * n_slots

    for c in (set(req_all.classId)):  # First take one class
        req_class = req_all[(req_all['batchId'] != '-')
                            & (req_all['classId'] == c)]
        for s in (set(req_class.subjectId)):
            req_subject = req_class[(req_class['subjectId'] == s)]
            for h in (set(req_subject.totalHrs)):
                req_hrs = req_subject[(req_subject['totalHrs'] == h)]
                for x in batch_sets:
                    req_batchset = set(req_hrs['batchId'].astype(int))
                    if (req_batchset < set(x)
                        ):  #Then we can schedule that group of batches
                        req_set = req_hrs.index  #1. Get the requirements
                        r_day = random.randint(0, n_days -
                                               1)  #2. Get the day and slot
                        r_slot = random.randint(0, n_slots - 1)
                        for i in req_set:  #Schedule each of these requirements
                            if (is_slot_available(req_all, timetable_np, c,
                                                  r_day, r_slot, i,
                                                  theory_roomgroup,
                                                  lab_roomgroup)):
                                timetable_np, theory_roomgroup, lab_roomgroup = assign(
                                    timetable_np, int(c), r_day, r_slot, i,
                                    req_all, theory_roomgroup, lab_roomgroup)
                                req_all.set_value(i, 'isAssigned', True)

    req_single = req_all[req_all['isAssigned'] == False]
    for c in (set(req_single.classId)):  # First take one class
        req_forgivenclass = req_single.loc[
            req_single['classId'] ==
            c]  # List all the requirements for that class in req_forgivenclass
        req_forgivenclass = req_forgivenclass.sort('eachSlot', ascending=False)
        req_set = req_forgivenclass.index
        for req in (req_set):  # Schedule each of these requirements
            notassigned = 1
            n_tries = 0
            while (notassigned == 1 and
                   n_tries < max_tries):  # Keep on scheduling till not found
                n_tries = n_tries + 1
                r_day = random.randint(0, n_days - 1)
                r_slot = random.randint(0, n_slots - 1)
                if (is_slot_available(req_all, timetable_np, c, r_day, r_slot,
                                      req, theory_roomgroup, lab_roomgroup)):
                    timetable_np, theory_roomgroup, lab_roomgroup = assign(
                        timetable_np, int(c), r_day, r_slot, req, req_all,
                        theory_roomgroup, lab_roomgroup)
                    req_all.set_value(req, 'isAssigned', True)
                    notassigned = 0
    return timetable_np
예제 #2
0
def class_batch_overlap(timetable, req_all):
    """Calculates overlaps for theory classes and (non allowed) overlaps for batches and increments cost accordingly"""

    class_cost = 0
    batch_cost = 0

    n_classes, n_days, n_slots, n_max_lec_per_slot = timetable.shape
    f_batch_can_overlap = da.initialize('batchcanoverlap')

    for cl in range(n_classes):
        for day in range(n_days):
            for slot in range(n_slots):
                class_list = []
                batch_list = []
                slot_array = timetable[cl, day, slot, :]
                # Make 2 lists-class_list having all classes in the sub-slot & batch-list having all batches in sub-slot
                # Classes have category 'T' and Batches have category 'L'
                for sub_slot in slot_array:
                    if not np.isnan(sub_slot):
                        req = req_all.loc[req_all.index == sub_slot]
                        if req.iloc[0][
                                'category'] == 'T':  # Class clash can be removed
                            class_list.append(req.iloc[0]['classId'])
                        elif req.iloc[0]['category'] == 'L':
                            batch_list.append(req.iloc[0]['batchId'])

                # If the same class is repeated in the class_list for the same sub-slot, increment cost
                if len(
                        class_list
                ) > 1:  # Cost will be incremented only if multiple classes in same sub-slot
                    for class_id in class_list:
                        class_cost = class_cost + class_list.count(
                            class_id) - 1

                if len(
                        batch_list
                ) > 1:  # Cost will be incremented only if multiple batches in same sub-slot
                    for batch_id in batch_list:  # In case same batch is slotted more than once in sub slot
                        batch_cost = batch_cost + batch_list.count(
                            batch_id) - 1
                    # 1. Consider first batch in batch_list.
                    # 2. Get all batches that are allowed to overlap
                    # 3. Loop over all batches in batch_list. If any batch does'nt belong to this list, cost incremented
                    batch_id = batch_list[0]
                    batches_can_overlap = f_batch_can_overlap[
                        f_batch_can_overlap['batchId'] == batch_id]
                    batches_all = batches_can_overlap[
                        batches_can_overlap.columns[
                            2:
                            3]]  # get batch_can_overlap column                    batches_all_list = batches_all['batchOverlapId'].tolist()
                    batches_all_list.append(batch_id)
                    for batch in batch_list:
                        if batch not in batches_all_list:
                            batch_cost += 1

    return class_cost + batch_cost
예제 #3
0
def get_room_groups(lab_group, theory_group):
    "Forms 2 groups of rooms. lab_group contains rooms with roomCount < 25, all others in theory_group"

    f_room = da.initialize('room')

    for i in range(len(f_room)):
        if (f_room.iloc[i]['roomCount'] > 25):
            theory_group.append(f_room.iloc[i]['roomId'])
        else:
            lab_group.append(f_room.iloc[i]['roomId'])
예제 #4
0
def test_class_batch_overlap(timetable, req_all):
    """Calculates overlaps for theory classes and (non allowed) overlaps for batches and increments cost accordingly. Inconsistencies in data are handled"""

    class_cost = 0
    batch_cost = 0

    n_classes, n_days, n_slots, n_max_lec_per_slot=timetable.shape
    f_batch_can_overlap = da.initialize('batchcanoverlap');

    # Get from database classId, batchId, overlapClassId, overlapBatchId
    f_overlapping_batches_with_classId = da.execquery("SELECT bc.classId, bc.batchId, bca.classId as 'overlapClassId', bca.batchId as 'overlapBatchId' FROM batchClass bc, batchClass bca, batchCanOverlap bo WHERE bc.batchId = bo.batchId AND bca.batchId = bo.batchOverlapId ");

    for cl in range(n_classes):
        for day in range(n_days):
            for slot in range(n_slots):
                class_list = []
                batch_list = []
                slot_array = timetable[cl,day,slot,:]
                # Make 2 lists-class_list having all classes in the sub-slot & batch-list having all batches in sub-slot
                # Classes have category 'T' and Batches have category 'L'
                for sub_slot in slot_array:
                    if not np.isnan(sub_slot):
                        req = req_all.loc[req_all.index == sub_slot]
                        if req.iloc[0]['category'] == 'T':        
                            class_list.append(req.iloc[0]['classId'])
                        elif req.iloc[0]['category'] == 'L':
                            batch_list.append(req.iloc[0]['batchId'])

                # If the same class is repeated in the class_list for the same sub-slot, increment cost
                if len(class_list) > 1 :        # Cost will be incremented only if multiple classes in same sub-slot
                    for class_id in class_list:                        class_cost = class_cost + class_list.count(class_id) - 1

                if len(batch_list)>1:           # Cost will be incremented only if multiple batches in same sub-slot
                    for batch_id in batch_list:             # In case same batch is slotted more than once in sub slot
                        batch_cost = batch_cost + batch_list.count(batch_id) - 1
                        
                    # 1. Consider first batch in batch_list.
                    # 2. Get all batches that are allowed to overlap
                    # 3. Loop over all batches in batch_list. If any batch does'nt belong to this list, cost incremented
                    batch_id = batch_list[0]
                    #batches_can_overlap = f_batch_can_overlap[f_batch_can_overlap['batchId'] == batch_id]
                    #batches_all = batches_can_overlap[batches_can_overlap.columns[2:3]] # get batch_can_overlap colum
                    #batches_all_list = batches_all['batchOverlapId'].tolist()
                    #batches_all_list.append(batch_id)


                    for batch in batch_list:
                        overlap_allowed = t.get_overlapping_batch_list(f_overlapping_batches_with_classId, cl, batch);

                        if (len(overlap_allowed) > 0):
                            if batch not in overlap_allowed:
                                batch_cost += 1
    #                        print("ClassId: ", cl, "Batch: ", batch, "Batch_all_lsit:", overlap_allowed, "batch_cost: ", batch_cost, "class_cost: ", class_cost);
    #print("Final cost: ", class_cost + batch_cost);
    return class_cost + batch_cost
예제 #5
0
classes_tobe_scheduled = set(req_all.classId);
#n_classes = len(classes_tobe_scheduled);
n_classes = 14
#print(n_classes);

# Create room groups -- used in cost claculations and final room allocation
lab_group = []
theory_group = []

m.get_room_groups(lab_group, theory_group);
max_theory = len(theory_group);
max_lab = len(lab_group);

# Select initial solution
tt_initial = m.generate_random_tt(req_all, n_days, n_slots, n_lec_per_slot, n_classes);
print("Initial TT");
#print(tt_initial[2, :, :, :])

print("Initial cost:")
print(cf.get_cost(tt_initial, req_all, n_days, n_slots, max_theory, max_lab));

tt_new =m.swap_neighbourhood(tt_initial, req_all, n_days, n_slots, n_lec_per_slot);
print("Changed TT");
#print(tt_new[2, :, :, :])

print("Changed cost:")
print(cf.get_cost(tt_new, req_all, n_days, n_slots, max_theory, max_lab));


f_batch_can_overlap = da.initialize('batchcanoverlap');
print(f_batch_can_overlap);