/// <summary> /// Template method, which can be configured by overriding the three /// primitive operations below. /// </summary> /// <param name="csp"></param> /// <param name="assignment"></param> /// <returns></returns> private Assignment RecursiveBackTrackingSearch(CSProblem csp, Assignment assignment) { Assignment result = null; if (assignment.IsComplete(csp.Variables)) { result = assignment; } else { Variable var = this.SelectUnassignedVariable(assignment, csp); foreach (object value in this.OrderDomainValues(var, assignment, csp)) { assignment.SetAssignment(var, value); this.FireStateChanged(assignment, csp); if (assignment.IsConsistent(csp.GetConstraints(var))) { DomainRestoreInfo info = this.Inference(var, assignment, csp); if (!info.IsEmpty()) { this.FireStateChanged(csp); } if (!info.IsEmptyDomainFound()) { result = this.RecursiveBackTrackingSearch(csp, assignment); if (result != null) { break; } } csp.RestoreDomains(info); } assignment.RemoveAssignment(var); } } return(result); }