如何获取使用数组的任意两个值调用的函数的所有可能值?

发布于 2024-09-14 08:11:33 字数 2629 浏览 5 评论 0原文

考虑以下代码:

class MyClass {
    string PropertyA;
    int PropertyB;
    double PropertyC;
    object PropertyD;
    static ComparisonResult Compare(MyClass a, MyClass b){
        // returns a ComparisonResult with
        // _sampleElement = a
        // _commonProperties = flags that describe the common properties of a and b
    }
}

enum SimilarityFlags {
    SharedPropertyA = 1,
    SharedPropertyB = 2,
    SharedPropertyC = 4,
    SharedPropertyD = 8
}

class ComparisonResult {
    private MyClass _sampleElement;
    private SimilarityFlags _commonProperties;

    bool Equals(object obj){
        ComparisonResult other = obj as ComparisonResult;
        if(other==null) return false;
        if(this._commonProperties != other._commonProperties) return false;
        MyClass s1 = this._sampleElement;
        MyClass s2 = other._sampleElement;
        if(_commonProperties.HasFlag(SimilarityFlags.SharedPropertyA) && s1.PropertyA != s2.PropertyA) return false; 
        if(_commonProperties.HasFlag(SimilarityFlags.SharedPropertyB) && s1.PropertyB != s2.PropertyB) return false; 
        if(_commonProperties.HasFlag(SimilarityFlags.SharedPropertyC) && s1.PropertyC != s2.PropertyC) return false; 
        if(_commonProperties.HasFlag(SimilarityFlags.SharedPropertyD) && s1.PropertyD != s2.PropertyD) return false; 
        return true;
    }

    int GetHashCode(){
        return (int)_commonProperties;
    }
}



MyClass[] array;
HashSet<ComparisonResult> possibleValues = GetAllPossibleComparisonValues(array);

当 Compare 获取数组中的任意两个元素时,如何获取 Compare 返回的所有可能值?

注意:Compare(a, b) == Compare(b, a) 和 a != b

示例(伪代码,3 个属性而不是 4):

GetAllPossibleComparisonValues( [  {"foo", 5, 0x00}, {"foo", 77, 0x00}, {"BAR", 5, 0x00}, {"foo", 5, 0x00}, {"BAR", 5, 0x00}  ] )

应返回此集合: [ {any, any, 0x00}, {"foo", any, 0x00}, {"foo", 5, 0x00}, {"BAR", 5, 0x00}, {any, 5, 0x00} ]

GetAllPossibleComparisonValues( [ {"foobar", 1}, {"foobar", 2},  {"foobar", 3},  {"foobar", 4} ])

应该返回 [ {"foobar", any} ]

目前,我正在使用此算法:

for(int i = 0; i < array.Length - 1; i++){
    for(int j = i + 1; i < array.Length; j++){
        possibleValues.Add(MyClass.Compare(array[i], array[j]));
    }
}

但效率非常低,特别是对于任意两个元素具有相同 ComparisonResult 的长数组。 计算后,possibleValues.Count 通常非常小 (1..3),即使对于长数组(2000+ 个元素)也是如此。

我认为可以大大提高计算效率。 例如,如果 Compare(array[0], array[1]) == Compare(array[0], array[2]),则无需调用 Compare(array[1], array[2])

如何我愿意?

Consider this code:

class MyClass {
    string PropertyA;
    int PropertyB;
    double PropertyC;
    object PropertyD;
    static ComparisonResult Compare(MyClass a, MyClass b){
        // returns a ComparisonResult with
        // _sampleElement = a
        // _commonProperties = flags that describe the common properties of a and b
    }
}

enum SimilarityFlags {
    SharedPropertyA = 1,
    SharedPropertyB = 2,
    SharedPropertyC = 4,
    SharedPropertyD = 8
}

class ComparisonResult {
    private MyClass _sampleElement;
    private SimilarityFlags _commonProperties;

    bool Equals(object obj){
        ComparisonResult other = obj as ComparisonResult;
        if(other==null) return false;
        if(this._commonProperties != other._commonProperties) return false;
        MyClass s1 = this._sampleElement;
        MyClass s2 = other._sampleElement;
        if(_commonProperties.HasFlag(SimilarityFlags.SharedPropertyA) && s1.PropertyA != s2.PropertyA) return false; 
        if(_commonProperties.HasFlag(SimilarityFlags.SharedPropertyB) && s1.PropertyB != s2.PropertyB) return false; 
        if(_commonProperties.HasFlag(SimilarityFlags.SharedPropertyC) && s1.PropertyC != s2.PropertyC) return false; 
        if(_commonProperties.HasFlag(SimilarityFlags.SharedPropertyD) && s1.PropertyD != s2.PropertyD) return false; 
        return true;
    }

    int GetHashCode(){
        return (int)_commonProperties;
    }
}



MyClass[] array;
HashSet<ComparisonResult> possibleValues = GetAllPossibleComparisonValues(array);

How can I get all the possible values that Compare returns when it takes any two elements in the array?

Note: Compare(a, b) == Compare(b, a) and a != b

Example (pseudocode, 3 properties instead of 4):

GetAllPossibleComparisonValues( [  {"foo", 5, 0x00}, {"foo", 77, 0x00}, {"BAR", 5, 0x00}, {"foo", 5, 0x00}, {"BAR", 5, 0x00}  ] )

should return this set:
[ {any, any, 0x00}, {"foo", any, 0x00}, {"foo", 5, 0x00}, {"BAR", 5, 0x00}, {any, 5, 0x00} ]

GetAllPossibleComparisonValues( [ {"foobar", 1}, {"foobar", 2},  {"foobar", 3},  {"foobar", 4} ])

should return
[ {"foobar", any} ]

Currently, I'm using this algorithm:

for(int i = 0; i < array.Length - 1; i++){
    for(int j = i + 1; i < array.Length; j++){
        possibleValues.Add(MyClass.Compare(array[i], array[j]));
    }
}

but it is very inefficient, especially with long arrays where any two elements have the same ComparisonResult.
After the computation, possibleValues.Count is usually very small (1..3), even for long arrays (2000+ elements).

I think it is possible to greatly improve the efficiency of the computation.
For example, if Compare(array[0], array[1]) == Compare(array[0], array[2]), there's no need to call Compare(array[1], array[2])

How can I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄离 2024-09-21 08:11:33

这个问题似乎是布尔可满足性问题。如果将数组的每个值建模为布尔输入变量,则可以使用维基百科页面中列出的算法来获取满足特定输出变量的所有输入向量。工作量并不低,所以这取决于您是否真的需要这种加速,或者您是否可以接受现有的工作解决方案,因为这很容易理解。

另一件事可能是您缓存所有已找到的解决方案,并且仅在一个数组中添加了新值时才修改这些找到的向量。这样你只需要先找到解向量。如果您可以应用此取决于天气,则可能的值会经常变化,或者如果它们变化不大。

This problem seems to bee the boolean satisfiability problem. If you model each value of your array as an boolean input variable, it might be possible to use the algorithms listed in the wikipedia page to get all input vectors that satisfy a certain output variable. The effort is not low, so it depends if you realy need this speedup or if you can live with your allready working solution since this is very easy to understand.

Another thing could be that you cache your allready found solutions and only modify those found vectors if i.e. a new value in one array has been added. That way you only need to find the solution vectors first. If you can apply this depends weather the possible values change very often, or if they are not altered very much.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文