1

我正在研究使用布尔条件表达式的匹配系统的一小部分。

这些条件表达式被限制为单个变量和单个运算符(具有 Inclusive Between 的边缘情况)。

我对感兴趣:

  • 等于“=”
  • 大于“>”
  • 大于或等于 ">="
  • 小于“<”
  • 小于或等于“<=”
  • 包含在 ">= AND <=" 之间

我需要比较两个条件表达式并评估:

1)可能的值是否重叠?

“X > 1000”是否与“X > 999”重叠?是的。

2)如果有重叠,返回重叠:

“X > 1000”与“X > 999”的重叠是“X > 1000”

3) 条件表达式是否受另一个条件表达式约束?

"X < 999" 受 "X < 1000" 约束;“X < 1001”不受“X < 1000”的约束


到目前为止我所做的是建立所有可能组合的真值表并返回结果,但我想知道是否有更简单的方法来计算这些?

有任何理论/参考资料/C# 库吗?

4

2 回答 2

3

我没有听说过,但是如果您将约束表示为间隔,则可以轻松地不使用它们:

x > 1000 变为 (1000, double.Infinity)
x == 1000 变为 [1000, 1000]

等等

这样你只需要一个类

class Constraint
{
    double Lower; bool isLowerStrict;
    double Upper; bool isUpperStrict;
    bool isIn(double d)
    { 
        return (isLowerStrict ? Lower < d : Lower <= d) &&
               (isUpperStrict ? Upper > d : Upper >= d);
    }

    Constraint intersect(Constraint other)
    {
        Constraint result = new Constraint();
        if (Lower > other.Lower)
        {
            result.Lower = Lower;
            result.isLowerStrict = isLowerStrict;
        }
        else if (Lower < other.Lower)
        {
            result.Lower = other.Lower;
            result.isLowerStrict = other.isLowerStrict;
        }
        else
        {
            result.Lower = Lower;
            result.IsLowerStrict = isLowerStrict || other.isLowerStrict;
        }
        // the same for upper
        return result;
    }

    public bool isEmpty()
    {
        if (Lower > Upper) return true;
        if (Lower == Upper && (isLowerStrict || isUpperStrict)) return true;
        return false;
    }
    public bool Equals(Constraint other)
    {
        if (isEmpty()) return other.isEmpty();
        return (Lower == other.Lower) && (Upper = other.Upper) &&
               (isLowerStrict == other.IsLowerStrict) &&
               (isUpperStrict == other.isUpperStrict);
    }

    // construction:
    static Constraint GreaterThan(double d)
    {
        return new Constraint()
        {
            Lower = d,
            isLowerStrict = true,
            Upper = double.PositiveInfinity,
            isUpperStrict = false
        };
    }
    static Constraint IsEqualTo(double d)
    {
        return new Constraint()
        {
            Lower = d,
            isLowerStrict = false,
            Upper = d,
            isUpperStrict = false
        };
    }
    // etc.
}

使用此代码,您可以回答以下问题:

1)重叠:a.Intersect(b).isEmpty()

2)相交:a.Intersect(b)

3) 约束:a.Intersect(b).Equals(a)


编辑:
正如@CodeInChaos 建议的那样,您应该考虑用十进制替换双精度。请注意,十进制缺少无限值,因此您应该改用 decimal.MaxValue 和 decimal.MinValue。

于 2011-08-17T14:43:37.063 回答
0

我已经快速编写了一些示例代码。希望这是有道理的:

enum SygnType
{
    More, Less, Equal
}
public class Representation
{
    public SignType sign;
    public int value;
}
public class Range
{
    public bool infinityNegative;
    public bool infinityPositive;
    public int minValue;
    public int maxValue;
    public Range(List<Representation> values)
    {
        infinityNegative=true;
        infinityPositive=true;
        foreach(var value in values)
        {
            if (value.sign==SignType.More)
            {
                infinityNegative=false;
                if (value>minValue)
                    minValue=value;
            }
            else if (value.sign==SignType.Less)
            {
                infinityPositive=false;
                if (value<maxValue)
                    maxValue=value;
            }
            else if (value.sign==SignType.Equal)
            {
                infinityPositive=infinityNegative=false;
                minValue=maxValue=value;
                break;
            }
        }
    }
    public bool Overlaps(Range checkRange)
    {
        if (checkRange.infinityPositive)
            return CompareUpperLevelValue(checkRange); //this method should compare upper value overlapping
        else if (checkRange.infinityNegative)
            return CompareLowerLevelValue(checkRange); //this method should compare lower value overlapping
        else
            return CompareInterval(checkRange); //this method should compare interval
    }
    public bool CompareUpperLevelValue(Range checkRange)
    {
        if (checkRange.maxValue<maxValue)
            return true;
        else 
            return false
    }
    public bool CompareLowerLevelValue(Range checkRange)
    {
        if (checkRange.minValue>minValue)
            return true;
        else 
            return false
    }
    public bool CompareInterval(Range checkRange)
    {
        if ((checkRange.minValue>minValue)&&(checkRange.maxValue<maxValue))
            return true;
        else
            return false;
    }
}
于 2011-08-17T14:56:33.190 回答