def solve(self): """ Searches for a solution using a combination of arcConsistency and backtracking. The Algorithm will run arcConsistency, find the smallest remaining domain (that's greater than 1), and systematically assign a value to the variable and recurse onwards. Returns True if a solution is found, False otherwise. """ self.arcConsistencyHelper() if self.isSolved(): for coordinate in self.board.getCoordinates(): coordinate.setValue(coordinate.getDomain()[0]) return True elif self.isDeadEnd(): return False else: print("selecting a variable to assign") savedDomains = self.backupDomains(self.getListOfDomains()) smallest = self.indexOfSmallestDomain(savedDomains) for x in savedDomains[smallest]: self.addRelatedToQueue(self.coordinates[smallest]) self.coordinates[smallest].setDomain([x,]) if (self.solve()): return True self.restoreDomains(self.backupDomains(savedDomains)) else: return False
def solve(self): """ Searches for a solution using a combination of arcConsistency and backtracking. The Algorithm will run arcConsistency, find the smallest remaining domain (that's greater than 1), and systematically assign a value to the variable and recurse onwards. Returns True is a solution is found, False otherwise. """ self.arcConsistencyHelper() if self.isSolved(): for coordinate in self.board.getCoordinates(): coordinate.setValue(coordinate.getDomain()[0]) return True elif self.isDeadEnd(): return False else: print("selecting a variable to assign") savedDomains = self.backupDomains(self.getListOfDomains()) smallest = self.indexOfSmallestDomain(savedDomains) for x in savedDomains[smallest]: self.addRelatedToQueue(self.coordinates[smallest]) self.coordinates[smallest].setDomain([ x, ]) if (self.solve()): return True self.restoreDomains(self.backupDomains(savedDomains)) else: return False
def solveWithLCV(self): """ Works the same as solveWithBackTracking, but assigns the variable in an order such that you assign the least constraining value first. That is, assign the value which would cause the least domain pruning after running arcConsistency. """ self.arcConsistencyHelper() if self.isSolved(): for coordinate in self.board.getCoordinates(): coordinate.setValue(coordinate.getDomain()[0]) return True elif self.isDeadEnd(): return False else: savedDomains = self.backupDomains(self.getListOfDomains()) smallest = self.indexOfSmallestDomain(savedDomains) resultingDomainsList = [] for x in savedDomains[smallest]: self.addRelatedToQueue(self.coordinates[smallest]) self.coordinates[smallest].setDomain([ x, ]) self.arcConsistencyHelper() resultingDomainsList.append((x, self.getListOfDomains())) self.restoreDomains(self.backupDomains(savedDomains)) for assignment, resultingDomains in resultingDomainsList: for domain in resultingDomains: if (len(domain) == 0): resultingDomainsList.remove( (assignment, resultingDomains)) #This assignment cannot work break #compute resulting total domain sizes mappedTotalDomainSizes = list( map(self.totalSizeOfDomains, [domains for assignment, domains in resultingDomainsList])) #pick the assigned variables, ordered by resulting domain size for i in range(len(resultingDomainsList)): currentAssignmentIndex = mappedTotalDomainSizes.index( max(mappedTotalDomainSizes)) currentAssignment, currentDomains = resultingDomainsList[ currentAssignmentIndex] self.restoreDomains(currentDomains) self.coordinates[smallest].setDomain([ currentAssignment, ]) if (self.solveWithLCV()): return True else: return False
def solveWithLCV(self): """ Works the same as solveWithBackTracking, but assigns the variable in an order such that you assign the least constraining value first. That is, assign the value which would cause the least domain pruning after running arcConsistency. """ self.arcConsistencyHelper() if self.isSolved(): for coordinate in self.board.getCoordinates(): coordinate.setValue(coordinate.getDomain()[0]) return True elif self.isDeadEnd(): return False else: savedDomains = self.backupDomains(self.getListOfDomains()) smallest = self.indexOfSmallestDomain(savedDomains) resultingDomainsList = [] for x in savedDomains[smallest]: self.addRelatedToQueue(self.coordinates[smallest]) self.coordinates[smallest].setDomain([x,]) self.arcConsistencyHelper() resultingDomainsList.append((x, self.getListOfDomains())) self.restoreDomains(self.backupDomains(savedDomains)) for assignment, resultingDomains in resultingDomainsList: for domain in resultingDomains: if (len(domain) == 0): resultingDomainsList.remove((assignment, resultingDomains)) #This assignment cannot work break #compute resulting total domain sizes mappedTotalDomainSizes = list(map(self.totalSizeOfDomains, [domains for assignment, domains in resultingDomainsList])) #pick the assigned variables, ordered by resulting domain size for i in range(len(resultingDomainsList)): currentAssignmentIndex = mappedTotalDomainSizes.index(max(mappedTotalDomainSizes)) currentAssignment, currentDomains = resultingDomainsList[currentAssignmentIndex] self.restoreDomains(currentDomains) self.coordinates[smallest].setDomain([currentAssignment,]) if (self.solveWithLCV()): return True else: return False