public Assignment(Variable var,OverFloorType val) { this.variable = var; this.value = val; this.nConflicts = 0; domainPrune = new Dictionary<Vector2, List<OverFloorType>> (); }
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> /// Removes an assignment and recover pruned variables /// </summary> /// <param name="var">Removes the assignment for this variable and adds pruned variables.</param> public void RemoveValue(Variable var) { Vector2 varPos = var.pos; Assignment assign = assignments.First (a => a.variable.pos == varPos); foreach (var varPrune in assign.domainPrune.Keys) { List<OverFloorType> valuesPruned = assign.domainPrune[varPrune]; Variable varToUnprune = vars.First(v=>v.pos == varPrune); foreach(var vPrune in valuesPruned) { varToUnprune.addDomainElement(vPrune); } } assignments.Remove (assign); }
/// <summary> /// Removes a available value from a variable /// </summary> /// <param name="var"></param> /// <param name="value"></param> public void RemoveDomainElementFromVariable(Variable var, OverFloorType value) { this.vars.First(v=>v.pos == var.pos).removeDomainElement(value); }
/// <summary> /// Return the value that will restrict less the assignment of future variables /// </summary> /// <param name="var">Variable to get possible assignments from</param> /// <returns>List with all possible assignments for the variable order by least restraining value</returns> public List<Assignment> OrderAssignmentsByLeastRestrictingValues(Variable var) { List<Assignment> remAssignments = new List<Assignment>(); foreach (var remValue in var.remDomain) { remAssignments.Add(new Assignment(var, remValue)); } remAssignments.ForEach(a => a.nConflicts = ConflictAssignment(a)); return remAssignments.Where(a => a.validAssignment).OrderByDescending(a => a.nConflicts).ToList(); }
/// <summary> /// Return if a variable has some assignment /// </summary> /// <param name="var"></param> /// <returns></returns> public bool IsVariableAssigned(Variable var) { return assignments.Any(a => a.variable.pos == var.pos); }
public OverFloorType GetVariableValue(Variable var) { return assignments.FirstOrDefault(a => a.variable.pos == var.pos).value; }
/// <summary> /// Return the list of neighbours of a variable /// </summary> /// <param name="var">Variable to get neighbours from</param> /// <returns>List of neighbours</returns> public List<Variable> GetNeighbours(Variable var) { return neighbours[var.pos]; }
/// <summary> /// Creates the assignment and prunes other variables /// </summary> /// <param name="var">Variable.</param> /// <param name="val">Value.</param> /// <returns>True if the assignment is legal</returns> public bool AssignValue(Variable var,OverFloorType val, bool inference = true) { //Create a new assignment Assignment assign = new Assignment (var, val); //Get current domain before MAC3 to store posible values to prune List<OverFloorType> domainBeformMAC = var.remDomain.ToList(); //Get variable prunes var validAssignment = true; if (inference) validAssignment = Search.MAC3(ref assign, new CSP(this) ); if (validAssignment) { //Prune all values that are not a variable assign.domainPrune.Add(var.pos, domainBeformMAC.Where(r => r != val).ToList()); //Go over variable domain prunes to remove from variables foreach (var varPrune in assign.domainPrune.Keys) { List<OverFloorType> valuesToPrune = assign.domainPrune[varPrune]; Variable varToPrune = vars.First(v => v.pos == varPrune); foreach (var vPrune in valuesToPrune) { varToPrune.removeDomainElement(vPrune); } } //Save the assignment assignments.Add(assign); } return validAssignment; }