def run(self) : s = self.options.s.split(";") node = None if len(self.selected) > 0 : node = self.selected.itervalues().next() if node.tag == '{http://www.w3.org/2000/svg}path' : self.path = CSP(node) else : error("Select a path or select nothing to create new path!") try : self.p = self.path.items[-1].points[-1][1] except : self.path = CSP( [[[P(self.view_center),P(self.view_center),P(self.view_center)]]], clean=False) self.p = self.path.items[-1].points[-1][1] self.last_command = None for a in s : self.parse_command(a) try : self.p = self.path.items[-1].points[-1][1] except : pass if node == None : self.path.draw(group = self.current_layer) else : node.set("d",self.path.to_string())
def __init__(self, graph, domain_size): self.graph = graph self.domain_size = domain_size self.astar = None self.csp = None self.astar = AStarCSP(self.graph) self.csp = CSP(self.graph) self.nodes_checked = set() self.goal_node = None
def question_5(): print_title(4) fails = [False]*2 test1= " v1 = Variable('V1', [1, 2])\n\ v2 = Variable('V2', [1, 2])\n\ v3 = Variable('V3', [1, 2, 3, 4, 5])\n\ v4 = Variable('V4', [1, 2, 3, 4, 5])\n\ v5 = Variable('V5', [1, 2, 3, 4, 5])\n\ v6 = Variable('V6', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v7 = Variable('V7', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v8 = Variable('V8', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v9 = Variable('V9', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ vars = [v1, v2, v3, v4, v5, v6, v7, v8, v9]\n\ nv9 = NValuesConstraint('9', vars, [9], 4, 5)\n\ testcsp = CSP('test', vars, [nv9])\n\ GacEnforce([nv9], testcsp, None, None)" v1 = Variable('V1', [1, 2]) v2 = Variable('V2', [1, 2]) v3 = Variable('V3', [1, 2, 3, 4, 5]) v4 = Variable('V4', [1, 2, 3, 4, 5]) v5 = Variable('V5', [1, 2, 3, 4, 5]) v6 = Variable('V6', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v7 = Variable('V7', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v8 = Variable('V8', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v9 = Variable('V9', [1, 2, 3, 4, 5, 6, 7, 8, 9]) vars = [v1, v2, v3, v4, v5, v6, v7, v8, v9] nv9 = NValuesConstraint('9', vars, [9], 4, 5) testcsp = CSP('test', vars, [nv9]) GacEnforce([nv9], testcsp, None, None) soln_doms = [set([1, 2]), set([1, 2]), set([1, 2, 3, 4, 5]), set([1, 2, 3, 4, 5]), set([1, 2, 3, 4, 5]), set([9]), set([9]), set([9]), set([9])] for i, v in enumerate(vars): if set(v.curDomain()) != soln_doms[i]: fails[0] = True print "Error: {}.curDomain() == {}".format(v.name(), v.curDomain()) print "Correct curDomin should be == {}".format(list(soln_doms[i])) if fails[0]: print "\nFail Q5 test 1\nErrors were generated on the following code:" print test1 else: print "Pass Q5 test 1" print_sep() test2 = " v1 = Variable('V1', [1, 2])\n\ v2 = Variable('V2', [1, 2])\n\ v3 = Variable('V3', [1, 2, 3, 4, 5])\n\ v4 = Variable('V4', [1, 2, 3, 4, 5])\n\ v5 = Variable('V5', [1, 2, 3, 4, 5])\n\ v6 = Variable('V6', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v7 = Variable('V7', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v8 = Variable('V8', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v9 = Variable('V9', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ vars = [v1, v2, v3, v4, v5, v6, v7, v8, v9]\n\ nv9 = NValuesConstraint('9', vars, [9], 4, 5)\n\ nv1 = NValuesConstraint('1', vars, [1], 5, 5)\n\ testcsp = CSP('test', vars, [nv1, nv9])\n\ GacEnforce([nv1, nv9], testcsp, None, None)" v1 = Variable('V1', [1, 2]) v2 = Variable('V2', [1, 2]) v3 = Variable('V3', [1, 2, 3, 4, 5]) v4 = Variable('V4', [1, 2, 3, 4, 5]) v5 = Variable('V5', [1, 2, 3, 4, 5]) v6 = Variable('V6', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v7 = Variable('V7', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v8 = Variable('V8', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v9 = Variable('V9', [1, 2, 3, 4, 5, 6, 7, 8, 9]) vars = [v1, v2, v3, v4, v5, v6, v7, v8, v9] nv9 = NValuesConstraint('9', vars, [9], 4, 5) nv1 = NValuesConstraint('1', vars, [1], 5, 5) testcsp = CSP('test', vars, [nv1, nv9]) GacEnforce([nv1, nv9], testcsp, None, None) soln_doms = [set([1]), set([1]), set([1]), set([1]), set([1]), set([9]), set([9]), set([9]), set([9])] #vars[0].pruneValue(1, None, None) for i, v in enumerate(vars): if set(v.curDomain()) != soln_doms[i]: fails[1] = True print "Error: {}.curDomain() == {}".format(v.name(), v.curDomain()) print "Correct curDomin should be == {}".format(list(soln_doms[i])) if fails[1]: print "\nFail Q5 test 2\nErrors were generated on the following code:" print test2 else: print "Pass Q5 test 2" print_sep() if not any(fails): grades[4] = outof[4]
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)
def moose_csp_problem(): constraints = [] # We start with the reduced domain. # So the constraint that McCain must sit in seat 1 is already # covered. variables = [] variables.append(Variable("1", ["Mc"])) variables.append(Variable("2", ["Y", "M", "P"])) variables.append(Variable("3", ["Y", "M", "O", "B"])) variables.append(Variable("4", ["Y", "M", "O", "B"])) variables.append(Variable("5", ["Y", "M", "O", "B"])) variables.append(Variable("6", ["Y", "M", "P"])) # these are all variable pairing of adjacent seats adjacent_pairs = [("1", "2"), ("2", "1"), ("2", "3"), ("3", "2"), ("3", "4"), ("4", "3"), ("4", "5"), ("5", "4"), ("5", "6"), ("6", "5"), ("6", "1"), ("1", "6")] # now we construct the set of non-adjacent seat pairs. nonadjacent_pairs = [] variable_names = ["1", "2", "3", "4", "5", "6"] for x in xrange(len(variable_names)): for y in xrange(x, len(variable_names)): if x == y: continue tup = (variable_names[x], variable_names[y]) rev = (variable_names[y], variable_names[x]) if tup not in adjacent_pairs: nonadjacent_pairs.append(tup) if rev not in adjacent_pairs: nonadjacent_pairs.append(rev) # all pairs is the set of all distinct seating pairs # this list is useful for checking where # the two seat are assigned to the same person. all_pairs = adjacent_pairs + nonadjacent_pairs # 1. The Moose is afraid of Palin def M_not_next_to_P(val_a, val_b, name_a, name_b): if (val_a == "M" and val_b == "P") or (val_a == "P" and val_b == "M"): return False return True for pair in adjacent_pairs: constraints.append( BinaryConstraint(pair[0], pair[1], M_not_next_to_P, "Moose can't be next to Palin")) # 2. Obama and Biden must sit next to each other. # This constraint can be directly phrased as: # # for all sets of adjacents seats # there must exist one pair where O & B are assigned # # C(1,2) or C(2,3) or C(3,4) or ... or C(6,1) # # where C is a binary constraint that checks # whether the value of the two variables have values O and B # # However the way our checker works, the constraint needs to be # expressed as a big AND. # So that when any one of the binary constraints # fails the entire assignment fails. # # To turn our original OR formulation to an AND: # We invert the constraint condition as: # # for all sets of nonadjacent seats # there must *not* exist a pair where O & B are assigned. # # not C(1,3) and not C(1,4) and not C(1,5) ... not C(6,4) # # Here C checks whether the values assigned are O and B. # # Finally, this is an AND of all the binary constraints as required. def OB_not_next_to_each_other(val_a, val_b, name_a, name_b): if (val_a == "O" and val_b == "B") or \ (val_a == "B" and val_b == "O"): return False return True for pair in nonadjacent_pairs: constraints.append( BinaryConstraint(pair[0], pair[1], OB_not_next_to_each_other, "Obama, Biden must be next to each-other")) # 3. McCain and Palin must sit next to each other def McP_not_next_to_each_other(val_a, val_b, name_a, name_b): if (val_a == "P" and val_b == "Mc") or (val_a == "Mc" and val_b == "P"): return False return True for pair in nonadjacent_pairs: constraints.append( BinaryConstraint(pair[0], pair[1], McP_not_next_to_each_other, "McCain and Palin must be next to each other")) # 4. Obama + Biden can't sit next to Palin or McCain def OB_not_next_to_McP(val_a, val_b, name_a, name_b): if ((val_a == "O" or val_a == "B") \ and (val_b == "Mc" or val_b == "P")) or \ ((val_b == "O" or val_b == "B") \ and (val_a == "Mc" or val_a == "P")): return False return True for pair in adjacent_pairs: constraints.append( BinaryConstraint(pair[0], pair[1], OB_not_next_to_McP, "McCain, Palin can't be next to Obama, Biden")) # No two seats can be occupied by the same person def not_same_person(val_a, val_b, name_a, name_b): return val_a != val_b for pair in all_pairs: constraints.append( BinaryConstraint( pair[0], pair[1], not_same_person, "No two seats can be occupied by the same person")) return CSP(constraints, variables)
# if all variables have been assigned, check if it adds correctly if len(assignment) == len(self.letters): s: int = assignment["S"] e: int = assignment["E"] n: int = assignment["N"] d: int = assignment["D"] m: int = assignment["M"] o: int = assignment["O"] r: int = assignment["R"] y: int = assignment["Y"] send: int = s * 1000 + e * 100 + n * 10 + d more: int = m * 1000 + o * 100 + r * 10 + e money: int = m * 10000 + o * 1000 + n * 100 + e * 10 + y return send + more == money return True # no conflict if __name__ == "__main__": letters: List[str] = ["S", "E", "N", "D", "M", "O", "R", "Y"] possible_digits: Dict[str, List[int]] = {} for letter in letters: possible_digits[letter] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] possible_digits["M"] = [1] # so we don't get answers starting with a 0 csp: CSP[str, int] = CSP(letters, possible_digits) csp.add_constraint(SendMoreMoneyConstraint(letters)) solution: Optional[Dict[str, int]] = csp.backtracking_search() if solution is None: print("No solution found!") else: print(solution)
def run_map_coloring(): # Generates random points coords = [] for _ in range(POINTS_NUMBER): point = [rd.randint(1, F_WIDTH), rd.randint(1, F_HEIGHT)] if point not in coords: coords.append(point) coords = [[x * LINE_DIS, y * LINE_DIS] for x, y in coords] gui = GUI(F_WIDTH, F_HEIGHT) gui.draw_background() # Connect points randomly lines = [] for _ in range(3): rd.shuffle(coords) for X in coords: # Sort by euclidean distance and get the first nearest dstn = sorted(coords, key=lambda point: math.dist(point, X)) for Y in dstn[1:]: # If two points on the line have been already chosen if [X, Y] in lines or [Y, X] in lines: continue # Check if current line intersects any other if any(map(lambda x: intersect(X, Y, *x), lines)): continue gui.draw_line(*X, *Y) lines.append([X, Y]) break # Prepare data for csp # Does not belong to problem solving grouped = {str(c): [] for c in coords} for [s, ends] in lines: if str(s) in grouped: grouped[str(s)].append(ends) # Initiate constraints and variables for map coloring problem VAR = ['red', 'blue', 'green', 'black', 'orange', 'yellow'] CONSTRAINTS = [] for x1 in grouped.keys(): for x2 in grouped[x1]: CONSTRAINTS.append( Constraint( [str(x1), str(x2)], lambda x, x1=x1, x2=x2: x[str(x1)][0] != x[str(x2)][0])) ''' ''' # Solve csp problem csp = CSP(list(VAR), {str(i): list(VAR) for i in grouped.keys()}, CONSTRAINTS) csp.solve_backtracking() # csp.solve_forward_checking() # csp.solve_ac3() if len(csp.sols) == 0: print('Solution does not exists') # gui.draw_color_points(coords, [x[0] for x in csp.doms.values()]) else: gui.draw_color_points(coords, [x[0] for x in csp.sols[0].values()]) # pass gui.root.mainloop()
skiprows=1, dtype=int) rightTimesStar = 0 rightTimesBFS = 0 rightTimesCSP = 0 totalCases = 0 totalTimeStar = 0 totalTimeBFS = 0 totalTimeDist = 0 totalTimeCSP = 0 astar = AStar(matrix) disktra = Dijkstra(matrix) bfs = BFS(matrix) csp = CSP(matrix) # (costAstar, path, timeCSP) = csp.resolve(C.HOSPITALET, C.MURCIA) # print(str(path) + " - " + str(timeCSP)) for city in C: for city2 in C: print("From :" + city.name + "\t" "to :" + city2.name) (costAstar, pathAStar, timeAStar) = astar.resolve(city, city2) print("Astart GOT: " + "Cost of:" + str(costAstar) + " Path of: " + str(pathAStar) + " Time of: " + str(timeAStar)) (costDisk, pathDisk, timeDisk) = disktra.resolve(city, city2) print("Disk GOT: " + "Cost of:" + str(costDisk) + " Path of: " +
def solve_planes(planes_problem, algo, allsolns, variableHeuristic='mrv', silent=False, trace=False): # Your implementation for Question 6 goes here. # # Do not but do not change the functions signature # (the autograder will twig out if you do). # If the silent parameter is set to True # you must ensure that you do not execute any print statements # in this function. # (else the output of the autograder will become confusing). # So if you have any debugging print statements make sure you # only execute them "if not silent". (The autograder will call # this function with silent=True, plane_scheduling.py will call # this function with silent=False) # You can optionally ignore the trace parameter # If you implemented tracing in your FC and GAC implementations # you can set this argument to True for debugging. # # Once you have implemented this function you should be able to # run plane_scheduling.py to solve the test problems (or the autograder). # # '''This function takes a planes_problem (an instance of PlaneProblem class) as input. It constructs a CSP, solves the CSP with bt_search (using the options passed to it), and then from the set of CSP solutions it constructs a list of lists specifying a schedule for each plane and returns that list of lists The required format is the list of lists is: For each plane P the list of lists contains a list L. L[0] == P (i.e., the first item of the list is the plane) and L[1], ..., L[k] (i.e., L[1:]) is the sequence of flights assigned to P. The returned list of lists should contain a list for every plane. ''' # BUILD your CSP here and store it in the variable csp # get the data from the planes_problem object planes = planes_problem.planes # list of planes flights = planes_problem.flights # list of flights can_follow = planes_problem.can_follow maintenance_flights = planes_problem.maintenance_flights frequency = planes_problem.min_maintenance_frequency # first define the variables # construct the variable: each can be allocated slot is a variable, domain is can_fly flights + '' var_array = [] # each plane is in order for plane in planes: plane_slots = [] # the first slot can only have can_start and '' first_dom = planes_problem.can_start(plane) + [''] first_var = Variable("{} slot1".format(plane, 1), first_dom) plane_slots.append(first_var) # remaining slot have can_fly and '' dom = planes_problem.can_fly(plane) + [''] for i in range(1, len(planes_problem.can_fly(plane))): var = Variable("{} slot{}".format(plane, i + 1), dom) plane_slots.append(var) var_array.append(plane_slots) # Set up the constraints # row constraints constraint_list = [] # table constraint for can follow for i in range(len(var_array)): # i is the index of plane in planes sequence = [] # construct the possible can fly sequences for each plane curr_can_fly = planes_problem.can_fly(planes[i]) num_slots = len(curr_can_fly) empty_assign = [] for _ in range(num_slots): empty_assign.append('') sequence.append(empty_assign) for first_flight in planes_problem.can_start(planes[i]): sequence_same_start = [[first_flight]] curr_step_sequence = sequence_same_start while True: flag = 0 for subsequence in curr_step_sequence: tail = subsequence[-1] new_sub = [] for nxt in curr_can_fly: if (tail, nxt) in can_follow and nxt not in subsequence: new_sub.append(subsequence + [nxt]) if len(new_sub) > 0: sequence_same_start.extend(new_sub) curr_step_sequence = new_sub else: flag = 1 if flag == 1: break for sub in sequence_same_start: if len(sub) < num_slots: sub += [''] * (num_slots - len(sub)) sequence.extend(sequence_same_start) constraint_list.append(TableConstraint('can follow', var_array[i], sequence)) # all different all_var = [] for plane_slots in var_array: all_var.extend(plane_slots) constraint_list.append(AllDiffFilterConstraint('different flights', all_var)) # construct csp problem vars = [var for row in var_array for var in row] csp = CSP("solve_planes", vars, constraint_list) # invoke search with the passed parameters solutions, num_nodes = bt_search(algo, csp, variableHeuristic, allsolns, trace) # Convert each solution into a list of lists specifying a schedule # for each plane in the format described above. allSolution = [] for solution in solutions: # solution is list of tuple of assignment assigned = [] for var, val in solution: # check all assigned if val not in assigned and val != '': assigned.append(val) if len(assigned) == len(flights): curr_solution = [] pivot = 0 for plane in planes: plane_sol = [plane] flight_sol = solution[pivot:pivot + len(planes_problem.can_fly(plane))] pivot += len(planes_problem.can_fly(plane)) # remove '' remove_empty = [] for var, val in flight_sol: if val != '': remove_empty.append(val) # check maintenance maintenance_list = [] for flight in remove_empty: if flight in maintenance_flights: maintenance_list.append(1) else: maintenance_list.append(0) if maintenance_check(maintenance_list, frequency): plane_sol.extend(remove_empty) curr_solution.append(plane_sol) if curr_solution: allSolution.append(curr_solution) # then return a list containing all converted solutions # (i.e., a list of lists of lists) return allSolution
class AStarGAC: def __init__(self, graph, domain_size): self.graph = graph self.domain_size = domain_size self.astar = None self.csp = None self.astar = AStarCSP(self.graph) self.csp = CSP(self.graph) self.nodes_checked = set() self.goal_node = None def makefunc(self, var_names, expression, envir=globals()): args = "" for n in var_names: args = args + "," + n return eval("(lambda " + args[1:] + ": " + expression + ")" , envir) # Return # "MOD" if we modified the domain # "SOL" if we solved the puzzle # "NON" if no change has happened def increment(self): # run astar #if self.csp.is_solved(): # print "Solution found!" # return "SOL" # From the pseudocode in the task description astar_result = self.astar.incremental_solver() if astar_result[0].startswith("SUCCESS"): current_csp_domains = deepcopy(self.csp.domains) found_better = False for node in self.astar.open_heap: if node not in self.nodes_checked: self.nodes_checked.add(node) else: continue self.csp.contradictory = False # rerun csp and find best guess self.csp.domains = node.domains csp_rerun_result = self.csp.rerun() if node.h == 0: print "Solution found" self.goal_node = node return "SOL" if self.csp.contradictory: self.astar.open_heap.remove(node) self.astar.open_set.remove(node) continue else: # fix node node.domains = deepcopy(self.csp.domains) found_better = True node.set_f(g=0, h=self.astar.calculate_h(node)) if found_better: node = min(self.astar.open_heap, key=attrgetter('f')) #node = self.astar.open_heap[0] #print "best f", node.f self.csp.domains = node.domains self.goal_node = node return "MOD" else: self.csp.domains = current_csp_domains heapq.heapify(self.astar.open_heap) return "NON" else: return "NON"
def initPlaneCSP(planes_problem): planes = planes_problem.planes.copy() flights = planes_problem.flights.copy() planes_can_fly_flights = planes_problem._can_fly.copy() valid_first_flights = planes_problem._flights_at_start.copy() valid_flight_prev_next_pairs = planes_problem.can_follow.copy() maintenance_flights = planes_problem.maintenance_flights.copy() min_maintenance_frequency = planes_problem.min_maintenance_frequency #First define the variables: # 构建Variables # Variable的设定是plane + 这个plane可以飞的航班flight # 假设有n个plane, 每个plane能飞m个航班flight, 那么我们就会有nm个variable在variable_arr里 variable_arr = [] for planeIndex in range(len(planes)): variable_arr.append([]) domain = [0] domain.extend(planes_can_fly_flights[planes[planeIndex]]) for flyableFlightIndex in range( len(planes_can_fly_flights[planes[planeIndex]])): newVar = Variable( "{},{}".format( planes[planeIndex], planes_can_fly_flights[ planes[planeIndex]][flyableFlightIndex]), domain) variable_arr[planeIndex].append(newVar) #Set up the constraints constraint_list = [] # Flight Maintenance constraints # 用 NValuesConstraint 因为对这个航班的数量有要求 # lowerBound is 1 # upperBound is min_maintenance_frequency required_values = [0] required_values.extend(maintenance_flights) for sub_arr in variable_arr: for index in range(len(sub_arr) - min_maintenance_frequency + 1): # scope 的长度是最多是min_maintenance_frequency scope = sub_arr[index:index + min_maintenance_frequency] # required_values 这里是maintenance的航班 # 至少有一个航班要是maintenance 航班, 最多是min_maintenance_frequency个 constraint_list.extend([ NValuesConstraint( "[{}] maintenance flight".format(sub_arr), scope, required_values, 1, min_maintenance_frequency) ]) # Consecutive flight constraints # allConsecutiveFlights 放所有的可以连接起来的flights allConsecutiveFlights = [[0, 0]] for pair in valid_flight_prev_next_pairs: allConsecutiveFlights.append(list(pair)) for flight in flights: allConsecutiveFlights.append([flight, 0]) # Construct constraints for possible consecutive two flights for sub_arr in variable_arr: for index in range(len(sub_arr) - 1): [prevFlight, nextFlight] = [sub_arr[index], sub_arr[index + 1]] # [prevFlight, nextFlight] 可以从allConsecutiveFlights里面挑选合适的pair new_constraint = TableConstraint( "[{}] consecutive flights".format(sub_arr), [prevFlight, nextFlight], allConsecutiveFlights) constraint_list.extend([new_constraint]) # First flight constraints for index in range(len(variable_arr)): initialFlight = variable_arr[index][0] initialFlightDomain = [[0]] # 0 for having no flight for possibleFirstFlight in valid_first_flights[planes[index]]: initialFlightDomain.append([possibleFirstFlight]) # initialFlight 是从 initialFlightDomain 里面挑选 constraint_list.extend([ TableConstraint("[{}] first flight".format(initialFlight), [initialFlight], initialFlightDomain) ]) # Cover all flights and no more than once variables = [var for row in variable_arr for var in row] constraint_list.extend( [coverAndNoDuplicate("all flights", variables, flights)]) return CSP("Plane Scheduling Problem", variables, constraint_list)
def run_crossmath(size, constraints): crossmath = Crossmath(size, constraints) crossmath.pretty_print(crossmath.variables) csp = CSP() csp.solve(crossmath) csp.print_solution()
def run_logic(constraints): logic = Logic(logic_constraints) csp = CSP() csp.solve(logic) csp.print_solution()
class BezierConsole(inkex.Effect): def __init__(self): inkex.Effect.__init__(self) self.OptionParser.add_option("", "--string", action="store", type="string", dest="s", default="", help="Draw string") self.OptionParser.add_option("", "--silent", action="store", type="inkbool", dest="silent", default=True, help="Do not show an errors, usable for live preview") self.OptionParser.add_option("", "--units", action="store", type="float", dest="units", default="3.543307", help="Units scale") def get_line_xy(self,x,y,a,l) : x1,y1 = self.p.x,self.p.y #warn((x,y,a,l)) if x==None : if y != None : if a!=None : a = tan(a) if abs(a)>16331778728300000 : return P(x1,y) if a == 0 : error("Bad param a=0 for y defined line. Command: %s"%self.command) return x1+(y-y1)/a,y elif l!=None : try : x = sqrt(l**2 - (y-y1)**2) except : error("Bad params, l to small. Command: %s"%self.command) return P(x,y) else : return P(x1,y) else : if a!=None and l!=None : return self.p+P(cos(a),sin(a))*l else : if y!=None : return P(x,y) else : if a!=None : a = tan(a) if abs(a)>16331778728300000 : error("Bad param a=pi/2 for x defined line. Command: %s"%self.command) else: return x, a*(x-x1) + y1 elif l!=None : try : y = sqrt(l**2 - (x-x1)**2) except : error("Bad params, l to small. Command: %s"%self.command) else : return P(x,y1) error("""Bad params for the line. Command: %s\n x = %s, y = %s, a = %s, l = %s """%(self.command,x,y,a,l)) def draw_line(self,x,y,a,l) : p1 = self.get_line_xy(x,y,a,l) self.path.join( CSP([[[self.p,self.p,self.p],[p1,p1,p1]]]) ) def move_to(self,x,y,a,l) : p1 = self.get_line_xy(x,y,a,l) self.path.items.append(CSPSubpath([[p1,p1,p1]])) def arc_on_two_points_and_slope(self,st,end,slope) : # find the center m = (end - st)/2 n = slope.ccw() # get the intersection of lines throught st and m normal to slope and st-end line l1 = Line(st,st+n) l2 = Line(st+m,st+m+m.ccw()) p = l1.intersect(l2,True) if len(p)!=1 : warn((p,l1,l2,slope)) error("Bad parameters for arc on two points. Command: %s"%self.command) c = p[0] a = (st-c).cross(slope) return Arc(st,end,c,a) def get_arg_comb(self,s,args): s = list(s) args = {"x":x,"y":y,"a":a,"r":r,"i":i,"j":j,"l":l} for i in args: if (args[i] == None and i in s or args[i] != None and i not in s) : return False return True def get_arc_param(self,x,y,a,r,i,j,l) : st = self.p c = None # asume not enought params use slope. if x !=None or y!=None: # using two points and slope. end = P(x if x!=None else self.p.x, y if y!=None else self.p.y) return self.arc_on_two_points_and_slope(self.p,end,self.slope) if a != None : if l !=None : r = l/a/2 if r != None : c = self.p+self.slope.ccw()*r if i != None or j != None : c = P(i if i!=None else self.p.x, j if j!=None else self.p.y) if c != None : end = (self.p - c).rotate(a) + c return self.arc_on_two_points_and_slope(self.p,end,self.slope) if l != None : if i != None or j != None : c = P(i if i!=None else self.p.x, j if j!=None else self.p.y) r = (self.p - c).mag() if r != None : a = l/r/2 return self.get_arc_param(None, None, a, r, None, None, None) error("To few parametersfor arc. Command: %s"%self.command) def draw_arc(self,x,y,a,r,i,j,l) : st = self.p arc = self.get_arc_param(x,y,a,r,i,j,l) #warn(arc) self.path.join(arc.to_csp()) def parse_command(self, command) : if command.strip() == "" : return self.command = command r = re.match("\s*([almhvALMHV]?)\s*((\s*[alxyrijdALXYRIJD]\s*\-?[\d\.]+)*)\s*", command) if not r: error("Cannot parse command: \"%s\""% command) r = re.match("\s*([almhvALMHV])\s*([alxyrijdALXYRIJD].*)", command) if r : warn(r.groups()) t, command = r.groups() else : t = self.last_command # parse the parameters x,y,a,l,r,i,j = None, None, None, None, None, None, None try: self.slope = self.path.slope(-1,-1,1) except: self.slope = P(1.,0.) for p in re.findall("([alxyrijALXYRIJ])\s*(\-?\d*\.?\d*)", command) : #warn(p) p = list(p) if p[0] == "A" : a = -float(p[1])/180*pi elif p[0] == "a" : a = self.slope.angle() -float(p[1])/180*pi else : p[1] = float(p[1])*self.options.units if p[0] == "x" : x = self.p.x + p[1] elif p[0] == "X" : x = p[1] elif p[0] == "y" : y = self.p.y - p[1] elif p[0] == "Y" : y = - p[1] elif p[0] == "i" : i = self.p.x + p[1] elif p[0] == "I" : I = p[1] elif p[0] == "j" : j = self.p.y - p[1] elif p[0] == "J" : J = -p[1] elif p[0] in ("r","R") : r = p[1] elif p[0] in ("d","D") : r = p[1]/2 elif p[0] in ("l","L") : l = p[1] # exec command if t in ("l","L") : self.draw_line(x,y,a,l) if t in ("a","A") : self.draw_arc(x,y,a,r,i,j,l) if t in ("m","M") : self.move_to(x,y,a,l) self.last_command = t def effect(self) : if self.options.silent : try : self.run() except : pass else : self.run() def run(self) : s = self.options.s.split(";") node = None if len(self.selected) > 0 : node = self.selected.itervalues().next() if node.tag == '{http://www.w3.org/2000/svg}path' : self.path = CSP(node) else : error("Select a path or select nothing to create new path!") try : self.p = self.path.items[-1].points[-1][1] except : self.path = CSP( [[[P(self.view_center),P(self.view_center),P(self.view_center)]]], clean=False) self.p = self.path.items[-1].points[-1][1] self.last_command = None for a in s : self.parse_command(a) try : self.p = self.path.items[-1].points[-1][1] except : pass if node == None : self.path.draw(group = self.current_layer) else : node.set("d",self.path.to_string())
def satisfied(self, assignment: Dict[int, int]) -> bool: # q1c 퀸1열 q1r 퀸1행 for q1c, q1r in assignment.items(): for q2c in range(q1c + 1, len(self.columns) + 1): if q2c in assignment: q2r: int = assignment[q2c] if q1r == q2r: return False if abs(q1r - q2r) == abs(q1c - q2c): return False return True #충돌 없음 if __name__ == "__main__": columns: List[int] = [1, 2, 3, 4, 5, 6, 7, 8] rows: Dict[int, List[int]] = {} for column in columns: rows[column] = [1, 2, 3, 4, 5, 6, 7, 8] # 체스 판 드로잉 csp: CSP[int, int] = CSP(columns, rows) csp.add_constraint(QueenConstraint(columns)) solution: Optional[Dict[int, int]] = csp.backtracking_search() if solution is None: print("답을 찾을 수 없습니다") else: print(solution)
n satisfying assignments, if n is not specified all assignments are returned Raises: Exception if the number of required assignments is greater than the number of satisfying assignments """ if (n != None) and (n > self.gatherer.solution_count()): raise Exception( 'The number of solution required is greater than the number of satisfying assingments' ) solutions = self.gatherer.get_solutions() if n != None: solutions = solutions[:n] return solutions # testing from ortools.sat.python import cp_model if __name__ == '__main__': # creating the csp csp = CSP(k=2, n=24, alpha=1.0, r=1.4, p=0.5) # initiate Solver solv = CSPSolver(csp.n, csp.d, csp.matrix, limit=4) print(solv.solution_count()) print(solv.get_satisfying_assignments(None))
from csp import CSP crossword_puzzle = CSP( var_domains={ # read across: 'a1': set("bus has".split()), 'a3': set("lane year".split()), 'a4': set("ant car".split()), # read down: 'd1': set("buys hold".split()), 'd2': set("search syntax".split()), }, constraints={ lambda a1, d1: a1[0] == d1[0], lambda d1, a3: d1[2] == a3[0], lambda a1, d2: a1[2] == d2[0], lambda d2, a3: d2[2] == a3[2], lambda d2, a4: d2[4] == a4[0], })
def __init__(self, place1, place2): super().__init__([place1, place2]) self.place1 = place1 self.place2 = place2 def satisfied(self, assignment: dict): """根据已经处理的结果判断受约束的对象是否满足约束(相邻州不能同色) 针对本问题,受约束的对象包括相邻的两个州1、2,若其中一个州还未着色,则一定可以满足约束 """ if self.place1 not in assignment or self.place2 not in assignment: return True return assignment[self.place1] != assignment[self.place2] if __name__ == '__main__': assignment = {} variables = ['We', 'No', 'So', 'Qu', 'Ne', 'Vi', 'Ta'] domins = {} for variable in variables: domins[variable] = ['red', 'green', 'blue'] csp: CSP = CSP(variables, domins) neighbour = [('We', 'No'), ('We', 'So'), ('So', 'No'), ('Qu', 'No'), ('Qu', 'So'), ('Qu', 'Ne'), ('Ne', 'So'), ('Vi', 'So'), ('Vi', 'Ne'), ('Vi', 'Ta')] for elem in neighbour: csp.add_constraint(MapColoringConstraint(*elem)) solution = csp.backtracking_search(assignment) print(solution) # {'We': 'red', 'No': 'green', 'So': 'blue', 'Qu': 'red', 'Ne': 'green', 'Vi': 'red', 'Ta': 'green'}
term_1_solution = ''.join([str(solution[x]) for x in term_1]) term_2_solution = ''.join([str(solution[x]) for x in term_2]) sum_solution = ''.join([str(solution[x]) for x in sum]) print(f' {term_1} -> {term_1_solution}') print(f'+ {term_2} -> {term_2_solution}') print(f'{"-" * (len(sum) + 1)} {"-" * (len(sum))}') print(f' {sum} -> {sum_solution}') if __name__ == "__main__": variables = 'SENDMORY' digits = set(range(10)) domains = {var: digits for var in variables} domains['S'] = domains['S'] - {0} # What if we wrote: domains['S'] = {8, 9} # Set assignment_limit to 0 to turn off tracing. A positive number indicates # the number of assignments to allow (and to display) before quitting. assignment_limit = 0 # Create the CSP object csp: CSP[str, int] = CSP(list(variables), domains, assignment_limit) csp.add_constraint(csp.all_different) csp.add_constraint(send_more_money_constraint) # The argument is an assignment used to start the process of assigning values to variables. # SInce 'M' must be 1, plug that into the initial assignment. solution = csp.complete_the_assignment({'M': 1}) assignments = csp.assignments display_result('SEND', 'MORE', 'MONEY', solution, assignments)
class CSPDataset(Dataset): """ Generate a CSP Dataset """ def __init__(self, size=100, k=4, n=20, alpha=0.4, r=1.4, p=0.5, transform=False): """ Initialize the CSPDataset object Args: k: arity of each constraint. n: number of variables of the CSP. alpha: parameter that indicates the domain sizes d = n^a r: parameter that indicates the number of constraints m=nr ln n p: parameter for the tightness of each constraint transform: Optional transform to be applied on a sample. """ self.transform = transform self.csp = CSP(k, n, alpha, r, p) solv = CSPSolver(self.csp.n, self.csp.d, self.csp.matrix, limit=50) if solv.solution_count() == 0: raise Exception('No solutions found') satisfying_assignments = solv.get_satisfying_assignments() self.n_sat_assignments = solv.solution_count() # labeling sat assignments sat_labels = np.ones((solv.solution_count(), 1)) sat_assignments = np.concatenate((satisfying_assignments, sat_labels), axis=1) print('sat assgn', satisfying_assignments.shape, sat_labels.shape, sat_assignments.shape) # getting random generated assignments random_assignments = self.csp.generate_rnd_assignment( solv.solution_count() * 8) # labeling rnd assignments consistency = matrix_assignment_consistency( torch.from_numpy(random_assignments), torch.from_numpy(self.csp.matrix), self.csp.d, self.csp.n) rnd_assignments = np.concatenate( (random_assignments, consistency.numpy()), 1) print('rnd assgn', random_assignments.shape, consistency.shape, rnd_assignments.shape) self.assignments = np.concatenate((sat_assignments, rnd_assignments), 0) def __len__(self): """ Compute the length of the dataset Returns: returns the size of the dataset """ return self.assignments.shape[0] def __getitem__(self, idx): """ Get item of index idx from the dataset Returns: returns the element of the dataset of index idx """ sample = self.assignments[idx] if self.transform: sample = self.transform(sample) sample_unsqueezed = torch.unsqueeze(sample, 0) return sample_unsqueezed
locations for values in assignment.values() for locations in values ] return len(set(all_locations)) == len(all_locations) if __name__ == '__main__': grid = generate_grid(9, 9) words = [ name.upper() for name in ['matthew', 'joe', 'mary', 'sarah', 'sally'] ] locations = {} for word in words: locations[word] = generate_domain(word, grid) csp = CSP(words, locations) csp.add_constraint(WordSearchConstraint(words)) solution = csp.backtracking_search() if solution is None: print('No solution found!') else: for word, grid_locations in solution.items(): # Random reverse half the time if choice([True, False]): grid_locations.reverse() for index, letter in enumerate(word): row, column = grid_locations[index].row, grid_locations[ index].column grid[row][column] = letter
return False # Vanderlinden must teach 344 if (A == "CS-344" and prof_a != "Vanderlinden") or (B == "CS-344" and prof_b != "Vanderlinden"): return False # Schuurman must teach 384 if (A == "CS-384" and prof_a != "Schuurman") or (B == "CS-384" and prof_b != "Schuurman"): return False # Vanderlinden must teach 398 if (A == "CS-398" and prof_a != "Vanderlinden") or (B == "CS-398" and prof_b != "Vanderlinden"): return False # professor can only teach one course at a time if(prof_a == prof_b) and (time_a == time_b): return False # we can't have two courses in the same room at the same time if(room_a == room_b) and (time_a == time_b): return False return True problem = CSP(variables, domains, neighbors, scheduler_constraint) solution = backtracking_search(problem) print(solution) solution = min_conflicts(problem) print(solution)
if 'parliaments' in variable_assignment.variables['cigarettes'].values and 'japanese' in variable_assignment.variables['people'].values: if variable_assignment.variables['cigarettes'].values.index('parliaments') != variable_assignment.variables['people'].values.index('japanese'): return False if 'blue' in variable_assignment.variables['houses'].values: if variable_assignment.variables['houses'].values.index('blue') != 1: return False return True #we define a list of problem variables and their domains variables = [Variable('people', ['englishman', 'japanese', 'norwegian', 'ukrainian', 'spaniard']), Variable('houses', ['red', 'green', 'blue', 'yellow', 'ivory']), Variable('animals', ['fox', 'dog', 'horse', 'zebra', 'snails']), Variable('cigarettes', ['old gold', 'kools', 'chesterfields', 'lucky strike', 'parliaments']), Variable('drinks', ['coffee', 'tea', 'milk', 'orange juice', 'water'])] #we run the search csp_search = CSP() solution = csp_search.search(variables, value_consistent) #we print the results in a nice way print '1. ' + solution.variables['people'].values[0] + ' -- ' + solution.variables['houses'].values[0] + ' -- ' + solution.variables['animals'].values[0] + ' -- ' + solution.variables['drinks'].values[0] + ' -- ' + solution.variables['cigarettes'].values[0] print '2. ' + solution.variables['people'].values[1] + ' -- ' + solution.variables['houses'].values[1] + ' -- ' + solution.variables['animals'].values[1] + ' -- ' + solution.variables['drinks'].values[1] + ' -- ' + solution.variables['cigarettes'].values[1] print '3. ' + solution.variables['people'].values[2] + ' -- ' + solution.variables['houses'].values[2] + ' -- ' + solution.variables['animals'].values[2] + ' -- ' + solution.variables['drinks'].values[2] + ' -- ' + solution.variables['cigarettes'].values[2] print '4. ' + solution.variables['people'].values[3] + ' -- ' + solution.variables['houses'].values[3] + ' -- ' + solution.variables['animals'].values[3] + ' -- ' + solution.variables['drinks'].values[3] + ' -- ' + solution.variables['cigarettes'].values[3] print '5. ' + solution.variables['people'].values[4] + ' -- ' + solution.variables['houses'].values[4] + ' -- ' + solution.variables['animals'].values[4] + ' -- ' + solution.variables['drinks'].values[4] + ' -- ' + solution.variables['cigarettes'].values[4] print print 'The ' + solution.variables['people'].values[solution.variables['drinks'].values.index('water')] + ' drinks water'
def unassign(self, var, assignment): "Remove var from assignment (if it is there) and track conflicts." if var in assignment: self.record_conflict(assignment, var, assignment[var], -1) CSP.unassign(self, var, assignment)
def question_3(): print_title(2) tested[2] = True fails = [False, False, False, False, False] v1 = Variable('V1', [1, 2]) v2 = Variable('V2', [1, 2]) v3 = Variable('V3', [1, 2, 3, 4, 5]) v4 = Variable('V4', [1, 2, 3, 4, 5]) v5 = Variable('V5', [1, 2, 3, 4, 5]) v6 = Variable('V6', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v7 = Variable('V7', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v8 = Variable('V8', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v9 = Variable('V9', [1, 2, 3, 4, 5, 6, 7, 8, 9]) vars = [v1, v2, v3, v4, v5, v6, v7, v8, v9] ac = AllDiffConstraint('test9', vars) testcsp = CSP('test', vars, [ac]) GacEnforce([ac], testcsp, None, None) test1 = " v1 = Variable('V1', [1, 2])\n\ v2 = Variable('V2', [1, 2])\n\ v3 = Variable('V3', [1, 2, 3, 4, 5])\n\ v4 = Variable('V4', [1, 2, 3, 4, 5])\n\ v5 = Variable('V5', [1, 2, 3, 4, 5])\n\ v6 = Variable('V6', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v7 = Variable('V7', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v8 = Variable('V8', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v9 = Variable('V9', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ vars = [v1, v2, v3, v4, v5, v6, v7, v8, v9]\n\ ac = AllDiffConstraint('test9', vars)\n\ testcsp = CSP('test', vars, [ac])\n\ GacEnforce([ac], testcsp, None, None)" soln_doms = [ set([1,2]), set([1,2]), set([3,4,5]), set([3,4,5]), set([3,4,5]), set([6, 7, 8, 9]), set([6, 7, 8, 9]), set([6, 7, 8, 9]), set([6, 7, 8, 9]) ] for i, v in enumerate(vars): if set(v.curDomain()) != soln_doms[i]: fails[0] = True print("Error: {}.curDomain() == {}".format(v.name(), v.curDomain())) print("Correct curDomin should be == {}".format(list(soln_doms[i]))) if fails[0]: print("\nFail Q3 test 1\nErrors were generated on the following code:") print(test1) else: print("Pass Q3 test 1") print_sep() v1 = Variable('V1', [1, 2]) v2 = Variable('V2', [1, 2]) v3 = Variable('V3', [1, 2, 3, 4, 5]) v4 = Variable('V4', [1, 2, 3, 4, 5]) v5 = Variable('V5', [1, 2, 3, 4, 5]) v6 = Variable('V6', [1, 3, 4, 5]) v7 = Variable('V7', [1, 3, 4, 5]) ac1 = AllDiffConstraint('1', [v1,v2,v3]) ac2 = AllDiffConstraint('1', [v1,v2,v4]) ac3 = AllDiffConstraint('1', [v1,v2,v5]) ac4 = AllDiffConstraint('1', [v3,v4,v5,v6]) ac5 = AllDiffConstraint('1', [v3,v4,v5,v7]) vars = [v1, v2, v3, v4, v5, v6, v7] cnstrs = [ac1,ac2,ac3,ac4,ac5] testcsp = CSP('test2', vars, cnstrs) GacEnforce(cnstrs, testcsp, None, None) test2 = " v1 = Variable('V1', [1, 2])\n\ v2 = Variable('V2', [1, 2])\n\ v3 = Variable('V3', [1, 2, 3, 4, 5])\n\ v4 = Variable('V4', [1, 2, 3, 4, 5])\n\ v5 = Variable('V5', [1, 2, 3, 4, 5])\n\ v6 = Variable('V6', [1, 3, 4, 5])\n\ v7 = Variable('V7', [1, 3, 4, 5])\n\ ac1 = AllDiffConstraint('1', [v1,v2,v3])\n\ ac2 = AllDiffConstraint('1', [v1,v2,v4])\n\ ac3 = AllDiffConstraint('1', [v1,v2,v5])\n\ ac4 = AllDiffConstraint('1', [v3,v4,v5,v6])\n\ ac5 = AllDiffConstraint('1', [v3,v4,v5,v7])\n\ vars = [v1, v2, v3, v4, v5, v6, v7]\n\ cnstrs = [ac1,ac2,ac3,ac4,ac5]\n\ testcsp = CSP('test2', vars, cnstrs)\n\ GacEnforce(cnstrs, testcsp, None, None)" soln_doms = [ set([1,2]), set([1,2]), set([3, 4, 5]), set([3,4,5]), set([3,4,5]), set([1]), set([1]) ] #v1.pruneValue(1, None, None) for i, v in enumerate(vars): if set(v.curDomain()) != soln_doms[i]: fails[1] = True print("Error: {}.curDomain() == {}".format(v.name(), v.curDomain())) print("Correct curDomin should be == {}".format(list(soln_doms[i]))) if fails[1]: print("\nFail Q3 test 2\nErrors were generated on the following code:") print(test2) else: print("Pass Q3 test 2") print_sep() v1 = Variable('V1', [1, 2]) v2 = Variable('V2', [1, 2]) v3 = Variable('V3', [1, 2, 3, 4, 5]) v4 = Variable('V4', [1, 2, 3, 4, 5]) v5 = Variable('V5', [1, 2, 3, 4, 5]) v6 = Variable('V6', [1, 3, 4, 5]) v7 = Variable('V7', [1, 3, 4, 5]) ac1 = AllDiffConstraint('1', [v1,v2,v3,v4,v5,v6,v7]) vars = [v1, v2, v3, v4, v5, v6, v7] cnstrs = [ac1] testcsp = CSP('test2', vars, cnstrs) val = GacEnforce(cnstrs, testcsp, None, None) test3 = " v1 = Variable('V1', [1, 2])\n\ v2 = Variable('V2', [1, 2])\n\ v3 = Variable('V3', [1, 2, 3, 4, 5])\n\ v4 = Variable('V4', [1, 2, 3, 4, 5])\n\ v5 = Variable('V5', [1, 2, 3, 4, 5])\n\ v6 = Variable('V6', [1, 3, 4, 5])\n\ v7 = Variable('V7', [1, 3, 4, 5])\n\ ac1 = AllDiffConstraint('1', [v1,v2,v3,v4,v5,v6,v7])\n\ vars = [v1, v2, v3, v4, v5, v6, v7]\n\ cnstrs = [ac1]\n\ testcsp = CSP('test2', vars, cnstrs)\n\ val = GacEnforce(cnstrs, testcsp, None, None)" if val != "DWO": fails[2] = True print("Error: GacEnforce failed to return \"DWO\" returned {} instead".format(val)) if fails[2]: print("\nFail Q3 test 3\nErrors were generated on the following code:") print(test3) else: print("Pass Q3 test 3") print_sep() csp = nQueens(8, 'row') solutions, num_nodes = bt_search('GAC', csp, 'fixed', False, False) errors = csp.check(solutions) if len(errors) > 0: fails[3] = True print("Fail Q3 test 4: invalid solution(s) returned by GAC") for err in errors: print_soln(err[0]) print("\n", err[1]) if len(solutions) != 1: fails[3] = True print("Fail Q3 test 4: GAC failed to return only one solution") print(" returned: ") for s in solutions: print_soln(s) print("") ok=True for v in csp.variables(): if set(v.curDomain()) != set(v.domain()): fails[3] = True print("Fail Q3 test 4: GAC failed to restore domains of variables") if not fails[3]: print("Pass Q3 test 4") print_sep() csp = nQueens(8, 'row') solutions, num_nodes = bt_search('GAC', csp, 'fixed', True, False) errors=csp.check(solutions) if len(errors) > 0: fails[4] = True print("Fail Q3 test 5: invalid solution(s) returned by GAC") for err in errors: print_soln(err[0]) print("\n", err[1]) if len(solutions) != 92: fails[4] = True print("Fail Q3 test 5: GAC failed to return 92 solutions") print(" returned {} solutions".format(len(solutions))) ok=True for v in csp.variables(): if set(v.curDomain()) != set(v.domain()): fails[4] = True print("Fail Q3 test 5: GAC failed to restore domains of variables") if not fails[4]: print("Pass Q3 test 5") print_sep() grades[2] = 0 # First 2 tests: GACEnforce # 3rd test: Checking DWO # Last 2 tests: returning single or all solutions if sum(fails[:2]) == 0: grades[2] += 3 if not fails[2]: grades[2] +=1 if sum([fails[3], fails[4]]) == 0: grades[2] += 3
def scheduling_constraints(courseA, variableA, courseB, variableB): """ if the courses have the same room, same time, that fails the requirements if the courses have the same prof, same time, that fails the requirements if the courses have the wrong prof, that also fails the requirements """ # check if they are in the same room or with the same faculty member at the same time if variableA[TIME] == variableB[TIME] and (variableA[ROOM] == variableB[ROOM] or variableA[PROF] == variableB[PROF]): return False # check that each course is with the correct professor if variableA[PROF] != assignments[courseA] or variableB[PROF] != assignments[courseB]: return False # if it didn't fail yet, it's valid return True result = min_conflicts(CSP(courses, domains, neighbors, scheduling_constraints)) print(result) """ An explanation of the reasoning of this solution should start at the end. Because of the requirements, the min_conflicts function and the CSP class are necessary components of the solution. To decide how to go about filling the requirements of the CSP class constructor, I looked at the Sudoku, Queens, and Zebra problems. The Sudoku was a particularly helpful one. The Zebra problem wsa confusing because of documentation issues, and the queens problem sent me down the wrong track with building a subclass of CSP. Making the list of requirements was very straightforward from the problem description. From there, the problem got more complicated to approach. It make sense to have the courses be the variables because they are fixed and the other parameters need to be assigned to them. Once we were told that it worked to make all the combinations of faculty, time, and room domains, the rest of it could use strategies from the Zebra problem, but actually simpler. As you can see by running the code, this solution works and gives a schedule that fills the requirements. """
self.place1 = place1 self.place2 = place2 def satisfied(self, assignment: Dict[str, str]) -> bool: if self.place1 not in assignment or self.place2 not in assignment: return True return assignment[self.place1] != assignment[self.place2] if __name__ == "__main__": variables = ["Western Australia", "Northern Territory", "South Australia", "Queensland", "New South Wales", "Victoria", "Tasmania"] domains = {} for variable in variables: domains[variable] = ["red", "blue", "green"] csp = CSP(variables, domains) csp.add_constraint(MapColoringConstraint( "Western Australia", "Northern Territory")) csp.add_constraint(MapColoringConstraint( "Western Australia", "South Australia")) csp.add_constraint(MapColoringConstraint( "South Australia", "Northern Territory")) csp.add_constraint(MapColoringConstraint( "Queensland", "Northern Territory")) csp.add_constraint(MapColoringConstraint("Queensland", "South Australia")) csp.add_constraint(MapColoringConstraint("Queensland", "New South Wales")) csp.add_constraint(MapColoringConstraint( "New South Wales", "South Australia")) csp.add_constraint(MapColoringConstraint("Victoria", "South Australia")) csp.add_constraint(MapColoringConstraint("Victoria", "New South Wales")) csp.add_constraint(MapColoringConstraint("Victoria", "Tasmania"))
def question_3(): print_title(2) tested[2] = True fails = [False, False, False, False, False, False, False, False] v1 = Variable('V1', [1, 2]) v2 = Variable('V2', [1, 2]) v3 = Variable('V3', [1, 2, 3, 4, 5]) v4 = Variable('V4', [1, 2, 3, 4, 5]) v5 = Variable('V5', [1, 2, 3, 4, 5]) v6 = Variable('V6', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v7 = Variable('V7', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v8 = Variable('V8', [1, 2, 3, 4, 5, 6, 7, 8, 9]) v9 = Variable('V9', [1, 2, 3, 4, 5, 6, 7, 8, 9]) vars = [v1, v2, v3, v4, v5, v6, v7, v8, v9] ac = AllDiffConstraint('test9', vars) testcsp = CSP('test', vars, [ac]) GacEnforce([ac], testcsp, None, None) #v1.pruneValue(1, None, None) test1 = " v1 = Variable('V1', [1, 2])\n\ v2 = Variable('V2', [1, 2])\n\ v3 = Variable('V3', [1, 2, 3, 4, 5])\n\ v4 = Variable('V4', [1, 2, 3, 4, 5])\n\ v5 = Variable('V5', [1, 2, 3, 4, 5])\n\ v6 = Variable('V6', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v7 = Variable('V7', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v8 = Variable('V8', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ v9 = Variable('V9', [1, 2, 3, 4, 5, 6, 7, 8, 9])\n\ vars = [v1, v2, v3, v4, v5, v6, v7, v8, v9]\n\ ac = AllDiffConstraint('test9', vars)\n\ testcsp = CSP('test', vars, [ac])\n\ GacEnforce([ac], testcsp, None, None)" soln_doms = [ set([1,2]), set([1,2]), set([3,4,5]), set([3,4,5]), set([3,4,5]), set([6, 7, 8, 9]), set([6, 7, 8, 9]), set([6, 7, 8, 9]), set([6, 7, 8, 9]) ] for i, v in enumerate(vars): if set(v.curDomain()) != soln_doms[i]: fails[0] = True print "Error: {}.curDomain() == {}".format(v.name(), v.curDomain()) print "Correct curDomin should be == {}".format(list(soln_doms[i])) if fails[0]: print "\nFail Q3 test 1\nErrors were generated on the following code:" print test1 else: print "Pass Q3 test 1" print_sep() v1 = Variable('V1', [1, 2]) v2 = Variable('V2', [1, 2]) v3 = Variable('V3', [1, 2, 3, 4, 5]) v4 = Variable('V4', [1, 2, 3, 4, 5]) v5 = Variable('V5', [1, 2, 3, 4, 5]) v6 = Variable('V6', [1, 3, 4, 5]) v7 = Variable('V7', [1, 3, 4, 5]) ac1 = AllDiffConstraint('1', [v1,v2,v3]) ac2 = AllDiffConstraint('1', [v1,v2,v4]) ac3 = AllDiffConstraint('1', [v1,v2,v5]) ac4 = AllDiffConstraint('1', [v3,v4,v5,v6]) ac5 = AllDiffConstraint('1', [v3,v4,v5,v7]) vars = [v1, v2, v3, v4, v5, v6, v7] cnstrs = [ac1,ac2,ac3,ac4,ac5] testcsp = CSP('test2', vars, cnstrs) GacEnforce(cnstrs, testcsp, None, None) test2 = " v1 = Variable('V1', [1, 2])\n\ v2 = Variable('V2', [1, 2])\n\ v3 = Variable('V3', [1, 2, 3, 4, 5])\n\ v4 = Variable('V4', [1, 2, 3, 4, 5])\n\ v5 = Variable('V5', [1, 2, 3, 4, 5])\n\ v6 = Variable('V6', [1, 3, 4, 5])\n\ v7 = Variable('V7', [1, 3, 4, 5])\n\ ac1 = AllDiffConstraint('1', [v1,v2,v3])\n\ ac2 = AllDiffConstraint('1', [v1,v2,v4])\n\ ac3 = AllDiffConstraint('1', [v1,v2,v5])\n\ ac4 = AllDiffConstraint('1', [v3,v4,v5,v6])\n\ ac5 = AllDiffConstraint('1', [v3,v4,v5,v7])\n\ vars = [v1, v2, v3, v4, v5, v6, v7]\n\ cnstrs = [ac1,ac2,ac3,ac4,ac5]\n\ testcsp = CSP('test2', vars, cnstrs)\n\ GacEnforce(cnstrs, testcsp, None, None)" soln_doms = [ set([1,2]), set([1,2]), set([3, 4, 5]), set([3,4,5]), set([3,4,5]), set([1]), set([1]) ] #v1.pruneValue(1, None, None) for i, v in enumerate(vars): if set(v.curDomain()) != soln_doms[i]: fails[1] = True print "Error: {}.curDomain() == {}".format(v.name(), v.curDomain()) print "Correct curDomin should be == {}".format(list(soln_doms[i])) if fails[1]: print "\nFail Q3 test 2\nErrors were generated on the following code:" print test2 else: print "Pass Q3 test 2" print_sep() csp = sudokuCSP(b1, 'neq') GacEnforce(csp.constraints(), csp, None, None) vars=csp.variables() vars.sort(key=lambda var: var.name()) soln_doms = [ set([3]), set([1]), set([2]), set([5]), set([9]), set([8]), set([7]), set([6]), set([4]), set([9]), set([4]), set([6]), set([7]), set([3]), set([1]), set([2]), set([5]), set([8]), set([8]), set([7]), set([5]), set([4]), set([2]), set([6]), set([9]), set([1]), set([3]), set([5]), set([6]), set([7]), set([8]), set([4]), set([2]), set([3]), set([9]), set([1]), set([4]), set([8]), set([1]), set([3]), set([6]), set([9]), set([5]), set([7]), set([2]), set([2]), set([9]), set([3]), set([1]), set([7]), set([5]), set([4]), set([8]), set([6]), set([1]), set([3]), set([8]), set([2]), set([5]), set([7]), set([6]), set([4]), set([9]), set([6]), set([5]), set([4]), set([9]), set([1]), set([3]), set([8]), set([2]), set([7]), set([7]), set([2]), set([9]), set([6]), set([8]), set([4]), set([1]), set([3]), set([5])] #vars[0].pruneValue(3, None, None) for i, v in enumerate(vars): if set(v.curDomain()) != soln_doms[i]: fails[2] = True print "Error: {}.curDomain() == {}".format(v.name(), v.curDomain()) print "Correct curDomin should be == {}".format(list(soln_doms[i])) if fails[2]: print "\nFail Q3 test 3\nErrors were generated on the following code:" print "python2.7 sudoku.py -e -m neq 1" else: print "Pass Q3 test 3" print_sep() csp = sudokuCSP(b5, 'neq') GacEnforce(csp.constraints(), csp, None, None) vars=csp.variables() vars.sort(key=lambda var: var.name()) soln_doms = [ set([2, 4, 5, 8]), set([6]), set([2, 4, 5, 8]), set([1]), set([2, 5, 8]), set([3, 8]), set([7, 9]), set([3, 5, 7, 8]), set([3, 7, 8, 9]), set([1, 2, 5, 8]), set([1, 2, 5, 8]), set([7]), set([2, 3, 9]), set([2, 5, 6, 8]), set([3, 6, 8]), set([1, 6, 9]), set([3, 5, 6, 8]), set([4]), set([1, 5, 8]), set([9]), set([3]), set([4]), set([7]), set([6, 8]), set([1, 6]), set([5, 6, 8]), set([2]), set([2, 4, 8]), set([2, 4, 7, 8]), set([1]), set([6]), set([3]), set([9]), set([2, 4, 7]), set([2, 4, 7]), set([5]), set([5, 9]), set([5, 7]), set([5, 6, 9]), set([8]), set([4]), set([2]), set([1, 6, 7, 9]), set([3, 6, 7]), set([1, 3, 6, 7, 9]), set([3]), set([2, 4]), set([2, 4, 6, 9]), set([5]), set([1]), set([7]), set([8]), set([2, 4, 6]), set([6, 9]), set([6]), set([2, 4, 5, 8]), set([2, 4, 5, 8]), set([2, 7]), set([9]), set([4, 8]), set([3]), set([1]), set([7, 8]), set([7]), set([1, 2, 3, 4, 8]), set([2, 4, 8, 9]), set([2, 3]), set([2, 6, 8]), set([1, 3, 4, 6, 8]), set([5]), set([2, 4, 6, 8]), set([6, 8]), set([1, 2, 4, 8]), set([1, 2, 3, 4, 8]), set([2, 4, 8]), set([2, 3, 7]), set([2, 6, 8]), set([5]), set([2, 4, 6, 7]), set([9]), set([6, 7, 8]) ] #vars[0].pruneValue(2, None, None) for i, v in enumerate(vars): if set(v.curDomain()) != soln_doms[i]: fails[3] = True print "Error: {}.curDomain() == {}".format(v.name(), v.curDomain()) print "Correct curDomin should be == {}".format(list(soln_doms[i])) if fails[3]: print "\nFail Q3 test 4\nErrors were generated on the following code:" print "python2.7 sudoku.py -e -m neq 5" else: print "Pass Q3 test 4" print_sep() v1 = Variable('V1', [1, 2]) v2 = Variable('V2', [1, 2]) v3 = Variable('V3', [1, 2, 3, 4, 5]) v4 = Variable('V4', [1, 2, 3, 4, 5]) v5 = Variable('V5', [1, 2, 3, 4, 5]) v6 = Variable('V6', [1, 3, 4, 5]) v7 = Variable('V7', [1, 3, 4, 5]) ac1 = AllDiffConstraint('1', [v1,v2,v3]) ac2 = AllDiffConstraint('1', [v1,v2,v4]) ac3 = AllDiffConstraint('1', [v1,v2,v5]) ac4 = AllDiffConstraint('1', [v3,v4,v5,v6]) ac5 = AllDiffConstraint('1', [v3,v4,v5,v7]) neq = NeqConstraint('2', [v6,v7]) vars = [v1, v2, v3, v4, v5, v6, v7] cnstrs = [ac1,ac2,ac3,ac4,ac5,neq] testcsp = CSP('test2', vars, cnstrs) val = GacEnforce(cnstrs, testcsp, None, None) test5 = " v1 = Variable('V1', [1, 2])\n\ v2 = Variable('V2', [1, 2])\n\ v3 = Variable('V3', [1, 2, 3, 4, 5])\n\ v4 = Variable('V4', [1, 2, 3, 4, 5])\n\ v5 = Variable('V5', [1, 2, 3, 4, 5])\n\ v6 = Variable('V6', [1, 3, 4, 5])\n\ v7 = Variable('V7', [1, 3, 4, 5])\n\ ac1 = AllDiffConstraint('1', [v1,v2,v3])\n\ ac2 = AllDiffConstraint('1', [v1,v2,v4])\n\ ac3 = AllDiffConstraint('1', [v1,v2,v5])\n\ ac4 = AllDiffConstraint('1', [v3,v4,v5,v6])\n\ ac5 = AllDiffConstraint('1', [v3,v4,v5,v7])\n\ neq = NeqConstraint('2', [v6,v7])\n\ vars = [v1, v2, v3, v4, v5, v6, v7]\n\ cnstrs = [ac1,ac2,ac3,ac4,ac5]\n\ testcsp = CSP('test2', vars, cnstrs)\n\ val = GacEnforce(cnstrs, testcsp, None, None)" #val = 'fo' if val != "DWO": fails[4] = True print "Error: GacEnforce failed to return \"DWO\" returned {} instead".format(val) if fails[4]: print "\nFail Q3 test 5\nErrors were generated on the following code:" print test5 else: print "Pass Q3 test 5" print_sep() csp = nQueens(8, False) solutions, num_nodes = bt_search('GAC', csp, 'fixed', False, False) errors = csp.check(solutions) if len(errors) > 0: fails[5] = True print "Fail Q3 test 6: invalid solution(s) returned by GAC" for err in errors: print_soln(err[0]) print "\n", err[1] if len(solutions) != 1: fails[5] = True print "Fail Q3 test 6: GAC failed to return only one solution" print " returned: " for s in solutions: print_soln(s) print "" ok=True for v in csp.variables(): if set(v.curDomain()) != set(v.domain()): fails[5] = True print "Fail Q3 test 6: GAC failed to restore domains of variables" if not fails[5]: print "Pass Q3 test 6" print_sep() csp = nQueens(8, False) solutions, num_nodes = bt_search('GAC', csp, 'fixed', True, False) errors=csp.check(solutions) if len(errors) > 0: fails[6] = True print "Fail Q3 test 7: invalid solution(s) returned by GAC" for err in errors: print_soln(err[0]) print "\n", err[1] if len(solutions) != 92: fails[6] = True print "Fail Q3 test 7: GAC failed to return 92 solutions" print " returned {} solutions".format(len(solutions)) ok=True for v in csp.variables(): if set(v.curDomain()) != set(v.domain()): fails[6] = True print "Fail Q3 test 7: GAC failed to restore domains of variables" if not fails[7]: print "Pass Q3 test 7" print_sep() grades[2] = 0 if sum(fails[:4]) == 0: grades[2] += 3 if not fails[4]: grades[2] +=1 if grades[2] >= 3: if sum([fails[5], fails[6]]) == 0: grades[2] += 3
class MapColoringProblem: def __init__(self, points_number, map_width, map_height): self.csp: Optional[CSP] = None self.points: List[List[int]] = [] self.connections: List[List[int]] = [] self.width = map_width self.height = map_height self.points_number = points_number for i in range(0, points_number): self.connections.append([]) self.colors = {} def init_problem(self, colors_number): if self.points == []: raise ProblemNotInitializedException() variables: List[Tuple[int, int]] = [] for p in self.points: variables.append((p[0], p[1])) domains: Dict[Tuple[int, int], List[int]] = {} domain = [] for i in range(1, colors_number + 1): domain.append(i) for variable in variables: domains[variable] = copy.deepcopy(domain) self.csp = CSP(variables, domains) self.add_constraints() def add_constraints(self): constraints = [] for p in self.points: for p2_idx in self.connections[self.points.index(p)]: p2 = self.points[p2_idx] if not (p, p2) in constraints and not (p2, p) in constraints: constraints.append((p, p2)) # self.csp.add_constraint(MapColoringConstraint((p[0], p[1]), (p2[0], p2[1]))) for c in constraints: self.csp.add_constraint( MapColoringConstraint((c[0][0], c[0][1]), (c[1][0], c[1][1]))) def solve(self): if self.csp == None: raise ProblemNotInitializedException() else: solutions = self.csp.backtracking_search( evaluate=self.csp.forward_checking, only_first_result=True) if solutions == []: print("No solution found...") else: self.print_solutions(solutions) self.get_colors_from_solutions(solutions) def get_colors_from_solutions(self, solutions): i = 0 for solution in solutions: self.colors[i] = [] for point in self.points: self.colors[i].append(solution[(point[0], point[1])]) i += 1 def print_solutions(self, solutions): for solution in solutions: for k in solution: color = "" if solution[k] == 1: color = "Blue" elif solution[k] == 2: color = "Green" elif solution[k] == 3: color = "Red" elif solution[k] == 4: color = "Yellow" elif solution[k] == 5: color == "Light green" else: color = solution[k] print(f"Point: {k}, color: {color}") print() print("Visited Nodes:", self.csp.visited_nodes) def generate_map(self): for i in range(self.points_number): while True: x = randint(1, self.width - 1) y = randint(1, self.height - 1) if [x, y] not in self.points: self.points.append([x, y]) break self.generate_connections() def print_map(self): if self.points == []: raise ProblemNotInitializedException() if self.colors == []: raise SolutionNotResolvedException() i = 0 for k in self.colors.keys(): colors = self.colors[k] print(colors) json = { "board": self.width, "regions": copy.deepcopy(self.points), "colors": colors, #"colors": [5, 5, 5, 5, 5], "connections": self.connections } #print(json) drawer = BoardDrawer(json) im = drawer.get_image() output_path = f"map_images/generated_map_{i+1}.png" im.save(output_path) i += 1 def generate_connections(self): done_points = [] while len(done_points) < len(self.points): for p in self.points: neighbour = self.find_closest(p) if neighbour: self.connections[self.points.index(p)].append( self.points.index(neighbour)) self.connections[self.points.index(neighbour)].append( self.points.index(p)) else: if p not in done_points: done_points.append(p) def find_closest(self, point) -> List[int]: min_distance = self.width * self.height closest = None pt_index = self.points.index(point) for other in self.points: if other != point and self.points.index( other) not in self.connections[pt_index]: if not self.intersects(point, other): distance = self.calculate_distance(point, other) if distance < min_distance: closest = other min_distance = distance return closest def intersects(self, point1, point2): for p1 in self.points: for p2_idx in self.connections[self.points.index(p1)]: p2 = self.points[p2_idx] int_pt = tools.find_intersection(point1, point2, p1, p2) if int_pt != None and int_pt != point1 and int_pt != point2: return True # if tools.intersects(point1, point2, p1, p2): # return True return False def calculate_distance(self, point, other): a = other[0] - point[0] b = other[1] - point[1] return math.sqrt(a * a + b * b)
def satisfied(self, assignment: Dict[str, List[GridLocation]]) -> bool: # if there are any duplicates grid locations then there is an overlap all_locations = [ locs for values in assignment.values() for locs in values ] return len(set(all_locations)) == len(all_locations) if __name__ == "__main__": grid: Grid = generate_grid(9, 9) words: List[str] = ["MATTHEW", "JOE", "MARY", "SARAH", "SALLY"] locations: Dict[str, List[List[GridLocation]]] = {} for word in words: locations[word] = generate_domain(word, grid) csp: CSP[str, List[GridLocation]] = CSP(words, locations) csp.add_constraint(WordSearchConstraint(words)) solution: Optional[Dict[str, List[GridLocation]]] = csp.backtracking_search() if solution is None: print("No solution found!") else: for word, grid_locations in solution.items(): # random reverse half the time if choice([True, False]): grid_locations.reverse() for index, letter in enumerate(word): (row, col) = (grid_locations[index].row, grid_locations[index].column) grid[row][col] = letter display_grid(grid)
def solve_planes(planes_problem, algo, allsolns, variableHeuristic='mrv', silent=False, trace=True): # Your implementation for Question 6 goes here. # # Do not but do not change the functions signature # (the autograder will twig out if you do). # If the silent parameter is set to True # you must ensure that you do not execute any print statements # in this function. # (else the output of the autograder will become confusing). # So if you have any debugging print statements make sure you # only execute them "if not silent". (The autograder will call # this function with silent=True, plane_scheduling.py will call # this function with silent=False) # You can optionally ignore the trace parameter # If you implemented tracing in your FC and GAC implementations # you can set this argument to True for debugging. # # Once you have implemented this function you should be able to # run plane_scheduling.py to solve the test problems (or the autograder). # # '''This function takes a planes_problem (an instance of PlaneProblem class) as input. It constructs a CSP, solves the CSP with bt_search (using the options passed to it), and then from the set of CSP solutions it constructs a list of lists specifying a schedule for each plane and returns that list of lists The required format is the list of lists is: For each plane P the list of lists contains a list L. L[0] == P (i.e., the first item of the list is the plane) and L[1], ..., L[k] (i.e., L[1:]) is the sequence of flights assigned to P. The returned list of lists should contain a list for every plane. ''' # BUILD your CSP here and store it in the varable csp planes = planes_problem.planes flights = planes_problem.flights can_follow = planes_problem.can_follow maintenance_flights = planes_problem.maintenance_flights min_maintenance = planes_problem.min_maintenance_frequency flights_of_planes = [] variables = [] constraints_list = [] max_flights = 0 for p in planes: if len(planes_problem.can_fly(p)) > max_flights: max_flights = len(planes_problem.can_fly(p)) if max_flights == len(flights): break for plane in planes: for i in range(max_flights): if i == 0: # Constraint 2 var = Variable(plane + ' flight' + str(i), planes_problem.can_start(plane) + ['']) else: # Constraint 1 var = Variable(plane + ' flight' + str(i), planes_problem.can_fly(plane) + ['']) variables.append(var) for i in range(len(planes)): lst = [] for j in range(max_flights): lst.append(variables[j + i * max_flights]) flights_of_planes.append(lst) # Constraint 3 can_follow_lists = [list(c) for c in can_follow] + [[f, ''] for f in flights] + [['', '']] for i in range(len(flights_of_planes)): for j in range(1, len(flights_of_planes[i])): constraints_list.append( TableConstraint( "Can follow ", [flights_of_planes[i][j - 1], flights_of_planes[i][j]], can_follow_lists)) # Constraint 4 for i in range(len(flights_of_planes)): for j in range(len(flights_of_planes[i]) - min_maintenance + 1): constraints_list.append( NValuesConstraint("Maintenance", flights_of_planes[i][j:j + min_maintenance], maintenance_flights, 1, min_maintenance)) # Constraint 5 non_empty_variables = [] for v in variables: if v.getValue() != '': non_empty_variables.append(v) constraints_list.append( AllDiffConstraint("All Flights", non_empty_variables)) constraints_list.append( NValuesConstraint("Every flight flown", non_empty_variables, flights, len(flights), len(flights))) csp = CSP('plane scheduling', variables, constraints_list) # invoke search with the passed parameters solutions, num_nodes = bt_search(algo, csp, variableHeuristic, allsolns, trace) # Convert each solution into a list of lists specifying a schedule # for each plane in the format described above. formatted_sol = [] for s in solutions: total_sol = [] for i in range(len(planes)): for j in range(max_flights): curr_sol = [planes[i]] for k in range(len(s)): if s[k][0].name().split( )[0] == planes[i] and s[k][1] != '': curr_sol.append(s[k][1]) if curr_sol not in total_sol: total_sol.append(curr_sol) formatted_sol.append(total_sol) # then return a list containing all converted solutions # (i.e., a list of lists of lists) return formatted_sol
if __name__ == "__main__": WA: str = "Western Australia" NT: str = "Northern Territory" SA: str = "South Australia" QL: str = "Queensland" NW: str = "New South Wales" VA: str = "Victoria" TM: str = "Tasmania" variables: List[str] = [WA, NT, SA, QL, NW, VA, TM] domains: Dict[str, List[str]] = { variable: ["red", "green", "blue"] for variable in variables } csp: CSP[str, str] = CSP(variables, domains) csp.add_constraint(MapColoringConstraint(WA, NT)) csp.add_constraint(MapColoringConstraint(WA, SA)) csp.add_constraint(MapColoringConstraint(SA, NT)) csp.add_constraint(MapColoringConstraint(QL, NT)) csp.add_constraint(MapColoringConstraint(QL, SA)) csp.add_constraint(MapColoringConstraint(QL, NW)) csp.add_constraint(MapColoringConstraint(NW, SA)) csp.add_constraint(MapColoringConstraint(VA, SA)) csp.add_constraint(MapColoringConstraint(VA, NW)) csp.add_constraint(MapColoringConstraint(VA, TM)) solution: Optional[Dict[str, str]] = csp.backtracking_search() if not solution: print("solution not found") else: pprint(solution)
def solve_schedules(schedule_problem, algo, allsolns, variableHeuristic='mrv', silent=False, trace=False): #Your implementation for Question 6 goes here. # #Do not but do not change the functions signature #(the autograder will twig out if you do). #If the silent parameter is set to True #you must ensure that you do not execute any print statements #in this function. #(else the output of the autograder will become confusing). #So if you have any debugging print statements make sure you #only execute them "if not silent". (The autograder will call #this function with silent=True, class_scheduling.py will call #this function with silent=False) #You can optionally ignore the trace parameter #If you implemented tracing in your FC and GAC implementations #you can set this argument to True for debugging. # #Once you have implemented this function you should be able to #run class_scheduling.py to solve the test problems (or the autograder). # # '''This function takes a schedule_problem (an instance of ScheduleProblem class) as input. It constructs a CSP, solves the CSP with bt_search (using the options passed to it), and then from the set of CSP solution(s) it constructs a list (of lists) specifying possible schedule(s) for the student and returns that list (of lists) The required format of the list is: L[0], ..., L[N] is the sequence of class (or NOCLASS) assigned to the student. In the case of all solutions, we will have a list of lists, where the inner element (a possible schedule) follows the format above. ''' # class CSP: # def __init__(self, name, variables, constraints): #BUILD your CSP here and store it in the varable csp # util.raiseNotDefined() # use time slots as variables event_in_time = {} for class_info in schedule_problem.classes: info = class_info.split('-') time = int(info[2]) if time not in event_in_time: event_in_time[time] = [class_info] else: event_in_time[time].append(class_info) variables = [] v_domain = [] # for i in range(schedule_problem.num_time_slots): # v_domain.append(NOCLASS) v_domain.append(NOCLASS) # create variables for i in range(schedule_problem.num_time_slots): new_slot_name = "{}".format(i + 1) if (i + 1) in event_in_time: # change variables.append( Variable( new_slot_name, v_domain + event_in_time[i + 1] + event_in_time[i + 1])) else: variables.append(Variable(new_slot_name, v_domain)) # There are 4 contstrings, 3 new and 1 alredy been implemented constraints = [] # 1 # use NValuesConstraint for student should take all courses on the list # print("c1") c_type = {} for c in schedule_problem.classes: info = c.split('-') cur_type = info[0] + '-' + info[3] # print(cur_type) if cur_type in c_type: #already in c_type[cur_type].append(c) else: c_type[cur_type] = [c] # print(c_type) for key_type in c_type: constraints.append( NValuesConstraint("c1_{}".format(key_type), variables, c_type[key_type], 1, 1)) # 2, sep for sepcific class # print("c2") sep_class = {} for key_type in c_type: info = key_type.split('-') cur_class = info[0] lt = info[1] if cur_class in sep_class: #already in sep_class[cur_class][lt] = c_type[ key_type] # since there are no duplicates in c_types else: sep_class[cur_class] = {lt: c_type[key_type]} # print(sep_class) for cur_class in sep_class: if TUT in sep_class[cur_class]: # have both lec and tut constraints.append( taftercConstraint("c2_{}".format(cur_class), variables, sep_class[cur_class][LEC], sep_class[cur_class][TUT])) # 3 # print("c3") close_distance_buildings = {} for building in schedule_problem.buildings: close_distance_buildings[ building] = schedule_problem.connected_buildings(building) constraints.append(cdbConstraint("c3", variables, close_distance_buildings)) # 4 # print("c4") constraints.append( rfConstraint("c4", variables, schedule_problem.min_rest_frequency)) csp = CSP("Class_Sheduling_Problem", variables, constraints) #invoke search with the passed parameters solutions, num_nodes = bt_search(algo, csp, variableHeuristic, allsolns, trace) #Convert each solution into a list of lists specifying a schedule #for each student in the format described above. final_solution = [] for s in solutions: cur_soluction = [] for (var, val) in s: cur_soluction.append(val) if cur_soluction not in final_solution: final_solution.append(cur_soluction) return final_solution
def sudokuCSP(initial_sudoku_board, model='neq'): '''The input board is specified as a list of 9 lists. Each of the 9 lists represents a row of the board. If a 0 is in the list it represents an empty cell. Otherwise if a number between 1--9 is in the list then this represents a pre-set board position. E.g., the board ------------------- | | |2| |9| | |6| | | |4| | | |1| | |8| | |7| |4|2| | | |3| |5| | | | | |3| | | | | |1| |6| |5| | | | | |3| | | | | |6| |1| | | |5|7| |4| | |6| | |9| | | |2| | | |2| | |8| |1| | | ------------------- would be represented by the list of lists [[0,0,2,0,9,0,0,6,0], [0,4,0,0,0,1,0,0,8], [0,7,0,4,2,0,0,0,3], [5,0,0,0,0,0,3,0,0], [0,0,1,0,6,0,5,0,0], [0,0,3,0,0,0,0,0,6], [1,0,0,0,5,7,0,4,0], [6,0,0,9,0,0,0,2,0], [0,2,0,0,8,0,1,0,0]] Construct and return CSP for solving this sudoku board using binary not equals if model='neq' or using allDiff constraints if model='alldiff' The CSP contains a variable for each cell of the board with with domain equal to {1-9} if the board has a 0 at that position, and domain equal {i} if the board has a fixed number i at that cell. The CSP has a neq constraint between every relevant pair of varibles, or an alldiff constraint between every set of variables in a row, column, or sub-square ''' #your implementation for Question 4 changes this function #implement handleing of model == 'alldiff' if not model in ['neq', 'alldiff']: print "Error wrong sudoku model specified {}. Must be one of {}".format( model, ['neq', 'alldiff']) #first define the variables i = 0 var_array = [] for row_list in initial_sudoku_board: var_array.append([]) j = 0 for col in row_list: cell = initial_sudoku_board[i][j] if cell == 0: dom = [1, 2, 3, 4, 5, 6, 7, 8, 9] else: dom = [cell] var = Variable("V{},{}".format(i+1, j+1), dom) var_array[i].append(var) j += 1 i += 1 #Set up the constraints #row constraints constraint_list = [] for row in var_array: if model == 'neq': constraint_list.extend(post_all_pairs(row)) elif model == 'alldiff': ro = AllDiffConstraint("Row",row) constraint_list.append(ro) for colj in range(len(var_array[0])): scope = map(lambda row: row[colj], var_array) if model == 'neq': constraint_list.extend(post_all_pairs(scope)) elif model == 'alldiff': col = AllDiffConstraint("Column",scope) constraint_list.append(col) for i in [0, 3, 6]: for j in [0, 3, 6]: #initial upper left hand index of subsquare scope = [] for k in [0, 1, 2]: for l in [0,1,2]: scope.append(var_array[i+k][j+l]) if model == 'neq': constraint_list.extend(post_all_pairs(scope)) elif model == 'alldiff': sql = AllDiffConstraint("Square",scope) constraint_list.append(sql) vars = [var for row in var_array for var in row] return CSP("Sudoku", vars, constraint_list)
def satisfied(self, assignment: Dict[Point, str]): if self.point1 not in assignment or self.point2 not in assignment: return True return assignment[self.point1] != assignment[self.point2] if __name__ == "__main__": grid = Grid(40, 40) grid.random_points(3) # n grid.generate_connections() variables: List[Point] = grid.points domains: Dict[Point, List[str]] = {} for variable in variables: domains[variable] = ["red", "green", "blue"] csp: CSP[Point, str] = CSP(variables, domains) for connection in grid.connections: csp.add_constraint(GridColoringConstraint(connection[0], connection[1])) for lcv in [False, True]: for mcv in [False, True]: for single in [True, False]: if mcv: print("MCV", end=" ") if lcv: print("LCV", end=" ") print("SINGLE" if single else "ALL") # bt_csp = copy.copy(csp)
def main(): """ Parse the command line arguments. Make the CSP object. Do preprocessing if requested. Then call the search object. () -> None """ args = parse_cmd_line_args() #Get the appropriate functions to be used by the search variable_selection_function = get_variable_selection_function(args.variable_heuristic) value_ordering_function = get_value_ordering_function(args.value_heuristic) inference_pre_function = get_inference_function(args.preprocessing) inference_search_function = get_inference_function(args.search_inference) print "Parsing CSP file:", args.input_file_name csp = CSP() if not csp.parse_csp_file(args.input_file_name): return print "Success." initial_assignment = dict([ (var, csp.domains[var][0])\ for var in csp.variables if len(csp.domains[var]) == 1 ]) #Apply preprocessing if requested if inference_pre_function is not None: print "Preprocessing..." result = inference_pre_function(None, initial_assignment, csp) if result is None: print "Error: inconsistency detected in preprocessing." return csp.notify_of_inference(None, initial_assignment, result[0], result[1]) print "Preprocessing made", len(result[1]), "assignments." if args.output_file_name is not None: print "Writing grounded CSP to:", args.output_file_name try: with file(args.output_file_name, "w") as output_file: csp.write(output_file) except IOError as e: print "Error: cannot open output file:", args.output_file_name return print "Performing backtracking search..." assignment, explored, search_time = search(csp, initial_assignment, variable_selection_function, value_ordering_function, inference_search_function) if args.solution_file_name is None: solution_file = sys.stdout else: try: solution_file = file(args.solution_file_name, "w") except IOError as e: print "Error: could not open output file:", args.solution_file_name return #Display the result if assignment is None: print "There is no solution!" solution_file.write("UNSAT\n") solution_file.write("Explored: " + str(explored) + "\n") solution_file.write("Time: " + str(search_time) + "\n") else: print "Solution found." if args.sudoku_output: for y in xrange(1, 10): for x in xrange(1, 10): solution_file.write(assignment[str(x)+str(y)] + " ") if x % 3 == 0 and x < 9: solution_file.write("| ") solution_file.write("\n") if y%3 == 0 and y < 9: solution_file.write("---------------------\n") else: solution_file.write("SAT\n") solution_file.write("Explored: " + str(explored) + "\n") solution_file.write("Time: " + str(search_time) + "\n") solution_file.write("Solution: " + " ".join([var+"="+val\ for var,val in assignment.iteritems() ]) + "\n")
#controls the minimum probability for a label to be considered in the csp probabilitythreshold = .2 # controls the minimum confidence for a label to be present in the gold bit vector confidencethreshold = .5 # gold output for evaluation for each training example testgoldvectors = testloader.extractLabelBitVectors(confidencethreshold) #Create a new csp for each example and assign unary potentials according to the classifier #Solve the csp using backtracking search #Compare the resulting assignment to the goldlabel vectors to get accuracy predictedvectors = {'sentiment':[], 'event':[], 'time':[]} numtrainingexamples = testX.shape[0] for exampleindex in range(numtrainingexamples): #print 'index: ', exampleindex examplecsp = CSP() #Load in variables and unary potentials for each labeltype for labeltype in ['sentiment', 'event', 'time']: numlabels = len(loader.labelnames[labeltype]) # get the unary probabilies for a given example index- sorted arithmetically so should be in order of increasing label index labelprobabilities= classifiers[labeltype].predict_proba(testX[exampleindex])# testx needs to be in the correct format for labelindex in range(numlabels): # get the name of the variable in the csp varname = loader.labelnames[labeltype][labelindex] #only add variable to csp if it's probability of occuring is nontrivial to save memory if labelprobabilities[0][labelindex] > probabilitythreshold: # add a variable with domain 1 or 0 representing whether we want to classify this z examplecsp.add_variable(varname, [0,1]) score = labelprobabilities[0][labelindex] examplecsp.add_unary_potential(varname, lambda x: math.pow(score, x) * math.pow(1-score, 1-x)) #add_binary_constraints(binaryConstraints, examplecsp)