public void Solve([NotNull] Action checkAbort) { // Remove all constraints subsumed by others MarkSubsumingConstraints(_allVariables.Values); IEnumerable <NumericVariable> variablesWhoseDependentConstraintsShouldBePropagated = _allVariables.Values.ToArray(); const int MAXLOOP = 10000; for (int i = 0; i < MAXLOOP; i++) { var modifiedVariables = new HashSet <NumericVariable>(); foreach (var v in variablesWhoseDependentConstraintsShouldBePropagated) { checkAbort(); foreach (var c in v.ActiveConstraints.ToArray()) { IEnumerable <NumericVariable> changed = c.Propagate(this).ToArray(); foreach (var ch in changed) { ch.MarkAllConstraintsDirty(); } modifiedVariables.UnionWith(changed); _now++; } } if (!modifiedVariables.Any()) { IEnumerable <NumericVariable> changedVariables = CheckState(_allVariables.Values); modifiedVariables = new HashSet <NumericVariable>((changedVariables ?? Enumerable.Empty <NumericVariable>()).Where(v => v != null)); if (!modifiedVariables.Any()) { break; } else { foreach (var ch in modifiedVariables) { ch.MarkAllConstraintsDirty(); } AbstractConstraint findADirtyConstraint = modifiedVariables.SelectMany(v => v.ActiveConstraints).FirstOrDefault(c => c.IsDirty); if (findADirtyConstraint == null) { throw new SolverException("No constraint was touched by the variables modified by CheckState"); } } } variablesWhoseDependentConstraintsShouldBePropagated = modifiedVariables; } _solved = true; Log.WriteInfo("Solved constraints for " + _allVariables.Count + " variables."); }
public override bool Subsumes(AbstractConstraint other) { if (base.Subsumes(other)) { return(true); } else { var otherRangeConstraint = other as RangeConstraint; return(otherRangeConstraint != null && otherRangeConstraint.Range.IsSubsetOf(Range)); } }
public void MarkAsSubsumedByThatAndOthers(AbstractConstraint c) { if (_subsumers == null) { _subsumers = new List <AbstractConstraint> { c }; } else { _subsumers.Add(c); } }
public void MarkSubsumingConstraints(IEnumerable <NumericVariable> variables = null) { foreach (var v in variables ?? _allVariables.Values) { foreach (var c in v.ActiveConstraints.ToArray()) { // ActiveConstraints is taken anew in each iteration. Otherwise, two equal constraints // that were active at the beginning will see feel subsumed by the other and hence both become inactive. AbstractConstraint subsumer = v.ActiveConstraints.FirstOrDefault(candidate => candidate != c && candidate.Subsumes(c)); if (subsumer != null) { c.MarkAsSubsumedByThatAndOthers(subsumer); } } } }
protected bool BaseEquals(AbstractConstraint other) { return(true); }
public virtual bool Subsumes(AbstractConstraint other) { return(Equals(other)); }
internal void AddAsDependentConstraintForUseInConstraintConstructorOnly(AbstractConstraint constraint) { _dependentConstraints.Add(constraint); }