def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 2 goes in this function body. #you must not change the function parameters. #Implementing handling of the trace parameter is optional #but it can be useful for debugging #trace = True if unAssignedVars.empty(): if trace: print "{} Solution Found".format(csp.name()) soln = [] for var in csp.variables(): soln.append((var, var.getValue())) #if allSolutions: return [soln] #else: #exit bt_search.nodesExplored += 1 solns = [] nxtvar = unAssignedVars.extract() if trace: print "==>Trying {}".format(nxtvar.name()) for val in nxtvar.curDomain(): #curDomain for FC!! if trace: print "==> {} = {}".format(nxtvar.name(), val) nxtvar.setValue(val) noDWO = True for constraint in csp.constraintsOf(nxtvar): #print "fc constr,", constraint if constraint.numUnassigned() == 1: if FCCheck(constraint, nxtvar, val) == "DWO": noDWO = False if trace: print "<==falsified constraint\n" break if noDWO: new_solns = FC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) Variable.restoreValues(nxtvar, val) if len(solns)> 0 and not allSolutions: break Variable.restoreValues(nxtvar, val) nxtvar.unAssign() #same as set Vlue none #nxtvar.setValue(None) unAssignedVars.insert(nxtvar) return solns
def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 2 goes in this function body. #you must not change the function parameters. #Implementing handling of the trace parameter is optional #but it can be useful for debugging if unAssignedVars.empty(): if trace: print "{} Solution Found".format(csp.name()) soln = [] for v in csp.variables(): soln.append((v, v.getValue())) return [soln] #each call returns a list of solutions found bt_search.nodesExplored += 1 solns = [] #so far we have no solutions recursive calls nxtvar = unAssignedVars.extract() if trace: print "==>Trying {}".format(nxtvar.name()) for val in nxtvar.curDomain(): if trace: print "==> {} = {}".format(nxtvar.name(), val) nxtvar.setValue(val) constraintsOK = True lastVar = None pruned_var = [] for cnstr in csp.constraintsOf(nxtvar): if cnstr.numUnassigned() == 1: lastVar = cnstr.unAssignedVars()[0] pruned_var.append(lastVar) if FCCheck(cnstr, nxtvar, val) == "DWO": constraintsOK = False if trace: print "<==falsified constraint\n" break if constraintsOK: new_solns = FC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: Variable.restoreValues(nxtvar, val) break #don't bother with other values of nxtvar #as we found a soln. # FCCheck failed or search rest solns, need to restore Variable.restoreValues(nxtvar, val) nxtvar.unAssign() unAssignedVars.insert(nxtvar) return solns
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging if unAssignedVars.empty(): if trace: print("{} Solution Found".format(csp.name())) soln = [] for v in csp.variables(): soln.append((v, v.getValue())) return [soln] #each call returns a list of solutions found solns = [] #so far we have no solutions recursive calls nxtvar = unAssignedVars.extract() if trace: print("==>Trying {}".format(nxtvar.name())) for val in nxtvar.curDomain(): if trace: print("==> {} = {}".format(nxtvar.name(), val)) nxtvar.setValue(val) # Prune all values of V ≠ d from CurDom[V] for p in nxtvar.curDomain(): if val != p: nxtvar.pruneValue(p, nxtvar, val) # for each constraint C whose scope contains V 
 Put C on GACQueue
 GACQueue = [] for c in csp.constraints(): if nxtvar in c.scope(): GACQueue.append(c) if GacEnforce(GACQueue, csp, nxtvar, val) != "DWO": new_solns = GAC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: Variable.restoreValues(nxtvar, val) break Variable.restoreValues(nxtvar, val) nxtvar.unAssign() unAssignedVars.insert(nxtvar) return solns
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging if unAssignedVars.empty(): if trace: print("{} Solution Found".format(csp.name())) soln = [] for v in csp.variables(): soln.append((v, v.getValue())) return [soln] #each call returns a list of solutions found bt_search.nodesExplored += 1 solns = [] #so far we have no solutions recursive calls "Choos a value from the unassigned ones" nxtvar = unAssignedVars.extract() if trace: print("==>Trying {}".format(nxtvar.name())) "Assign every value to the next variable from its domain -- Note that curDomain is used instead of domain because cur is pruned" for val in nxtvar.curDomain(): if trace: print("==> {} = {}".format(nxtvar.name(), val)) nxtvar.setValue(val) "For every constraint that the next variable has to satisfy -- " if GacEnforce(csp.constraintsOf(nxtvar), csp, nxtvar, val) == "OK": new_solns = GAC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: Variable.restoreValues(nxtvar, val) break #don't bother with other values of nxtvar #as we found a soln. "Restore all the values that have been pruned away" Variable.restoreValues(nxtvar, val) nxtvar.unAssign() unAssignedVars.insert(nxtvar) return solns
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging # util.raiseNotDefined() # print unAssignedVars if unAssignedVars.empty(): if trace: print "{} Solution Found".format(csp.name()) soln = [] for var in csp.variables(): soln.append((var, var.getValue())) return [soln] bt_search.nodesExplored += 1 solns = [] nextVar = unAssignedVars.extract() if trace: print "{} Solution Found".format(csp.name()) for value in nextVar.curDomain(): nextVar.setValue(value) noDWO = True constraints = csp.constraintsOf(nextVar) if GacEnforce(constraints, csp, nextVar, value) == "DWO": if trace: print "<==falsified constraint\n" noDWO = False if noDWO: newSolns = GAC(unAssignedVars, csp, allSolutions, trace) if newSolns: solns.extend(newSolns) if len(solns) > 0 and not allSolutions: # restore pruned values even if FC is terminating after one solution found; if keep finding other # solutions, the second restoreValues gonna be executed Variable.restoreValues(nextVar, value) break Variable.restoreValues(nextVar, value) nextVar.unAssign() unAssignedVars.insert(nextVar) return solns
def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 2 goes in this function body. #you must not change the function parameters. #Implementing handling of the trace parameter is optional #but it can be useful for debugging #Forward checking, pass unassigned variables if unAssignedVars.empty(): #no more unassigned variables # print "{} Solution Found".format(csp.name()) soln = [] for var in csp.variables(): soln.append((var, var.getValue())) if not allSolutions: Variable.restoreValues(var, var.getValue()) return [soln] #terminate after one solution found. var = unAssignedVars.extract() #select next variable to assign # print "==>Trying {}".format(var.name()) bt_search.nodesExplored += 1 solns = [] for val in var.curDomain(): # print "==> {} = {}".format(var.name(), val) var.setValue(val) noDWO = True for constraint in csp.constraintsOf(var): if constraint.numUnassigned() == 1: if FCCheck(constraint, var, val) == "DWO": #prune future variables noDWO = False #pass var/val as reason # print "<==falsified constraint\n" break if noDWO: solns.extend(FC(unAssignedVars, csp, allSolutions, trace)) if len(solns) > 0 and not allSolutions: break #don't bother with other values of var #as we found a soln. Variable.restoreValues(var, val) #restore values pruned by this assignment var.setValue(None) #undo assignemnt to var unAssignedVars.insert(var) #restore var to unAssignedVars return solns
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging if unAssignedVars.empty(): if trace: print "{} Solution Found".format(csp.name()) soln = [] for v in csp.variables(): soln.append((v, v.getValue())) return [soln] #each call returns a list of solutions found bt_search.nodesExplored += 1 solns = [] #so far we have no solutions recursive calls nxtvar = unAssignedVars.extract() if trace: print "==>Trying {}".format(nxtvar.name()) for val in nxtvar.curDomain(): if trace: print "==> {} = {}".format(nxtvar.name(), val) nxtvar.setValue(val) constraintsOK = True constraints = csp.constraintsOf(nxtvar) subResult = GacEnforce(constraints, csp, nxtvar, val) if subResult == "DWO": constraintsOK = False if trace: print "<==falsified constraint\n" if constraintsOK: new_solns = GAC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: Variable.restoreValues(nxtvar, val) break #don't bother with other values of nxtvar #as we found a soln. Variable.restoreValues(nxtvar, val) nxtvar.unAssign() unAssignedVars.insert(nxtvar) return solns
def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 2 goes in this function body. #you must not change the function parameters. #Implementing handling of the trace parameter is optional #but it can be useful for debugging if unAssignedVars.empty(): soln = [] for var in csp.variables(): soln.append((var, var.getValue())) return [soln] bt_search.nodesExplored += 1 solns = [] #so far we have no solutions recursive calls var = unAssignedVars.extract() for val in var.curDomain(): var.setValue(val) noDwo = True for cnstr in csp.constraintsOf(var): if cnstr.numUnassigned() == 1: if FCCheck(cnstr, var, val) == "DWO": noDwo = False break if noDwo: new_solns = FC(unAssignedVars, csp, allSolutions, trace) Variable.restoreValues(var, val) if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: break #don't bother with other values of nxtvar #as we found a soln. Variable.restoreValues(var, val) var.unAssign() unAssignedVars.insert(var) return solns
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging # util.raiseNotDefined() if unAssignedVars.empty(): if trace: print("{} Solution Found".format(csp.name())) solution = [] for var in csp.variables(): if trace: print(var.name(), ",", var.getValue()) solution.append((var, var.getValue())) return [solution] all_solutions = [] var = unAssignedVars.extract() bt_search.nodesExplored += 1 if trace: print(" Trying {}".format(var.name())) for val in var.curDomain(): if trace: print(" {} = {}".format(var.name(), val)) var.setValue(val) noDWO = True if GacEnforce(csp.constraintsOf(var), csp, var, val) == "DWO": noDWO = False if noDWO: currentSolution = GAC(unAssignedVars, csp, allSolutions, trace) all_solutions.extend(currentSolution) if (not allSolutions) and len(all_solutions) >= 1: Variable.restoreValues(var, val) break Variable.restoreValues(var, val) var.unAssign() unAssignedVars.insert(var) return all_solutions
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. #TODO: q4 unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging # TODO: q4 in CSP pseudo code if unAssignedVars.empty(): soln = [] for var in csp.variables(): soln.append((var, var.getValue())) #if allSolutions: return [soln] var = unAssignedVars.extract() bt_search.nodesExplored += 1 solns = [] for val in var.curDomain(): var.setValue(val) noDWO = True if GacEnforce(csp.constraintsOf(var), csp, var, val) == "DWO": noDWO = False if noDWO: new_solns = GAC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) Variable.restoreValues(var, val) if len(solns)> 0 and not allSolutions: break Variable.restoreValues(var, val) var.setValue(None) unAssignedVars.insert(var) return solns
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging if unAssignedVars.empty(): soln = [] for v in csp.variables(): soln.append((v, v.getValue())) return [soln] # each call returns a list of solutions found bt_search.nodesExplored += 1 solns = [] # so far we have no solutions recursive calls nxtvar = unAssignedVars.extract() for val in nxtvar.curDomain(): nxtvar.setValue(val) status = "none" DWO = "DWO" nDWO = "nDWO" if GacEnforce(csp.constraintsOf(nxtvar), csp, nxtvar, val) == DWO: status = DWO else: status = nDWO if status == nDWO: new_solns = GAC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: Variable.restoreValues(nxtvar, val) break Variable.restoreValues(nxtvar, val) nxtvar.unAssign() unAssignedVars.insert(nxtvar) return solns
def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' if unAssignedVars.empty(): if trace: print "{} Solution Found".format(csp.name()) soln = [] for v in csp.variables(): soln.append((v, v.getValue())) return [soln] # each call returns a list of solutions found bt_search.nodesExplored += 1 solns = [] # so far we have no solutions recursive calls nxtvar = unAssignedVars.extract() if trace: print "==>Trying {}".format(nxtvar.name()) for val in nxtvar.curDomain(): if trace: print "==> {} = {}".format(nxtvar.name(), val) nxtvar.setValue(val) noDWO = True for cnstr in csp.constraintsOf(nxtvar): if cnstr.numUnassigned() == 1: if FCCheck(cnstr, nxtvar, val) == "DWO": noDWO = False if trace: print "<==Domain Wipe Out\n" break if noDWO: new_solns = FC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: Variable.restoreValues(nxtvar, val) break # don't bother with other values of nxtvar # as we found a soln. Variable.restoreValues(nxtvar, val) nxtvar.unAssign() unAssignedVars.insert(nxtvar) return solns
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging if unAssignedVars.empty(): soln = [] for var in csp.variables(): soln.append((var, var.getValue())) if not allSolutions: Variable.restoreValues(var, var.getValue()) return [soln] var = unAssignedVars.extract() #select next variable to assign bt_search.nodesExplored += 1 solns = [] for val in var.curDomain(): #current domain! var.setValue(val) noDWO = True if GacEnforce(csp.constraintsOf(var), csp, var, val) == "DWO": #only var's domain changed-constraints with var have to be checked noDWO = False if noDWO: solns.extend(GAC(unAssignedVars, csp, allSolutions, trace)) if len(solns) > 0 and not allSolutions: break #don't bother with other values of var #as we found a soln. Variable.restoreValues( var, val) #restore values pruned by var = val assignment var.setValue(None) #set var to be unassigned and return to list unAssignedVars.insert(var) return solns
def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 2 goes in this function body. #you must not change the function parameters. #Implementing handling of the trace parameter is optional #but it can be useful for debugging solutions = [] if unAssignedVars.empty(): solution = [(var,var.getValue()) for var in csp.variables()] solutions.append(solution) return solutions var = unAssignedVars.extract() for val in var.curDomain(): var.setValue(val) noDWO = True for constraint in csp.constraintsOf(var): if constraint.numUnassigned()==1: if FCCheck(constraint,var,val)=="DWO": noDWO = False break if noDWO: new = FC(unAssignedVars,csp,allSolutions,trace) if new: solutions.extend(new) if not(len(solutions)==0 or allSolutions): Variable.restoreValues(var,val) break Variable.restoreValues(var,val) var.unAssign() unAssignedVars.insert(var) return solutions util.raiseNotDefined()
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging solutions = [] if unAssignedVars.empty(): if trace: for var in csp.variables(): print var.name(), " = ", var.getValue() solution = [(var,var.getValue()) for var in csp.variables()] solutions.append(solution) return solutions var = unAssignedVars.extract() for val in var.curDomain(): var.setValue(val) noDWO = True if GacEnforce(csp.constraintsOf(var),csp,var,val)=="DWO": noDWO = False if noDWO: new = GAC(unAssignedVars,csp,allSolutions,trace) if new: solutions.extend(new) if not(len(solutions)==0 or allSolutions): Variable.restoreValues(var,val) break Variable.restoreValues(var,val) var.unAssign() unAssignedVars.insert(var) return solutions
def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 2 goes in this function body. #you must not change the function parameters. #Implementing handling of the trace parameter is optional #but it can be useful for debugging if unAssignedVars.empty(): return [[(v, v.getValue()) for v in csp.variables()]] sol_a = [] v = unAssignedVars.extract() bt_search.nodesExplored += 1 for val in v.curDomain(): v.setValue(val) DWO = False for c in csp.constraintsOf(v): if c.numUnassigned() == 1: if FCCheck(c, v, val) == 'DWO': DWO = True break if not DWO: sol_a += FC(unAssignedVars, csp, allSolutions, trace) if not allSolutions and len(sol_a): Variable.restoreValues(v, val) break Variable.restoreValues(v, val) v.unAssign() unAssignedVars.insert(v) return sol_a
def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 2 goes in this function body. #you must not change the function parameters. #Implementing handling of the trace parameter is optional #but it can be useful for debugging if unAssignedVars.empty(): if trace: print("{} Solution Found".format(csp.name())) soln = [] for v in csp.variables(): soln.append((v, v.getValue())) return [soln] #each call returns a list of solutions found bt_search.nodesExplored += 1 solns = [] #so far we have no solutions recursive calls "Choos a value from the unassigned ones" nxtvar = unAssignedVars.extract() if trace: print("==>Trying {}".format(nxtvar.name())) "Assign every value to the next variable from its domain -- Note that curDomain is used instead of domain because cur is pruned" for val in nxtvar.curDomain(): if trace: print("==> {} = {}".format(nxtvar.name(), val)) nxtvar.setValue(val) "For every constraint that the next variable has to satisfy -- " DWO = False for cnstr in csp.constraintsOf(nxtvar): "If the other variable(s) involved in the constraint has only 1 choice left -- " "If that choice will be pruned by this value of nxtvar, it will become DWO" if cnstr.numUnassigned() == 1: if FCCheck(cnstr, nxtvar, val) == "DWO": DWO = True if trace: print("<==domain wiped out\n") break if DWO == False: new_solns = FC(unAssignedVars, csp, allSolutions, trace) if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: Variable.restoreValues(nxtvar, val) break #don't bother with other values of nxtvar #as we found a soln. "Restore all the values that have been pruned away" Variable.restoreValues(nxtvar, val) nxtvar.unAssign() unAssignedVars.insert(nxtvar) return solns
def FC(unAssignedVars, csp, allSolutions, trace): '''Forward checking search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 2 goes in this function body. #you must not change the function parameters. #Implementing handling of the trace parameter is optional #but it can be useful for debugging # unAssignedVars --> UnassignedVars # csp --> CSP # allSolutions --> bool # trace --> bool if unAssignedVars.empty(): # no more unassigned variables if trace: print("{} Solution Found".format(csp.name())) solution = [] for var in csp.variables(): if trace: print(var.name(), ",", var.getValue()) solution.append((var, var.getValue())) # return one solution return [solution] all_solutions = [] var = unAssignedVars.extract() bt_search.nodesExplored += 1 if trace: print(" Trying {}".format(var.name())) for val in var.curDomain(): if trace: print(" {} = {}".format(var.name(), val)) var.setValue(val) noDWO = True for constraint in csp.constraintsOf(var): if constraint.numUnassigned() == 1: if FCCheck(constraint, var, val) == "DWO": noDWO = False if trace: print(" falsified constraint\n") break if noDWO: currrentSol = FC(unAssignedVars, csp, allSolutions, trace) all_solutions.extend(currrentSol) # if allSolutions is false and we at least find one solution, then stop searching if (not allSolutions) and len(all_solutions) >= 1: # restore values when a solution is returned Variable.restoreValues(var, val) break Variable.restoreValues(var, val) var.unAssign() unAssignedVars.insert(var) return all_solutions
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging # if run out of unAssignedVars, get the value into solutions if unAssignedVars.empty(): if trace: print("{} Solution Found".format(csp.name())) soln = [] for v in csp.variables(): soln.append((v, v.getValue())) return [soln] #each call returns a list of solutions found bt_search.nodesExplored += 1 solns = [] #so far we have no solutions recursive calls nxtvar = unAssignedVars.extract() if trace: print("==>Trying {}".format(nxtvar.name())) # check through the domain fromthe newly extracted one for val in nxtvar.curDomain(): if trace: print("==> {} = {}".format(nxtvar.name(), val)) nxtvar.setValue(val) # check if stisfy all constraints # this is where FC start to differenciate themselves from the others. DWOoccured = False if GacEnforce(csp.constraintsOf(nxtvar), csp, nxtvar, val) == "DWO": DWOoccured = True # for cnstr in csp.constraintsOf(nxtvar): # # print(cnstr.numUnassignedVars) # if cnstr.numUnassigned() == 1: # if FCCheck(cnstr, nxtvar, val) == "DWO": # DWOoccured = True # if trace: print("<==falsified constraint\n") # break # # if satisfy all constraints if (not DWOoccured): new_solns = GAC(unAssignedVars, csp, allSolutions, trace) # if there are new solutions, extend them if new_solns: solns.extend(new_solns) if len(solns) > 0 and not allSolutions: Variable.restoreValues(nxtvar, val) break #don't bother with other values of nxtvar #as we found a soln. Variable.restoreValues(nxtvar, val) nxtvar.unAssign() unAssignedVars.insert(nxtvar) return solns
def GAC(unAssignedVars, csp, allSolutions, trace): '''GAC search. unAssignedVars is the current set of unassigned variables. csp is the csp problem, allSolutions is True if you want all solutionsl trace if you want some tracing of variable assignments tried and constraints failed. RETURNS LIST OF ALL SOLUTIONS FOUND. Finding allSolutions is handled just as it was in BT. Except that when we are not looking for all solutions and we stop early because one of the recursive calls found a solution we must make sure that we restore all pruned values before returning. ''' #your implementation for Question 3 goes in this function body #You must not change the function parameters. #implementing support for "trace" is optional, but it might #help you in debugging if unAssignedVars.empty(): if trace: debugString = "{} Solution Found".format(csp.name()) print(debugString) soln = [] for var in csp.variables(): soln.append((var, var.getValue())) return [soln] solutions = [] bt_search.nodesExplored += 1 nextVariable = unAssignedVars.extract() if trace: debugString = "==>Trying {}".format(nextVariable.name()) print(debugString) for val in nextVariable.curDomain(): if trace: debugString = "==> {} = {}".format(nextVariable.name(), val) print(debugString) nextVariable.setValue(val) DWO = False DWOCondition = GacEnforce(csp.constraintsOf(nextVariable), csp, nextVariable, val) == 'DWO' if DWOCondition: DWO = True if trace: debugString = "<== DWO\n" print(debugString) if not DWO: new_soln = GAC(unAssignedVars, csp, allSolutions, trace) if new_soln: solutions.extend(new_soln) if not allSolutions and len(solutions) > 0: Variable.restoreValues(nextVariable, val) break Variable.restoreValues(nextVariable, val) nextVariable.unAssign() unAssignedVars.insert(nextVariable) #print(len(solutions)) return solutions