static void Main(string[] args) { Network net = new Network(); IntVariable[] A = new IntVariable[6]; for (int j=0; j< 6; j++) { IntDomain d = new IntDomain(1, 9); A[j] = new IntVariable(net); A[j].Domain = d; Trail trail = new Trail(); } ((A[4].Multiply(10).Add(A[5])).Multiply(A[0])).Add( ((A[1].Multiply(10).Add(A[2])).Multiply(A[3]))).Equals( (A[1].Multiply(10).Add(A[2])).Multiply(A[4].Multiply(10).Add(A[5]))); new NotEquals(net, A); Solver solver = new DefaultSolver(net); int i = 0; for (solver.Start(); solver.WaitNext(); solver.Resume()) { Solution solution = solver.Solution; Console.Out.WriteLine(); Console.Out.WriteLine(solution.GetIntValue(A[0]) + " " + solution.GetIntValue(A[3])); Console.Out.WriteLine("-- + -- = 1"); Console.Out.WriteLine(solution.GetIntValue(A[1])+""+solution.GetIntValue(A[2])+" "+ solution.GetIntValue(A[4]) + solution.GetIntValue(A[5])); Console.Out.WriteLine("========="); i++; } Console.Out.WriteLine("There are {0} solutions",i); solver.Stop(); Console.In.ReadLine(); //------------------------------------------------------------------------------------------ }
private bool SatisfySequential(Trail trail) { if (_order == null) return true; for (int k = 0; k < _order.Length - 1; k++) { int i = _order[k]; int j = _order[k + 1]; var d0 = (IntDomain) _v[i].Domain; var d1 = (IntDomain) _v[j].Domain; int diffMin = d1.Maximum() - _l[i] + 1; int diffMax = d0.Minimum() + _l[i] - 1; d0 = d0.Delete(diffMin, IntDomain.MaxValue); if (d0.Empty) return false; d1 = d1.Delete(IntDomain.MinValue, diffMax); if (d1.Empty) return false; if (trail != null) { _v[i].UpdateDomain(d0, trail); _v[j].UpdateDomain(d1, trail); } } return true; }
//public int getMostSoftSatisfiedDomain() //{ // Domain d = v[0].Domain; // if (CType == ConstraintTypes.Soft) // { // for (int i = 1; i < v.Length; i++) // { // d = d.Cap(v[i].Domain); // if (d.EmptyDomain) // return -1; // } // } // return ((IntDomain) d).Min(); //} protected internal override bool Satisfy(Trail trail) { Domain d = v[0].Domain; for (int i = 1; i < v.Length; i++) { d = d.Cap(v[i].Domain); if (d.Empty) { return(false); } } if (trail != null) { for (int i = 0; i < v.Length; i++) { v[i].UpdateDomain(d, trail); } } return(true); }
protected internal override bool Satisfy(Trail trail) { switch (arith) { case Add: return(SatisfyADD(v[0], v[1], v[2], trail)); case Subtract: return(SatisfyADD(v[1], v[0], v[2], trail)); case MULTIPLY: return(SatisfyMULTIPLY(v[0], v[1], v[2], trail)); case MAX: return(SatisfyMAX(v[0], v[1], v[2], trail)); case MIN: return(SatisfyMIN(v[0], v[1], v[2], trail)); } return(false); }
protected internal override bool Satisfy(Trail trail) { for (int i = 0; i < _v.Length - 1; i++) { int j = i + 1; var d0 = (IntDomain) _v[i].Domain; var d1 = (IntDomain) _v[j].Domain; int diffMin = d1.Maximum() - _l[i] + 1; int diffMax = d0.Minimum() + _l[i] - 1; d0 = d0.Delete(diffMin, IntDomain.MaxValue); if (d0.Empty) return false; d1 = d1.Delete(IntDomain.MinValue, diffMax); if (d1.Empty) return false; if (trail != null) { _v[i].UpdateDomain(d0, trail); _v[j].UpdateDomain(d1, trail); } } return true; }
protected internal override bool Satisfy(Trail trail) { for (int i = 0; i < _v.Length; i++) { Domain d = _v[i].Domain; if (d.Size() != 1) continue; Object elem = d.Element(); for (int j = 0; j < _v.Length; j++) { if (i == j) continue; Domain d1 = _v[j].Domain.Delete(elem); if (d1.Empty) return false; if (trail != null) { _v[j].UpdateDomain(d1, trail); } } } return true; }
private bool SatisfyMIN(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; var d2 = (IntDomain)v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = Min(v1, v2) int value = Math.Min(d1.Value(), d2.Value()); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d0.Size() == 1) { int value = d0.Value(); if (!d1.Contains(value) && !d2.Contains(value)) { return(false); } // ??? if (d1.Minimum() < value) { d1.CapInterval(value, IntDomain.MaxValue); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } } if (d2.Minimum() < value) { d2.CapInterval(value, IntDomain.MaxValue); if (d2.Empty) { return(false); } if (trail != null) { v2.UpdateDomain(d2, trail); } } return(true); } // v0 = Min(v1, v2) int min = Math.Min(d1.Minimum(), d2.Minimum()); int max = Math.Min(d1.Maximum(), d2.Maximum()); d0 = d0.CapInterval(min, max); if (d0.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); } // if (d1.Minimum() < d0.Minimum()) { d1 = d1.CapInterval(d0.Minimum(), IntDomain.MaxValue); } if (d2.Minimum() < d0.Minimum()) { d2 = d2.CapInterval(d0.Minimum(), IntDomain.MaxValue); } if (d1.Minimum() > d0.Maximum()) { d0 = (IntDomain)d0.Cap(d2); d2 = d0; } if (d2.Minimum() > d0.Maximum()) { d0 = (IntDomain)d0.Cap(d1); d1 = d0; } if (d0.Empty) { return(false); } if (d1.Empty) { return(false); } if (d2.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); v2.UpdateDomain(d2, trail); } return(true); }
protected override internal bool Satisfy(Trail trail) { int n = v.Length; // limit the domain of v1 to 0..n-1 var d1 = (IntDomain)v1.Domain; d1 = d1.CapInterval(0, n - 1); if (d1.Empty) { return(false); } // get the possible range of v[i] as Min..Max int min = IntDomain.MaxValue; int max = IntDomain.MinValue; for (int i = 0; i < n; i++) { if (d1.Contains(i)) { var d = (IntDomain)v[i].Domain; min = Math.Min(min, d.Minimum()); max = Math.Max(max, d.Maximum()); } } if (min > max) { return(false); } // limit the domain of v0 to Min..Max var d0 = (IntDomain)v0.Domain; d0 = d0.CapInterval(min, max); if (d0.Empty) { return(false); } // Delete impossible indices from v1 for (int i = 0; i < n; i++) { if (d1.Contains(i)) { var d = (IntDomain)v[i].Domain; if (d0.CapInterval(d.Minimum(), d.Maximum()).Empty) { d1 = d1.Delete(i); } } } if (d1.Empty) { return(false); } // propagate v0 to v[v1] when v1 is determined if (d1.Size() == 1) { int i = d1.Value(); var d = (IntDomain)v[i].Domain; d0 = (IntDomain)d.Cap(d0); if (d0.Empty) { return(false); } if (trail != null) { v[i].UpdateDomain(d0, trail); } } if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); } return(true); }
private static bool SatisfyMULTIPLY(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; var d2 = (IntDomain) v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = v1 * v2 int value = ToInt(d1.Value() * (long) d2.Value()); if (!d0.Contains(value)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1 && d2.Size() == 1) { // v1 = v0 / v2 int x = d0.Value(); int y = d2.Value(); if (y == 0) { return x == 0; } if (x % y != 0) { return false; } int value = x / y; if (!d1.Contains(value)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1 && d1.Size() == 1) { // v2 = v0 / v1 int x = d0.Value(); int y = d1.Value(); if (y == 0) { return x == 0; } if (x % y != 0) { return false; } int value = x / y; if (!d2.Contains(value)) return false; if (d2.Size() > 1) if (trail != null) { v2.UpdateDomain(new IntDomain(value), trail); } return true; } d0 = Multiply(d0, d1, d2); if (d0.Empty) return false; d1 = Divide(d1, d0, d2); if (d1.Empty) return false; d2 = Divide(d2, d0, d1); if (d2.Empty) return false; if (trail != null) { if (d0 != v0.Domain) v0.UpdateDomain(d0, trail); if (d1 != v1.Domain) v1.UpdateDomain(d1, trail); if (d2 != v2.Domain) v2.UpdateDomain(d2, trail); } return true; }
private static bool SatisfyAdd(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; var d2 = (IntDomain) v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = v1 + v2 var value = d1.Value() + d2.Value(); if (!d0.Contains(value)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1 && d2.Size() == 1) { // v1 = v0 - v2 var value = d0.Value() - d2.Value(); if (!d1.Contains(value)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1 && d1.Size() == 1) { // v2 = v0 - v1 var value = d0.Value() - d1.Value(); if (!d2.Contains(value)) return false; if (d2.Size() > 1) if (trail != null) { v2.UpdateDomain(new IntDomain(value), trail); } return true; } // v0 = v1 + v2 d0 = d0.CapInterval(d1.Minimum() + d2.Minimum(), d1.Maximum() + d2.Maximum()); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } // v1 = v0 - v2 d1 = d1.CapInterval(d0.Minimum() - d2.Maximum(), d0.Maximum() - d2.Minimum()); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } // v2 = v0 - v1 d2 = d2.CapInterval(d0.Minimum() - d1.Maximum(), d0.Maximum() - d1.Minimum()); if (d2.Empty) return false; if (trail != null) { v2.UpdateDomain(d2, trail); } return true; }
private static bool SatisfySIGN(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; if (d1.Size() == 1) { // v0 = Sign(v1) int sign = 0; if (d1.Value() < 0) { sign = -1; } else if (d1.Value() > 0) { sign = 1; } if (!d0.Contains(sign)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(sign), trail); } } return(true); } if (d0.Size() == 1) { // Sign(v1) = v0 int sign = d0.Value(); if (sign < 0) { if (d1.Maximum() >= 0) { d1 = d1.CapInterval(IntDomain.MinValue, -1); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } } return(true); } if (sign == 0) { if (!d1.Contains(0)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(0), trail); } } return(true); } if (sign > 0) { if (d1.Minimum() <= 0) { d1 = d1.CapInterval(1, IntDomain.MaxValue); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } } return(true); } return(false); } // v0 = Sign(v1) if (!(-1 <= d0.Minimum() && d0.Maximum() <= 1)) { d0 = d0.CapInterval(-1, 1); } if (d1.Minimum() >= 0) { d0 = d0.Delete(-1); } if (!d1.Contains(0)) { d0 = d0.Delete(0); } if (d1.Maximum() <= 0) { d0 = d0.Delete(1); } // Sign(v1) = v0 if (!d0.Contains(-1)) { if (d1.Minimum() < 0) { d1 = d1.CapInterval(0, IntDomain.MaxValue); } } if (!d0.Contains(0)) { d1 = d1.Delete(0); } if (!d0.Contains(1)) { if (d1.Maximum() > 0) { d1 = d1.CapInterval(IntDomain.MinValue, 0); } } if (d0.Empty) { return(false); } if (d1.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); } return(true); }
/// <summary> /// Run method /// </summary> public override void Run() { ClearBest(); trail = new Trail(); Solve(0); trail.Undo(0); Fail(); }
private bool SatisfySerialized(Trail trail) { for (int i = 0; i < _v.Length; i++) { for (int j = 0; j < _v.Length; j++) { if (i == j) continue; var d0 = (IntDomain) _v[i].Domain; var d1 = (IntDomain) _v[j].Domain; int diffMin = d1.Maximum() - _l[i] + 1; int diffMax = d1.Minimum() + _l[j] - 1; if (diffMin <= diffMax) { d0 = d0.Delete(diffMin, diffMax); if (d0.Empty) return false; if (trail != null) { _v[i].UpdateDomain(d0, trail); } } } } return true; }
protected internal override bool Satisfy(Trail trail) { int n = _v.Length; // limit the domain of v1 to 0..n-1 var d1 = (IntDomain) _v1.Domain; d1 = d1.CapInterval(0, n - 1); if (d1.Empty) return false; // get the possible range of v[i] as Min..Max int min = IntDomain.MaxValue; int max = IntDomain.MinValue; for (int i = 0; i < n; i++) { if (d1.Contains(i)) { var d = (IntDomain) _v[i].Domain; min = Math.Min(min, d.Minimum()); max = Math.Max(max, d.Maximum()); } } if (min > max) return false; // limit the domain of v0 to Min..Max var d0 = (IntDomain) _v0.Domain; d0 = d0.CapInterval(min, max); if (d0.Empty) return false; // Delete impossible indices from v1 for (int i = 0; i < n; i++) { if (d1.Contains(i)) { var d = (IntDomain) _v[i].Domain; if (d0.CapInterval(d.Minimum(), d.Maximum()).Empty) { d1 = d1.Delete(i); } } } if (d1.Empty) return false; // propagate v0 to v[v1] when v1 is determined if (d1.Size() == 1) { int i = d1.Value(); var d = (IntDomain) _v[i].Domain; d0 = (IntDomain) d.Cap(d0); if (d0.Empty) return false; if (trail != null) { _v[i].UpdateDomain(d0, trail); } } if (trail != null) { _v0.UpdateDomain(d0, trail); _v1.UpdateDomain(d1, trail); } return true; }
private static bool SatisfySIGN(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; if (d1.Size() == 1) { // v0 = Sign(v1) int sign = 0; if (d1.Value() < 0) { sign = - 1; } else if (d1.Value() > 0) { sign = 1; } if (!d0.Contains(sign)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(sign), trail); } return true; } if (d0.Size() == 1) { // Sign(v1) = v0 int sign = d0.Value(); if (sign < 0) { if (d1.Maximum() >= 0) { d1 = d1.CapInterval(IntDomain.MinValue, - 1); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } } return true; } if (sign == 0) { if (!d1.Contains(0)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(0), trail); } return true; } if (sign > 0) { if (d1.Minimum() <= 0) { d1 = d1.CapInterval(1, IntDomain.MaxValue); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } } return true; } return false; } // v0 = Sign(v1) if (!(- 1 <= d0.Minimum() && d0.Maximum() <= 1)) { d0 = d0.CapInterval(- 1, 1); } if (d1.Minimum() >= 0) d0 = d0.Delete(- 1); if (!d1.Contains(0)) d0 = d0.Delete(0); if (d1.Maximum() <= 0) d0 = d0.Delete(1); // Sign(v1) = v0 if (!d0.Contains(- 1)) { if (d1.Minimum() < 0) d1 = d1.CapInterval(0, IntDomain.MaxValue); } if (!d0.Contains(0)) { d1 = d1.Delete(0); } if (!d0.Contains(1)) { if (d1.Maximum() > 0) d1 = d1.CapInterval(IntDomain.MinValue, 0); } if (d0.Empty) return false; if (d1.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); } return true; }
private static bool SatisfyNEGATE(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; if (d1.Size() == 1) { // v0 = -v1 int value = - d1.Value(); if (!d0.Contains(value)) return false; if (d0.Size() > 1) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1) { // v1 = -v0 int value = - d0.Value(); if (!d1.Contains(value)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } // v0 = -v1 d0 = d0.CapInterval(- d1.Maximum(), - d1.Minimum()); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } // v1 = -v0 d1 = d1.CapInterval(- d0.Maximum(), - d0.Minimum()); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } return true; }
private static bool SatisfyABS(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; if (d1.Size() == 1) { // v0 = Abs(v1) int value = Math.Abs(d1.Value()); if (!d0.Contains(value)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1) { // Abs(v1) = v0 int value = d0.Value(); if (value < 0) { return false; } if (value == 0) { if (!d1.Contains(value)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } if (d1.Contains(value) && d1.Contains(- value)) { if (d1.Size() > 2) { value = Math.Abs(value); d1 = new IntDomain(- value, value); d1 = d1.Delete(- value + 1, value - 1); if (trail != null) { v1.UpdateDomain(d1, trail); } } return true; } if (d1.Contains(value)) { if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } if (d1.Contains(- value)) { if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(-value), trail); } return true; } return false; } int min; int max; // v0 = Abs(v1) if (d1.Minimum() >= 0) { min = d1.Minimum(); max = d1.Maximum(); } else if (d1.Maximum() <= 0) { min = - d1.Maximum(); max = - d1.Minimum(); } else { min = 0; max = Math.Max(- d1.Minimum(), d1.Maximum()); } d0 = d0.CapInterval(min, max); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } // Abs(v1) = v0 min = d0.Minimum(); max = d0.Maximum(); d1 = d1.CapInterval(- max, max); if (d1.Empty) return false; if (min > 0) d1 = d1.Delete(- min + 1, min - 1); if (trail != null) { v1.UpdateDomain(d1, trail); } return true; }
protected internal override bool Satisfy(Trail trail) { switch (_arith) { case Negate: return SatisfyNEGATE(_v[0], _v[1], trail); case Abs: return SatisfyABS(_v[0], _v[1], trail); case Sign: return SatisfySIGN(_v[0], _v[1], trail); } return false; }
//public int getMostSoftSatisfiedDomain() //{ // Domain d = v[0].Domain; // if (CType == ConstraintTypes.Soft) // { // for (int i = 1; i < v.Length; i++) // { // d = d.Cap(v[i].Domain); // if (d.EmptyDomain) // return -1; // } // } // return ((IntDomain) d).Min(); //} protected internal override bool Satisfy(Trail trail) { Domain d = _v[0].Domain; for (int i = 1; i < _v.Length; i++) { d = d.Cap(_v[i].Domain); if (d.Empty) return false; } if (trail != null) { foreach (Variable t in _v) { t.UpdateDomain(d, trail); } } return true; }
protected internal override bool Satisfy(Trail trail) { if (!SatisfySequential(trail)) return false; return SatisfySerialized(trail); }
protected internal override bool Satisfy(Trail trail) { int m = _rel.Length; int n = _rel[0].Length; // limit the domain of v0 to 0..m-1 var d0 = (IntDomain) _v0.Domain; d0 = d0.CapInterval(0, m - 1); if (d0.Empty) return false; // limit the domain of v1 to 0..n-1 var d1 = (IntDomain) _v1.Domain; d1 = d1.CapInterval(0, n - 1); if (d1.Empty) return false; // Delete impossible indices from v0 for (int i = 0; i < m; i++) { if (!d0.Contains(i)) continue; bool support = false; for (int j = 0; j < n; j++) { if (_rel[i][j] && d1.Contains(j)) { support = true; break; } } if (!support) { d0 = d0.Delete(i); } } if (d0.Empty) return false; // Delete impossible indices from v1 for (int j = 0; j < n; j++) { if (!d1.Contains(j)) continue; bool support = false; for (int i = 0; i < m; i++) { if (_rel[i][j] && d0.Contains(i)) { support = true; break; } } if (!support) { d1 = d1.Delete(j); } } if (d1.Empty) return false; if (trail != null) { _v0.UpdateDomain(d0, trail); _v1.UpdateDomain(d1, trail); } return true; }
/// <summary> /// Updates the domain of the current variable with the parameter domain d after /// pushing the Trail trial /// </summary> /// <param name="d">the domain to be updated with</param> /// <param name="trail">the trail to be pushed</param> public virtual void UpdateDomain(Domain d, Trail trail) { if (_domain == null || !_domain.Equals(d)) { trail.Push(this); _domain = d; _modified = true; if (_watch) { Console.Out.WriteLine(this + " = " + _domain); } } }
private static bool SatisfyLT(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; d0 = d0.CapInterval(IntDomain.MinValue, d1.Maximum() - 1); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } d1 = d1.CapInterval(d0.Minimum() + 1, IntDomain.MaxValue); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } return true; }
private static bool SatisfyABS(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; if (d1.Size() == 1) { // v0 = Abs(v1) int value = Math.Abs(d1.Value()); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d0.Size() == 1) { // Abs(v1) = v0 int value = d0.Value(); if (value < 0) { return(false); } if (value == 0) { if (!d1.Contains(value)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d1.Contains(value) && d1.Contains(-value)) { if (d1.Size() > 2) { value = Math.Abs(value); d1 = new IntDomain(-value, value); d1 = d1.Delete(-value + 1, value - 1); if (trail != null) { v1.UpdateDomain(d1, trail); } } return(true); } if (d1.Contains(value)) { if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d1.Contains(-value)) { if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(-value), trail); } } return(true); } return(false); } int min; int max; // v0 = Abs(v1) if (d1.Minimum() >= 0) { min = d1.Minimum(); max = d1.Maximum(); } else if (d1.Maximum() <= 0) { min = -d1.Maximum(); max = -d1.Minimum(); } else { min = 0; max = Math.Max(-d1.Minimum(), d1.Maximum()); } d0 = d0.CapInterval(min, max); if (d0.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); } // Abs(v1) = v0 min = d0.Minimum(); max = d0.Maximum(); d1 = d1.CapInterval(-max, max); if (d1.Empty) { return(false); } if (min > 0) { d1 = d1.Delete(-min + 1, min - 1); } if (trail != null) { v1.UpdateDomain(d1, trail); } return(true); }
protected internal override bool Satisfy(Trail trail) { switch (_comparison) { case Le: return SatisfyLE(_v[0], _v[1], trail); case Lt: return SatisfyLT(_v[0], _v[1], trail); case Ge: return SatisfyLE(_v[1], _v[0], trail); case Gt: return SatisfyLT(_v[1], _v[0], trail); } return false; }
protected internal abstract bool Satisfy(Trail trail);
protected internal override bool Satisfy(Trail trail) { switch (_arith) { case Add: return SatisfyAdd(_v[0], _v[1], _v[2], trail); case Subtract: return SatisfyAdd(_v[1], _v[0], _v[2], trail); case MULTIPLY: return SatisfyMULTIPLY(_v[0], _v[1], _v[2], trail); case MAX: return SatisfyMAX(_v[0], _v[1], _v[2], trail); case MIN: return SatisfyMIN(_v[0], _v[1], _v[2], trail); } return false; }
protected override internal bool Satisfy(Trail trail) { int m = rel.Length; int n = rel[0].Length; // limit the domain of v0 to 0..m-1 var d0 = (IntDomain)v0.Domain; d0 = d0.CapInterval(0, m - 1); if (d0.Empty) { return(false); } // limit the domain of v1 to 0..n-1 var d1 = (IntDomain)v1.Domain; d1 = d1.CapInterval(0, n - 1); if (d1.Empty) { return(false); } // Delete impossible indices from v0 for (int i = 0; i < m; i++) { if (!d0.Contains(i)) { continue; } bool support = false; for (int j = 0; j < n; j++) { if (rel[i][j] && d1.Contains(j)) { support = true; break; } } if (!support) { d0 = d0.Delete(i); } } if (d0.Empty) { return(false); } // Delete impossible indices from v1 for (int j = 0; j < n; j++) { if (!d1.Contains(j)) { continue; } bool support = false; for (int i = 0; i < m; i++) { if (rel[i][j] && d0.Contains(i)) { support = true; break; } } if (!support) { d1 = d1.Delete(j); } } if (d1.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); } return(true); }
private static bool SatisfyMIN(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; var d2 = (IntDomain) v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = Min(v1, v2) int value = Math.Min(d1.Value(), d2.Value()); if (!d0.Contains(value)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1) { int value = d0.Value(); if (!d1.Contains(value) && !d2.Contains(value)) return false; // ??? if (d1.Minimum() < value) { d1.CapInterval(value, IntDomain.MaxValue); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } } if (d2.Minimum() < value) { d2.CapInterval(value, IntDomain.MaxValue); if (d2.Empty) return false; if (trail != null) { v2.UpdateDomain(d2, trail); } } return true; } // v0 = Min(v1, v2) int min = Math.Min(d1.Minimum(), d2.Minimum()); int max = Math.Min(d1.Maximum(), d2.Maximum()); d0 = d0.CapInterval(min, max); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } // if (d1.Minimum() < d0.Minimum()) d1 = d1.CapInterval(d0.Minimum(), IntDomain.MaxValue); if (d2.Minimum() < d0.Minimum()) d2 = d2.CapInterval(d0.Minimum(), IntDomain.MaxValue); if (d1.Minimum() > d0.Maximum()) { d0 = (IntDomain) d0.Cap(d2); d2 = d0; } if (d2.Minimum() > d0.Maximum()) { d0 = (IntDomain) d0.Cap(d1); d1 = d0; } if (d0.Empty) return false; if (d1.Empty) return false; if (d2.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); v2.UpdateDomain(d2, trail); } return true; }
private bool SatisfyADD(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; var d2 = (IntDomain)v2.Domain; int value; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = v1 + v2 value = d1.Value() + d2.Value(); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } } return(true); } value = d0.Value() - d2.Value(); if (d0.Size() == 1 && d2.Size() == 1) { // v1 = v0 - v2 if (!d1.Contains(value)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } value = d0.Value() - d1.Value(); if (d0.Size() == 1 && d1.Size() == 1) { // v2 = v0 - v1 if (!d2.Contains(value)) { return(false); } if (d2.Size() > 1) { if (trail != null) { v2.UpdateDomain(new IntDomain(value), trail); } } return(true); } // v0 = v1 + v2 d0 = d0.CapInterval(d1.Minimum() + d2.Minimum(), d1.Maximum() + d2.Maximum()); if (d0.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); } // v1 = v0 - v2 d1 = d1.CapInterval(d0.Minimum() - d2.Maximum(), d0.Maximum() - d2.Minimum()); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } // v2 = v0 - v1 d2 = d2.CapInterval(d0.Minimum() - d1.Maximum(), d0.Maximum() - d1.Minimum()); if (d2.Empty) { return(false); } if (trail != null) { v2.UpdateDomain(d2, trail); } return(true); }
private bool SatisfyMULTIPLY(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; var d2 = (IntDomain)v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = v1 * v2 int value = ToInt(d1.Value() * (long)d2.Value()); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d0.Size() == 1 && d2.Size() == 1) { // v1 = v0 / v2 int x = d0.Value(); int y = d2.Value(); if (y == 0) { return(x == 0); } if (x % y != 0) { return(false); } int value = x / y; if (!d1.Contains(value)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d0.Size() == 1 && d1.Size() == 1) { // v2 = v0 / v1 int x = d0.Value(); int y = d1.Value(); if (y == 0) { return(x == 0); } if (x % y != 0) { return(false); } int value = x / y; if (!d2.Contains(value)) { return(false); } if (d2.Size() > 1) { if (trail != null) { v2.UpdateDomain(new IntDomain(value), trail); } } return(true); } d0 = Multiply(d0, d1, d2); if (d0.Empty) { return(false); } d1 = Divide(d1, d0, d2); if (d1.Empty) { return(false); } d2 = Divide(d2, d0, d1); if (d2.Empty) { return(false); } if (trail != null) { if (d0 != v0.Domain) { v0.UpdateDomain(d0, trail); } if (d1 != v1.Domain) { v1.UpdateDomain(d1, trail); } if (d2 != v2.Domain) { v2.UpdateDomain(d2, trail); } } return(true); }