def my_csp_problem_1(): # Defined in notebook constraints = [] variables = [] variables.append(Variable("1", ['R', 'G', 'B', 'Y'])) variables.append(Variable("2", ['R', 'G', 'B', 'Y'])) variables.append(Variable("3", ['R', 'G', 'B', 'Y'])) variables.append(Variable("4", ['R', 'G', 'B', 'Y'])) variables.append(Variable("5", ['R', 'G', 'B', 'Y'])) # these are all variable pairing of adjacent slots adjacent_pairs = [ ("1", "2"), ("1", "5"), ("2", "1"), ("2", "3"), ("2", "5"), ("3", "2"), ("3", "4"), ("3", "5"), ("4", "3"), ("4", "5"), ("5", "1"), ("5", "2"), ("5", "3"), ("5", "4") ] # No same neighbor colors def base_rule(val_a, val_b, name_a, name_b): if val_a == val_b: return False return True for pair in adjacent_pairs: constraints.append( BinaryConstraint(pair[0], pair[1], base_rule, "No same color neighbors")) return CSP(constraints, variables)
def time_traveling_csp_problem(): constraints = [] variables = [] # order of the variables here is the order given in the problem variables.append(Variable("T", ["1"])) variables.append(Variable("L", ["1", "2", "3", "4"])) variables.append(Variable("B", ["1", "2", "3", "4"])) variables.append(Variable("C", ["1", "2", "3", "4"])) variables.append(Variable("S", ["1", "2", "3", "4"])) variables.append(Variable("P", ["1", "2", "3", "4"])) variables.append(Variable("N", ["1", "2", "3", "4"])) # these are all variable pairing of adjacent seats edges = [("C", "P"), ("C", "L"), ("C", "N"), ("C", "B"), ("B", "C"), ("B", "N"), ("N", "B"), ("N", "C"), ("N", "P"), ("N", "L"), ("N", "T"), ("T", "N"), ("T", "L"), ("L", "T"), ("L", "N"), ("L", "P"), ("P", "L"), ("P", "N"), ("P", "C"), ("P", "S"), ("S", "P")] # not allowed constraints: def conflict(val_a, val_b, var_a, var_b): if val_a == val_b: return False return True for pair in edges: constraints.append( BinaryConstraint(pair[0], pair[1], conflict, "Time conflict")) return CSP(constraints, variables)
def map_coloring_csp_problem(): constraints = [] variables = [] # order of the variables here is the order given in the problem variables.append(Variable("MA", ["B"])) variables.append(Variable("TX", ["R"])) variables.append(Variable("NE", ["R", "B", "Y"])) variables.append(Variable("OV", ["R", "B", "Y"])) variables.append(Variable("SE", ["R", "B", "Y"])) variables.append(Variable("GL", ["R", "B", "Y"])) variables.append(Variable("MID", ["R", "B", "Y"])) variables.append(Variable("MW", ["R", "B", "Y"])) variables.append(Variable("SO", ["R", "B"])) variables.append(Variable("NY", ["R", "B"])) variables.append(Variable("FL", ["R", "B"])) # these are all variable pairing of adjacent seats edges = [("NE", "NY"), ("NE", "MA"), ("MA", "NY"), ("GL", "NY"), ("GL", "OV"), ("MID", "NY"), ("OV", "NY"), ("OV", "MID"), ("MW", "OV"), ("MW", "TX"), ("TX", "SO"), ("SO", "OV"), ("SO", "FL"), ("FL", "SE"), ("SE", "MID"), ("SE", "SO")] # duplicate the edges the other way. all_edges = [] for edge in edges: all_edges.append((edge[0], edge[1])) all_edges.append((edge[1], edge[0])) forbidden = [("R", "B"), ("B", "R"), ("Y", "Y")] # not allowed constraints: def forbidden_edge(val_a, val_b, name_a, name_b): if (val_a, val_b) in forbidden or (val_b, val_a) in forbidden: return False return True for pair in all_edges: constraints.append( BinaryConstraint(pair[0], pair[1], forbidden_edge, "R-B, B-R, Y-Y edges are not allowed")) return CSP(constraints, variables)
def my_csp_problem_2(): # Defined in notebook constraints = [] variables = [] colors = ['R', 'O', 'Y', 'G', 'B'] variables.append(Variable("1", colors.copy())) variables.append(Variable("2", colors.copy())) variables.append(Variable("3", colors.copy())) variables.append(Variable("4", colors.copy())) variables.append(Variable("5", colors.copy())) variables.append(Variable("6", colors.copy())) variables.append(Variable("7", colors.copy())) variables.append(Variable("8", colors.copy())) variables.append(Variable("9", colors.copy())) variables.append(Variable("10", colors.copy())) # these are all variable pairing of adjacent slots adjacent_pairs = [("1", "2"), ("1", "10"), ("10", "9"), ("10", "1")] for i in range(1, 9): adjacent_pairs.append( (variables[i].get_name(), variables[i - 1].get_name())) adjacent_pairs.append( (variables[i].get_name(), variables[i + 1].get_name())) # No same neighbor colors def base_rule(val_a, val_b, name_a, name_b): if val_a == val_b: return False return True for pair in adjacent_pairs: constraints.append( BinaryConstraint(pair[0], pair[1], base_rule, "No same color neighbors")) return CSP(constraints, variables)
def ta_scheduling_csp_problem(): constraints = [] variables = [] # order of the variables here is the order given in the problem # the domains are those pre-reduced in part A. # constraints variables.append(Variable("C", ["Mark", "Rob", "Sam"])) # optimal search variables.append(Variable("O", ["Mark", "Mike", "Sam"])) # games variables.append(Variable("G", ["Mark"])) # rules variables.append(Variable("R", ["Mark", "Mike", "Sam"])) # id-trees variables.append(Variable("I", ["Mark", "Rob", "Sam"])) # neural nets variables.append(Variable("N", ["Mike", "Sam"])) # svms variables.append(Variable("S", ["Rob"])) # boosting variables.append(Variable("B", ["Mike"])) # these are all variable pairing of adjacent seats edges = [("C", "R"), ("B", "I"), ("B", "S"), ("S", "O"), ("S", "G"), ("S", "R"), ("S", "N"), ("N", "G")] # not allowed constraints: def conflict(val_a, val_b, var_a, var_b): if val_a == val_b: return False return True for pair in edges: constraints.append( BinaryConstraint(pair[0], pair[1], conflict, "TA(subject_a) != TA(subject_b) constraint")) return CSP(constraints, variables)
def sudoku_csp_problem(partial_grid=grid): #Ensure board is 9x9. This could easily be extended to n^2 by n^2 if len(partial_grid) <> 9: 'Error: Board must be 9x9' for i in range(len(partial_grid)): if len(partial_grid[i]) <> 9: return 'Error: Board must be 9x9' # Initialize... constraints = [] indices = [(i, j) for i in range(1, 10) for j in range(1, 10)] variables = [] #Initialize variables with one variable for each square. for (i, j) in indices: if partial_grid[i - 1][j - 1] <> 0: theval = [partial_grid[i - 1][j - 1]] else: theval = range(1, 10) variables.append(Variable(str(i) + ',' + str(j), theval)) #returns i coordinate of a variable def i(var): return var.get_name()[0] #returns j coordinate of a variable def j(var): return var.get_name()[2] #gives the 3x3 box a given square is in, they are numbered left to right, top to bottom. def getbox(stri, strj): i = int(stri) j = int(strj) if i <= 3: if j <= 3: return 1 elif 4 <= j <= 6: return 2 elif 7 <= j <= 9: return 3 elif 4 <= i <= 6: if j <= 3: return 4 elif 4 <= j <= 6: return 5 elif 7 <= j <= 9: return 6 elif 7 <= i <= 9: if j <= 3: return 7 elif 4 <= j <= 6: return 8 elif 7 <= j <= 9: return 9 return 'Error: Please enter i,j in the correct range' # make list of all square sharing a row, column or box # no need to duplicate the other way around since this loops through all edges = [] for v1 in variables: for v2 in variables: if v1 <> v2 and (i(v1) == i(v2) or j(v1) == j(v2) or getbox(i(v1), j(v1)) == getbox(i(v2), j(v2))): edges.append((v1.get_name(), v2.get_name())) # not allowed to have same value for square: def nomatch_constraint(val_a, val_b, name_a, name_b): if val_a == val_b: return False return True for e in edges: constraints.append( BinaryConstraint(e[0], e[1], nomatch_constraint, "Cant match squares in same row, column, or box")) return CSP(constraints, variables)
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 range(len(variable_names)): for y in range(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)
def moose_csp_problem_1(): # We start with the reduced domain. # So the constraint that McCain must sit in seat 1 is already # covered. domain = [1, 2, 3, 4, 5, 6] variables = [] variables.append(Variable("Mc", [1])) variables.append(Variable("O", domain)) variables.append(Variable("B", domain)) variables.append(Variable("P", domain)) variables.append(Variable("M", domain)) constraints = [] def next_to(val_a, val_b, name_a=None, name_b=None): return val_a == val_b + 1 or val_a == val_b - 1 def not_next_to(val_a, val_b, name_a=None, name_b=None): return val_a != val_b + 1 and val_a != val_b - 1 # not two people can sit in one seat def not_equal(val_a, val_b, name_a=None, name_b=None): return val_a != val_b # no one can sit in two seats constraints.append(BinaryConstraint("P", "Mc", next_to, "P next to Mc")) constraints.append(BinaryConstraint("B", "O", next_to, "B next to O")) constraints.append( BinaryConstraint("Mc", "O", not_next_to, "Mc not next to O")) constraints.append( BinaryConstraint("Mc", "B", not_next_to, "Mc not next to B")) constraints.append( BinaryConstraint("P", "B", not_next_to, "P not next to B")) constraints.append( BinaryConstraint("P", "O", not_next_to, "P not next to O")) constraints.append( BinaryConstraint("O", "Mc", not_next_to, "O not next to Mc")) constraints.append( BinaryConstraint("O", "P", not_next_to, "O not next to P")) constraints.append( BinaryConstraint("B", "Mc", not_next_to, "B not next to Mc")) constraints.append( BinaryConstraint("B", "P", not_next_to, "B not next to P")) constraints.append( BinaryConstraint("M", "P", not_next_to, "M not next to P")) constraints.append(BinaryConstraint("Mc", "O", not_equal, "Mc != O")) constraints.append(BinaryConstraint("Mc", "B", not_equal, "Mc != B")) constraints.append(BinaryConstraint("Mc", "P", not_equal, "Mc != P")) constraints.append(BinaryConstraint("Mc", "M", not_equal, "Mc != M")) constraints.append(BinaryConstraint("O", "B", not_equal, "O != B")) constraints.append(BinaryConstraint("O", "P", not_equal, "O != P")) constraints.append(BinaryConstraint("O", "M", not_equal, "O != M")) constraints.append(BinaryConstraint("B", "P", not_equal, "B != P")) constraints.append(BinaryConstraint("B", "M", not_equal, "B != M")) constraints.append(BinaryConstraint("P", "M", not_equal, "P != M")) return CSP(constraints, variables)