def Scheduling(): """Return an instance of the Zebra Puzzle.""" Faculty = 'Adams Schuurman VanderLinden Bailey'.split() Times = 'mwf900 mwf1030 tth900 tth1030'.split() Classrooms = 'nh253 sb382'.split() Courses = 'cs104 cs108 cs112 cs212 cs214 cs336 cs344'.split() variables = Courses domains = {} combo = list(itertools.product(Times, Faculty, Classrooms)) for var in variables: domains[var] = combo # domains['Adams1'] = [1, 5] # neighbor parsing -- not implemented neighbors = parse_neighbors("""cs104: cs108; cs344: cs336""", variables) for type in [Courses, Faculty, Times, Classrooms]: for A in type: for B in type: if A != B: if B not in neighbors[A]: neighbors[A].append(B) if A not in neighbors[B]: neighbors[B].append(A) def constraint(A, a, B, b, recurse=0): # a room can only have one class at each time same_timespace = (a[0] == b[0] and a[2] == b[2]) # faculty member can only teach one thing at a time same_profslot = (a[0] == b[0] and a[1] == b[1]) if recurse == 0: return constraint(B, b, A, a, 1) return not (same_timespace or same_profslot) return CSP(variables, domains, neighbors, constraint)
def MapColoringCSP(colors, neighbors): """Make a CSP for the problem of coloring a map with different colors for any two adjacent regions. Arguments are a list of colors, and a dict of {region: [neighbor,...]} entries. This dict may also be specified as a string of the form defined by parse_neighbors.""" if isinstance(neighbors, str): neighbors = AIMAcsp.parse_neighbors(neighbors) return TUMCSP(list(neighbors.keys()), AIMAcsp.UniversalDict(colors), neighbors, AIMAcsp.different_values_constraint)
def get_neighbors(self): self.neighbors = parse_neighbors("junk: filler") for type in [self.variables, self.possible_setups]: for A in type: for B in type: if A != B: if B not in self.neighbors[A]: self.neighbors[A].append(B) if A not in self.neighbors[B]: self.neighbors[B].append(A) return self.neighbors
def Scheduling(): Courses = ['cs108', 'cs112', 'cs214', 'cs344', 'cs212'] Faculty = ['Schuurman', 'Adams', 'Vanderlinden', 'Plantinga'] Timeslot = ['MWF9', 'MWF1030', 'TTH9', 'TTH1030'] Rooms = ['NH253', 'SB382'] Assignement = { 'cs108': 'Schuurman', 'cs112': 'Adams', 'cs214': 'Adams', 'cs344': 'Vanderlinden', 'cs212': 'Plantinga' } # setting Courses as variable variable = Courses # domains lists all possible combination of course, faculty, time, and room domains = {} for course in Courses: # making the course as the key to the domain dictionary domains[course] = [] for prof in Faculty: for time in Timeslot: for room in Rooms: # appending professor, time slot, room number to the course domains[course].append([prof, time, room]) # creating neighbors with each class to be neighbor to all other classes neighbors = parse_neighbors( """ cs108:cs112; cs108:cs212; cs108:cs344; cs108:cs214; cs112:cs212; cs112:cs344; cs112:cs214; cs212:cs344; cs212:cs214; cs344:cs212""", variable) def scheduling_constraints(courseA, a, courseB, b): # check if the assigned professor to the course and the professor in domain value are the same if (a[0] != Assignement[courseA]) or (b[0] != Assignement[courseB]): return False # check if the faculty and time slot are the same for different classes, then return false if a[0] == b[0] and a[1] == b[1]: return False # check if the time slot and the room number are the same for different classes, then return false if a[1] == b[1] and a[2] == b[2]: return False return True return CSP(variable, domains, neighbors, scheduling_constraints)
def scheduler(): classes = "CS232 CS108 CS212 CS112 CS336 CS344".split() profs = "Adams VanderLinden Plantinga Schuurman Norman Nelsen".split() times = "mwf0800 mwf0900 mwf1000 th1230".split() rooms = "nh253 sb382".split() variables = classes all_domains = [] for room in rooms: for time in times: for prof in profs: all_domains.append(room + " " + time + " " + prof) domains = {} for var in variables: domains[var] = all_domains neighbors = parse_neighbors("""CS344: nh253 mwf0800""", variables) for type in [variables]: for A in type: for B in type: if A != B: if B not in neighbors[A]: neighbors[A].append(B) if A not in neighbors[B]: neighbors[B].append(A) def scheduler_constraint(A, a, B, b, recurse=0): conflict = (a == b) if (a.split()[0] == b.split()[0]) and (a.split()[2] == b.split()[2]): return conflict if (a.split()[1] == b.split()[1]) and (a.split()[2] == b.split()[2]): return conflict if recurse == 0: return scheduler_constraint(B, b, A, a, 1) return True return CSP(variables, domains, neighbors, scheduler_constraint)
def scheduling(courses, faculties, times, rooms, assigned_faculty): domains = {} # to append all possible courses' cases to domains for course in courses: domains[course] = list() for faculty in faculties: for time in times: for room in rooms: domains[course].append([faculty, time, room]) # Pairing two courses each. neighbors = parse_neighbors( """cs108: cs112; cs112: cs212; cs212: cs214; cs214: cs384; cs384: cs232; cs232: cs344; cs344: cs108""", courses) for type in [courses]: for A in type: for B in type: if A != B: if B not in neighbors[A]: neighbors[A].append(B) if A not in neighbors[B]: neighbors[B].append(A) def scheduling_constraint(A, a, B, b, recurse=0): # each course should be offered exactly once by the assigned faculty member. if assigned_faculty[A] != a[0] and assigned_faculty[B] != b[0]: return False # a faculty member can only teach one thing at a time. if a[0] == b[0] and a[1] == b[1]: return False # a room can only have one class at each time. if a[1] == b[1] and a[2] == b[2]: return False return True return CSP(courses, domains, neighbors, scheduling_constraint)
import csp def constraint(A, a, B, b): if (A == 't1' and B == 't3'): return (a > b) elif (B == 't1' and A == 't3'): return (b > a) elif (A == 't3' and B == 't4'): return (b > a) elif (B == 't3' and A == 't4'): return (a > b) elif (A == 't3' and B == 't5'): return (a > b) elif (B == 't3' and A == 't5'): return (b > a) elif (A == 't1' and B == 't2') or (A == 't2' and B == 't1'): return (abs(a - b) > 60) elif (A == 't2' and B == 't4') or (A == 't4' and B == 't2'): return (abs(a - b) > 60) else: print(A, a, B, b) variables = ['t1', 't2', 't3', 't4', 't5'] domains = {var: [540, 600, 660] for var in variables} domains['t4'] = [540, 660] neighs = """t1: t2 t3;t2: t4;t4: t3;t3: t5""" neighs = csp.parse_neighbors(neighs) timecsp = csp.CSP(variables, domains, neighs, constraint)
times = '800MWF, 900MWF, 1030MWF, 1130MWF, 830TT, 1030TT,'.split() rooms = 'NH253 SB382'.split() domainsList = [] # Create every permutation of professor, time, and room for p in profs: for t in times: for r in rooms: key = p + t + r domainsList.append( key ) variables = ['cs108', 'cs112', 'cs104', 'cs212', 'cs214', 'cs262', 'cs232'] domains = {} # Assign each class to all the domain permutations for var in variables: domains[var] = domainsList neighbors = parse_neighbors("""cs108: DS,800MWF,NH253""", variables) for type in [domainsList, variables]: for A in type: for B in type: if A != B: if B not in neighbors[A]: neighbors[A].append(B) if A not in neighbors[B]: neighbors[B].append(A) problem = CSP(variables, domains, neighbors, schedule_constraint) result = min_conflicts(problem, max_steps=1000) print("Min conflicts:") printResult( result)
def Scheduler(): """ Returns an instance of the CSP class. """ courses = "cs108 cs112 cs214 stat343 cs336 cs300".split() profs = "norman adams schuurman pruim vanderlinden".split() slots = "mwf900 mwf1130 tth1030 tth130".split() rooms = "sb354 nh064".split() variables = courses assignments = {} assignments['cs108'] = "norman" assignments['cs112'] = "adams" assignments['cs214'] = "adams" assignments['stat343'] = "pruim" assignments['cs336'] = "vanderlinden" assignments['cs300'] = "schuurman" neighbors = parse_neighbors(""" cs108: norman; cs112: adams; cs214: adams; stat343: pruim; cs336: vanderlinden; cs300: schuurman """, variables) domains = {} for course in courses: domains[course] = [] for course in courses: for prof in profs: for room in rooms: for slot in slots: domains[course].append(prof + " " + room + " " + slot) for type in [courses]: for A in type: for B in type: if A != B: if B not in neighbors[A]: neighbors[A].append(B) if A not in neighbors[B]: neighbors[B].append(A) def scheduler_constraints(A, a, B, b, recurse=0): ADomain = a.split() BDomain = b.split() A_Prof = ADomain[0] B_Prof = BDomain[0] A_Room = ADomain[1] B_Room = BDomain[1] A_Slot = ADomain[2] B_Slot = BDomain[2] A_Course = A B_Course = B if(A_Prof == B_Prof and A_Slot == B_Slot): return False if(A_Room == B_Room and A_Slot == B_Slot): return False if('norman' in a and A == 'cs108'): return True if('adams' in a and A == 'cs112'): return True if('adams' in a and A == 'cs214'): return True if('pruim' in a and A == 'stat343'): return True if('vanderlinden' in a and A == 'cs336'): return True if('schuurman' in a and A == 'cs300'): return True if(A in courses and B in courses): return False if(recurse == 0): return scheduler_constraints(B, b, A, a, 1) return True return CSP(variables, domains, neighbors, scheduler_constraints)
def courses_scheduling(): # Defines the variables and values. courses = 'cs108 cs112 cs212 cs214 cs232 cs262 cs344'.split() faculty = 'adams vanderlinden plantinga wieringa norman'.split() time_slots = 'mwf8:00-8:50 mwf9:00-9:50 mwf10:30-11:20 tth11:30-12:20 tth12:30-1:20'.split( ) classrooms = 'nh253 sb382'.split() if debug: # Debug statements. print('\ncourses list:' + str(courses)) print('faculty list:' + str(faculty)) print('time_slots list:' + str(time_slots)) print('classrooms list:' + str(classrooms)) variables = courses values = faculty + time_slots + classrooms if debug: # Debug statements. print('\nMy variables: ' + str(variables)) print('My values: ' + str(values)) # Combine values into triplets for use as part of domain. value_triplets = [] for faculty in faculty: for timeslots in time_slots: for classroom in classrooms: triplet = faculty + ' ' + timeslots + ' ' + classroom value_triplets.append(triplet) if debug: # Debug statement. print("\nContents of value_triplets: " + str(value_triplets) + "\n") # Defines the domain. domain = {} for var in variables: domain[var] = value_triplets if debug: # Debug statements. for key, value in domain.items(): print("My domain key: " + key) print("My domain values: " + str(value)) # Define neighbors of each variable. neighbors = csp.parse_neighbors( """cs108: cs112 cs212 cs214 cs232 cs262 cs344; cs112: cs108 cs212 cs214 cs232 cs262 cs344; cs212: cs108 cs112 cs214 cs232 cs262 cs344; cs214: cs108 cs112 cs212 cs232 cs262 cs344; cs232: cs108 cs112 cs212 cs214 cs262 cs344; cs262: cs108 cs112 cs212 cs214 cs232 cs344; cs344: cs108 cs112 cs212 cs214 cs232 cs262""") if debug: # Debug statements. print("\n\n") for key, value in neighbors.items(): print("Neighbors Key:" + key) print("Neighbors Values: " + str(value)) """ The constraints are that: each course should be offered exactly once by the assigned faculty member. a faculty member can only teach one thing at a time. a room can only have one class at each time. """ # Define the constraints on the variables. # FIXME - WTB more documentation for AIMA code. def scheduling_constraint(A, a, B, b): if debug: # Debug statement. print("\nvalue of A: " + A) print("value of B: " + B) print("value of a: " + a) print("value of b: " + b) # Split "a" and "b" from triplets into singlets to test for same'ness. a_split = str(a).split() b_split = str(b).split() if debug: # Debug statement. print("\na split contents: " + str(a_split)) print("b split contents: " + str(b_split)) # Important note: (faculty, timeslot, classroom) is the order of the split triplet!!! if a_split[0] == b_split[0] and a_split[1] == b_split[1]: return False if a_split[1] == b_split[1] and a_split[2] == b_split[2]: return False # If no constraint violations, return true. return True # raise Exception('error') return csp.CSP(variables, domain, neighbors, scheduling_constraint)
def Schedule(): Profs = 'dschuurman adams vnorman kvlinden'.split() Classes = 'cs108 cs112 cs212 cs214 cs300 cs344'.split() Times = 'mwf800 mwf900 mwf1030 mwf1130'.split() Rooms = 'sb354 sb372'.split() variables = Classes domains = {} for var in variables: domains[var] = [] for Prof in Profs: for Time in Times: for Room in Rooms: domains[var].append((Prof, Time, Room)) neighbors = parse_neighbors( 'cs108: ; cs112: ; cs212: ; cs214: ; cs300: ; cs344: ', variables) for type in [Classes]: for A in type: for B in type: if A != B: if B not in neighbors[A]: neighbors[A].append(B) if A not in neighbors[B]: neighbors[B].append(A) def schedule_constraints(A, a, B, b, recurse=0): same = (a == b) if A == B: return same if A != B: # if same professor if a[0] == b[0]: # if meeting at same time if a[1] == b[1]: return False # No professor can teach consecutive classes elif a[1] == "mwf800" and b[1] == "mwf900": return False elif b[1] == "mwf800" and a[1] == "mwf900": return False elif a[1] == "mwf1030" and b[1] == "mwf900": return False elif b[1] == "mwf1030" and a[1] == "mwf900": return False elif a[1] == "mwf1030" and b[1] == "mwf1130": return False elif b[1] == "mwf1030" and a[1] == "mwf1130": return False else: return True # if same time if a[1] == b[1]: # if classes have same professor or room if a[0] == b[0] or a[2] == b[2]: return False else: return True if a[2] == b[2]: if a[1] == b[1]: return False else: return True else: return True raise Exception('error') return CSP(variables, domains, neighbors, schedule_constraints)
times = ['mwf900', 'mwf1030', 'mwf1130', 'mwf1230', 'mwf130'] rooms = ['nh253', 'sb382'] assignments = {'cs108': 'dschuurman', 'cs112': 'adams', 'cs212':'hplantin', 'cs214':'adams', 'cs232':'pmb4', 'cs262':'vlinden', 'cs300':'vlinden'} num_courses = len(courses) # neighbors: list all pairs of courses in the format needed for parse_neighbors # does not include pairing courses with themselves or pairs that are the same in the other order neighbors_string = "" for i in range(num_courses): for j in range(num_courses-i-1): course1 = courses[i] course2 = courses[num_courses-j-1] neighbors_string += course1 + ":" + course2 + ";" neighbors_string = neighbors_string[:-1] # get rid of the last semicolon neighbors = parse_neighbors(neighbors_string, variables=courses) # list all teaching combinations (of faculty, time, and room) that could be assigned to a course domains = {} for course in courses: domains[course] = [] for prof in faculty: for time in times: for room in rooms: domains[course].append( [prof, time, room] ) # return whether the pair of courses do not conflict def scheduling_constraints(courseA, variableA, courseB, variableB): """ if the courses have the same room, same time, that fails the requirements
# all the domain possibilities domain_possibilities = [] for room in rooms: for time_slot in time_slots: for prof in professors: domain_possibilities.append(prof + " " + room + " " + time_slot) # variables : courses # domains : everything else variables = classes domains = {} for var in variables: domains[var] = domain_possibilities # neighbors : everybody is a neighbor neighbors = parse_neighbors("""CS-344: NH158 8MWF""", variables) for type in [classes, domain_possibilities]: for A in type: for B in type: if A != B: if B not in neighbors[A]: neighbors[A].append(B) if A not in neighbors[B]: neighbors[B].append(A) # constraint function # ensuring that a room is acceptable # and that no schedule conflicts occur # (i.e. kvlinden can't be in two rooms at once) def scheduler_constraint(A, a, B, b, recurse=0):
def schedule(): """CSP set-up for a class scheduling problem.""" classes = 'cs108 cs112 cs214 cs374 cs344 cs212'.split() faculty = 'Schuurman Adams Vanderlinden Plantinga'.split() times = 'mwf9 mwf10 mwf11 mwf12'.split() rooms = 'nh253 sb382'.split() # create every [professor, time, room] combo combo = [0] * 32 i = 0 for x in range(len(faculty)): for y in range(len(times)): for z in range(len(rooms)): combo[i] = [faculty[x], times[y], rooms[z]] i += 1 # Each class gets every single combination domains = {} for course in classes: domains[course] = combo # Everyone is a neighbor with everyone but themselves neighbors = parse_neighbors(""" cs108: cs112 cs214 cs374 cs344 cs212; cs112: cs214 cs374 cs344 cs212; cs214: cs374 cs344 cs212; cs374: cs344 cs212; cs344: cs212; cs212: """) def schedule_constraint(A, a, B, b): """Codes the constraints the problem must follow""" # There can only be one instance of a class if A == B: return False # Certain professors only teach certain classes if A == 'cs108' and a[0] != 'Vanderlinden': return False if B == 'cs108' and b[0] != 'Vanderlinden': return False if A == 'cs344' and a[0] != 'Vanderlinden': return False if B == 'cs344' and b[0] != 'Vanderlinden': return False if A == 'cs374' and a[0] != 'Adams': return False if B == 'cs374' and b[0] != 'Adams': return False if A == 'cs112' and a[0] != 'Adams': return False if B == 'cs112' and b[0] != 'Adams': return False if A == 'cs212' and a[0] != 'Plantinga': return False if B == 'cs212' and b[0] != 'Plantinga': return False if A == 'cs214' and a[0] != 'Schuurman': return False if B == 'cs214' and b[0] != 'Schuurman': return False # a professor cannot teach two classes at the same time if a[0] == b[0] and a[1] == b[1]: return False # Two classes cannot be in the same room at the same time if a[1] == b[1] and a[2] == b[2]: return False return True return CSP(classes, domains, neighbors, schedule_constraint)