예제 #1
0
        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();
            //------------------------------------------------------------------------------------------
        }
예제 #2
0
 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);
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
        }
예제 #7
0
 /// <summary>
 /// Initiates block
 /// </summary>
 /// <param name="enclosingIns">
 /// The enclosing instance
 /// </param>
 private void InitBlock(IntDomain enclosingIns)
 {
     _enclosingInstance = enclosingIns;
     _choice = Enclosing_Instance._minField;
 }
예제 #8
0
 /// <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);
 }
예제 #9
0
        /// <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;
        }
예제 #10
0
        /// <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;
        }
예제 #11
0
        /// <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;
        }
예제 #12
0
        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;
        }
예제 #13
0
        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);
        }
예제 #14
0
 /// <summary>
 /// Initiates block
 /// </summary>
 /// <param name="enclosingIns">
 /// The enclosing instance
 /// </param>
 private void InitBlock(IntDomain enclosingIns)
 {
     enclosingInstance = enclosingIns;
     choice            = Enclosing_Instance.minField;
 }
예제 #15
0
 /// <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);
 }
예제 #16
0
 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;
 }
예제 #17
0
 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;
 }
예제 #18
0
        /// <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);
        }