示例#1
0
 protected override bool Update(NumericVariable v)
 {
     return(v.RestrictRange(-(v == _variable1 ? _variable2 : _variable1).Value));
 }
示例#2
0
        //public SumIs0Constraint Plus(DoubleHolder d) {
        //    return new SumIs0Constraint(_plus.Concat(new[] { d }));
        //}

        protected override bool Update(NumericVariable v)
        {
            bool changed = false;

            // The following propagation uses these ideas:
            // For each variable v, take the sum S of all OTHER Lo values. A high value that is higher
            // than -S will never cancel S to zero, let alone sums that are greater than S. Hence,
            // v.Hi can be restricted to <= -S.
            // Likewise, v.Lo can be restricted to >= -S where S is the sum of all other Hi values.

            // O(n^2) algorithm - a O(n) algorithm is possible ... later
            double loSum = 0;

            // OnceExcluded is necessary for a constraint like X + X + Y = 0: When we already know
            // that X = [100..100] and Y = [-200..-200], this should succeed. However, when during
            // Upgrade(X) we skip both X's (via w != v), the sum will not be 100-200 == 100, but
            // -200; and hence
            // X will then be restricted to [200..+inf], which, together with the previously known
            // value X = 100 will erroneously imply that there is no solution for X.
            // By the way, when in X + X + Y = 0, we have X = [-inf...+inf] and Y = [-200..-200] at
            // the beginning, we will NOT conclude that X = [100..100] - that would be equation
            // solving, which we do not support at this level.

            bool onceExcluded = false;

            foreach (var w in _inputVariables)
            {
                if (onceExcluded || w != v)
                {
                    double wLo = w.Value.Lo;
                    if (double.IsNegativeInfinity(wLo))
                    {
                        // Nothing can be said about the sum of lows - cancel this computation;
                        goto SKIP_LO;
                    }
                    loSum += wLo;
                }
                else
                {
                    onceExcluded = true;
                }
            }
            changed |= v.RestrictRange(double.NegativeInfinity, -loSum);
SKIP_LO:

            double hiSum = 0;

            onceExcluded = false;
            foreach (var w in _inputVariables)
            {
                if (onceExcluded || w != v)
                {
                    double wHi = w.Value.Hi;
                    if (double.IsPositiveInfinity(wHi))
                    {
                        // Nothing can be said about the sum of his - cancel this computation;
                        goto SKIP_HI;
                    }
                    hiSum += wHi;
                }
                else
                {
                    onceExcluded = true;
                }
            }
            changed |= v.RestrictRange(-hiSum, double.PositiveInfinity);
SKIP_HI:
            return(changed);
        }
示例#3
0
 protected override bool Update(NumericVariable v)
 {
     return(v.RestrictRange(_range));
 }