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 IntDomain Divide(IntDomain d0, IntDomain d1, IntDomain d2) { if (!d1.Contains(0)) { d0 = d0.Delete(0); if (d0.Empty) { return(IntDomain.EmptyDomain); } } if (d2.Contains(0)) { return(d0); } if (d2.Maximum() < 0 || 0 < d2.Minimum()) { var x = new[] { d1.Minimum() / d2.Minimum(), d1.Maximum() / d2.Minimum(), d1.Minimum() / d2.Maximum(), d1.Maximum() / d2.Maximum() }; d0 = d0.CapInterval(Min(x), Max(x)); } else { var x = new[] { d1.Minimum() / d2.Minimum(), d1.Maximum() / d2.Minimum(), d1.Minimum() / d2.Maximum(), d1.Maximum() / d2.Maximum(), d1.Minimum(), d1.Maximum(), -d1.Minimum(), -d1.Maximum() }; d0 = d0.CapInterval(Min(x), Max(x)); } return(d0); }
/// <summary> /// Deletes values between minimum and miximum values /// </summary> /// <param name="low"> /// The low.value /// </param> /// <param name="high"> /// The high.value /// </param> /// <returns> /// IntDomain object /// </returns> public virtual IntDomain Delete(int low, int high) { if (sizeField == 0 || low > high || high < minField || maxField < low) { return(this); } if (low == high) { return(Delete(low)); } var d = new IntDomain(); try { for (int i = 0; i < intervals.Count; i++) { var interval = (int[])intervals[i]; int mi = Math.Max(low, interval[0]); int ma = Math.Min(high, interval[1]); if (mi <= ma) { if (interval[0] < mi) { var period = new int[2]; period[0] = interval[0]; period[1] = mi - 1; d.intervals.Add(period); } if (ma < interval[1]) { var period = new int[2]; period[0] = ma + 1; period[1] = interval[1]; d.intervals.Add(period); } } else { var period = new int[2]; period[0] = interval[0]; period[1] = interval[1]; d.intervals.Add(period); } } } catch (IndexOutOfRangeException) { } d.UpdateSize(); d.UpdateMinMax(); return(d); }
/// <summary> /// Captilizes interval /// </summary> /// <param name="low"> /// The low.value /// </param> /// <param name="high"> /// The high.value /// </param> /// <returns> /// a modified domain /// </returns> public virtual IntDomain CapInterval(int low, int high) { IntDomain d = this; if (MinValue < low) { d = d.Delete(MinValue, low - 1); } if (high < MaxValue) { d = d.Delete(high + 1, MaxValue); } return(d); }
/// <summary> /// Clones this object /// </summary> /// <returns> /// an object value /// </returns> public override object Clone() { var d = new IntDomain(); try { for (int i = 0; i < intervals.Count; ++i) { d.intervals.Add(((int[])intervals[i]).Clone()); } } catch (IndexOutOfRangeException) { } d.sizeField = sizeField; d.minField = minField; d.maxField = maxField; return(d); }
private IntDomain Multiply(IntDomain d0, IntDomain d1, IntDomain d2) { if (!d1.Contains(0) && !d2.Contains(0)) { d0 = d0.Delete(0); if (d0.Empty) { return(IntDomain.EmptyDomain); } } var x = new[] { ToInt(d1.Minimum() * (long)d2.Minimum()), ToInt(d1.Minimum() * (long)d2.Maximum()), ToInt(d1.Maximum() * (long)d2.Minimum()), ToInt(d1.Maximum() * (long)d2.Maximum()) }; d0 = d0.CapInterval(Min(x), Max(x)); return(d0); }
/// <summary> /// Initiates block /// </summary> /// <param name="enclosingIns"> /// The enclosing instance /// </param> private void InitBlock(IntDomain enclosingIns) { _enclosingInstance = enclosingIns; _choice = Enclosing_Instance._minField; }
/// <summary> /// Initializes a new instance of the <see cref="IntDomainIterator"/> class. /// </summary> /// <param name="enclosingInstance"> /// The enclosing instance. /// </param> public IntDomainIterator(IntDomain enclosingInstance) { InitBlock(enclosingInstance); }
/// <summary> /// Deletes values between minimum and miximum values /// </summary> /// <param name="low"> /// The low.value /// </param> /// <param name="high"> /// The high.value /// </param> /// <returns> /// IntDomain object /// </returns> public virtual IntDomain Delete(int low, int high) { if (sizeField == 0 || low > high || high < _minField || _maxField < low) { return this; } if (low == high) { return Delete(low); } var d = new IntDomain(); try { for (int i = 0; i < _intervals.Count; i++) { var interval = (int[])_intervals[i]; int mi = Math.Max(low, interval[0]); int ma = Math.Min(high, interval[1]); if (mi <= ma) { if (interval[0] < mi) { var period = new int[2]; period[0] = interval[0]; period[1] = mi - 1; d._intervals.Add(period); } if (ma < interval[1]) { var period = new int[2]; period[0] = ma + 1; period[1] = interval[1]; d._intervals.Add(period); } } else { var period = new int[2]; period[0] = interval[0]; period[1] = interval[1]; d._intervals.Add(period); } } } catch (IndexOutOfRangeException) { } d.UpdateSize(); d.UpdateMinMax(); return d; }
/// <summary> /// Clones this object /// </summary> /// <returns> /// an object value /// </returns> public override object Clone() { var d = new IntDomain(); try { for (int i = 0; i < _intervals.Count; ++i) { d._intervals.Add(((int[])_intervals[i]).Clone()); } } catch (IndexOutOfRangeException) { } d.sizeField = sizeField; d._minField = _minField; d._maxField = _maxField; return d; }
/// <summary> /// Capitalize domain /// </summary> /// <param name="domain"> /// The domain. /// </param> /// <returns> /// A modified domain /// </returns> public override Domain Cap(Domain domain) { if (!(domain is IntDomain)) { return emptyDomain; } var newD = new IntDomain(); IntDomain d0 = this; var d1 = (IntDomain)domain; try { int i0 = 0; int i1 = 0; while (i0 < d0._intervals.Count && i1 < d1._intervals.Count) { var interval = (int[])d0._intervals[i0]; int min0 = interval[0]; int max0 = interval[1]; interval = (int[])d1._intervals[i1]; int min1 = interval[0]; int max1 = interval[1]; if (max0 < min1) { i0++; continue; } if (max1 < min0) { i1++; continue; } interval = new int[2]; interval[0] = Math.Max(min0, min1); interval[1] = Math.Min(max0, max1); newD._intervals.Add(interval); if (max0 <= max1) { i0++; } if (max1 <= max0) { i1++; } } } catch (IndexOutOfRangeException) { } newD.UpdateSize(); newD.UpdateMinMax(); if (newD.Empty) { return emptyDomain; } return newD; }
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; }
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); }
/// <summary> /// Initiates block /// </summary> /// <param name="enclosingIns"> /// The enclosing instance /// </param> private void InitBlock(IntDomain enclosingIns) { enclosingInstance = enclosingIns; choice = Enclosing_Instance.minField; }
private static IntDomain Divide(IntDomain d0, IntDomain d1, IntDomain d2) { if (!d1.Contains(0)) { d0 = d0.Delete(0); if (d0.Empty) return IntDomain.emptyDomain; } if (d2.Contains(0)) { return d0; } if (d2.Maximum() < 0 || 0 < d2.Minimum()) { var x = new[]{d1.Minimum() / d2.Minimum(), d1.Maximum() / d2.Minimum(), d1.Minimum() / d2.Maximum(), d1.Maximum() / d2.Maximum()}; d0 = d0.CapInterval(Min(x), Max(x)); } else { var x = new[]{d1.Minimum() / d2.Minimum(), d1.Maximum() / d2.Minimum(), d1.Minimum() / d2.Maximum(), d1.Maximum() / d2.Maximum(), d1.Minimum(), d1.Maximum(), - d1.Minimum(), - d1.Maximum()}; d0 = d0.CapInterval(Min(x), Max(x)); } return d0; }
private static IntDomain Multiply(IntDomain d0, IntDomain d1, IntDomain d2) { if (!d1.Contains(0) && !d2.Contains(0)) { d0 = d0.Delete(0); if (d0.Empty) return IntDomain.emptyDomain; } var x = new[] { ToInt(d1.Minimum() * (long) d2.Minimum()), ToInt(d1.Minimum() * (long) d2.Maximum()), ToInt(d1.Maximum() * (long) d2.Minimum()), ToInt(d1.Maximum() * (long) d2.Maximum()) }; d0 = d0.CapInterval(Min(x), Max(x)); return d0; }
/// <summary> /// Capitalize domain /// </summary> /// <param name="domain"> /// The domain. /// </param> /// <returns> /// A modified domain /// </returns> public override Domain Cap(Domain domain) { if (!(domain is IntDomain)) { return(EmptyDomain); } var newD = new IntDomain(); IntDomain d0 = this; var d1 = (IntDomain)domain; try { int i0 = 0; int i1 = 0; while (i0 < d0.intervals.Count && i1 < d1.intervals.Count) { var interval = (int[])d0.intervals[i0]; int min0 = interval[0]; int max0 = interval[1]; interval = (int[])d1.intervals[i1]; int min1 = interval[0]; int max1 = interval[1]; if (max0 < min1) { i0++; continue; } if (max1 < min0) { i1++; continue; } interval = new int[2]; interval[0] = Math.Max(min0, min1); interval[1] = Math.Min(max0, max1); newD.intervals.Add(interval); if (max0 <= max1) { i0++; } if (max1 <= max0) { i1++; } } } catch (IndexOutOfRangeException) { } newD.UpdateSize(); newD.UpdateMinMax(); if (newD.Empty) { return(EmptyDomain); } return(newD); }