private static List <OverFloorType> MAC3HeadTailChecker(Variable headVar, Variable tailVar, CSP problem) { var ret = new List <OverFloorType>(); //Loop remaining domain values var remainingDomains = tailVar.remDomain.ToList(); foreach (var remDomTail in remainingDomains) { int validTailValue = 0; problem.AssignValue(tailVar, remDomTail, false); var remDomainHead = headVar.remDomain.ToList(); foreach (var remDomHead in remDomainHead) { var alreadyAssigned = problem.IsVariableAssigned(headVar); if (!alreadyAssigned) { problem.AssignValue(headVar, remDomHead, false); } bool valid = problem.ValidateConstraints(); if (!valid) { validTailValue++; break; } if (!alreadyAssigned) { problem.RemoveValue(headVar); } } if (validTailValue == remDomainHead.Count()) { ret.Add(remDomTail); } problem.RemoveValue(tailVar); } return(ret); }
private static List<OverFloorType> MAC3HeadTailChecker(Variable headVar, Variable tailVar, CSP problem) { var ret = new List<OverFloorType>(); //Loop remaining domain values var remainingDomains = tailVar.remDomain.ToList(); foreach (var remDomTail in remainingDomains) { int validTailValue = 0; problem.AssignValue(tailVar, remDomTail, false); var remDomainHead = headVar.remDomain.ToList(); foreach (var remDomHead in remDomainHead) { var alreadyAssigned = problem.IsVariableAssigned(headVar); if(!alreadyAssigned)problem.AssignValue(headVar, remDomHead, false); bool valid = problem.ValidateConstraints(); if (!valid) { validTailValue++; break; } if (!alreadyAssigned) problem.RemoveValue(headVar); } if (validTailValue == remDomainHead.Count()) ret.Add(remDomTail); problem.RemoveValue(tailVar); } return ret; }
/// <summary> /// Maintenance Arc Consistency, this algorithm will check how many domain prunes are done when a assignemnt is executed /// </summary> /// <param name="assign">Assignment to be evaluated and updated</param> /// <param name="neighbours">List of neighbours to start with (difference between AC3 and MAC3)</param> /// <returns></returns> public static bool MAC3(ref Assignment assign,CSP problem) { var position = assign.variable.pos; var variableInLocalProblem = problem.vars.First(v => v.pos == position); //Add the assignment to the problem problem.AssignValue(variableInLocalProblem, assign.value,false); List<Variable> queueToPrune = new List<Variable>(); queueToPrune.Add(variableInLocalProblem); while (queueToPrune.Any()) { //Get the first variable var headVariable = queueToPrune.First(); queueToPrune.Remove(headVariable); //Get the neighbours of the variable List<Variable> neighbours = problem.GetNeighbours(headVariable).Where(n => !problem.IsVariableAssigned(n)).ToList(); //Loop over neighbours foreach (var neigh in neighbours) { //Get the list of values to delete for conflict List<OverFloorType> valuesToPrune = new List<OverFloorType>(); //Check if value is compatible with remaining values in head foreach (var valPruned in MAC3HeadTailChecker(headVariable, neigh, problem)) { if (!valuesToPrune.Any(v => v == valPruned)) valuesToPrune.Add(valPruned); } //Remove the value from the variable domain in temporal CSP and add to the domain prune foreach (var prunedVal in valuesToPrune) { //Remove domain from variable in problem problem.RemoveDomainElementFromVariable(neigh, prunedVal); //remove domain from variable in current variable neigh.removeDomainElement(prunedVal); if (!neigh.remDomain.Any()) return false; //Add prune action to assignment assign.AddDomainPrune(neigh.pos, prunedVal); } if (valuesToPrune.Any()) { queueToPrune.Add(neigh); } } } return true; }
/// <summary> /// Maintenance Arc Consistency, this algorithm will check how many domain prunes are done when a assignemnt is executed /// </summary> /// <param name="assign">Assignment to be evaluated and updated</param> /// <param name="neighbours">List of neighbours to start with (difference between AC3 and MAC3)</param> /// <returns></returns> public static bool MAC3(ref Assignment assign, CSP problem) { var position = assign.variable.pos; var variableInLocalProblem = problem.vars.First(v => v.pos == position); //Add the assignment to the problem problem.AssignValue(variableInLocalProblem, assign.value, false); List <Variable> queueToPrune = new List <Variable>(); queueToPrune.Add(variableInLocalProblem); while (queueToPrune.Any()) { //Get the first variable var headVariable = queueToPrune.First(); queueToPrune.Remove(headVariable); //Get the neighbours of the variable List <Variable> neighbours = problem.GetNeighbours(headVariable).Where(n => !problem.IsVariableAssigned(n)).ToList(); //Loop over neighbours foreach (var neigh in neighbours) { //Get the list of values to delete for conflict List <OverFloorType> valuesToPrune = new List <OverFloorType>(); //Check if value is compatible with remaining values in head foreach (var valPruned in MAC3HeadTailChecker(headVariable, neigh, problem)) { if (!valuesToPrune.Any(v => v == valPruned)) { valuesToPrune.Add(valPruned); } } //Remove the value from the variable domain in temporal CSP and add to the domain prune foreach (var prunedVal in valuesToPrune) { //Remove domain from variable in problem problem.RemoveDomainElementFromVariable(neigh, prunedVal); //remove domain from variable in current variable neigh.removeDomainElement(prunedVal); if (!neigh.remDomain.Any()) { return(false); } //Add prune action to assignment assign.AddDomainPrune(neigh.pos, prunedVal); } if (valuesToPrune.Any()) { queueToPrune.Add(neigh); } } } return(true); }