protected bool ArcReduce(BinaryConstraint <T> arc) { var x = arc.VariableA; var y = arc.VariableB; bool change = false; for (var i = 0; i < x.Domain.Count; i++) { var valueX = x.Domain[i]; x.Current = valueX; bool satisfactionFound = false; foreach (var valueY in y.Domain) { y.Current = valueY; if (arc.Check()) { satisfactionFound = true; break; } } if (!satisfactionFound) { Console.WriteLine("Reduced xd"); x.Domain.Remove(valueX); change = true; } y.Current = default; } x.Current = default; return(change); }
// Pseudokod xDxD // https://en.wikipedia.org/wiki/AC-3_algorithm protected bool Ac3() { //List<(IVariable<T>, IVariable<T>)> workList = new List<(IVariable<T>, IVariable<T>)>(); List <BinaryConstraint <T> > workList = new List <BinaryConstraint <T> >(); foreach (var constraint in Constraints) { var cast = constraint as BinaryConstraint <T>; if (cast != null) { workList.Add(cast); BinaryConstraint <T> reverseConstraint = new BinaryConstraint <T>() { Check = cast.Check, VariableA = cast.VariableB, VariableB = cast.VariableA }; workList.Add(reverseConstraint); } } while (workList.Count > 0) { var arc = workList[0]; workList.RemoveAt(0); if (ArcReduce(arc)) { if (arc.VariableA.Domain.Count == 0) { return(false); } else { Constraints.ForEach(c => { var cast = c as BinaryConstraint <T>; IVariable <T> other = null; if (cast.VariableA == arc.VariableA) { other = cast.VariableB; } if (cast.VariableB == arc.VariableA) { other = cast.VariableA; } if (other != null && other != arc.VariableB) { workList.Add(cast); BinaryConstraint <T> reverseConstraint = new BinaryConstraint <T>() { Check = cast.Check, VariableA = cast.VariableB, VariableB = cast.VariableA }; workList.Add(reverseConstraint); } }); } } } return(true); }