确定不等式关系的算法

时间:2016-06-03 04:06:48

标签: algorithm

这个问题是关于算法是否存在。首先,我有一个由未识别的东西组成的集合T,也就是说,我不知道两个元素是相同还是不同。但是,我有一个函数,在一些编程语言中(更具体地说,在R中)能够确定T的两个或三个东西是否不同,但只是不同。例如,假设T = {A,B,C}, 所以我的功能是这样的:

f(B,C) = (0,1)  means that C is not equal to B;

f(B,C) = (0,0)  nothing to say about B and C. In other words, B and C can be equal or different;

f(B,C) = (1,1)  the same thing of the last example, B and C can be equal or different;

此外,此功能适用于任意三个元素组

f(A,B,C) = (0,0,1), that means that C is not equal to A and B, but A and B can be equal or different, that is, nothing to say.

另外两个例子,

f(A,B,C) = (1,2,3) means that A, B, C are different mutually

f(A,B,C) = (1,0,1)  means that A and C aren't no equals to B, but A and C can be equal or different, that is, nothing to say.

总之,不同的数字表示不等式,但相同的数字表示没有关系,既不相同也不相同。

我想使用f函数和能够用n个元素评估任何集合T的任何算法(?)生成其他函数f2> 3。

这样的事情:

f2(T)
if cardinality of T < 3, return f(T)
else 
....... 

f2表现得像f一样。也就是说,例如,

f2(A,B,C,D) = (0,1,0,0) meaning that A, B or D is not iqual to C, but nothing to say between A, B and D.

又一个例子

 f2(A,B,C,D,E,F) = (1,2,3,4,0,0) meaning that A,B,C and D are mutually not iqual, but E and F with no relation. 

可能有些算法吗?

1 个答案:

答案 0 :(得分:2)

我相信你的'不等式'功能完全等同于适当的子集分组功能。换句话说:

f(a,b) -> (x,y)

真的意味着

there exists proper subsets x and y of T
such that a is an element of x and b is an element of y

为了转换为不等式,我们知道元素是否在不同的适当(即非重叠)子集中,那么它们必须不相等。如果它们属于同一子集,那么它们可能相等也可能不相等。

因此,现在为两个以上的元素创建一个等效函数需要创建一组子集来放置每个元素。

所以,粗略地说,算法是:

f(Set s)
    for each element in S
        use f to determine which other elements it is in a subset with
    for each pair of element
        if they are in the same subsets as all other elements
            they are in the same subset in the result
        else
            they are in different subsets

这是一些使用一些相关测试实现算法的Java代码。我为流的简洁使用道歉。如果需要,我可以解释它是如何工作的。

public class Inequality {

    private final Set<Set<String>> inequalities = new HashSet<>();

    public void add(String... elements) {
        inequalities.add(new HashSet<>(Arrays.asList(elements)));
    }

    public List<Integer> get(String... elements) {
        List<Set<String>> distinctSets = Arrays.stream(elements)
                .map(el -> knownUnequalElements(Arrays.asList(elements), el))
                .distinct().collect(Collectors.toList());
        return Arrays.stream(elements)
                .map(el -> distinctSets.indexOf(knownUnequalElements(Arrays.asList(elements), el)))
                .collect(Collectors.toList());
    }

    private Set<String> knownUnequalElements(List<String> list, String element) {
        return inequalities.stream()
                .filter(ineq -> ineq.contains(element))
                .flatMap(ineq -> ineq.stream().filter(other -> !other.equals(element)))
                .filter(list::contains)
                .collect(Collectors.toSet());
    }
}

请注意,我只是忽略了不为人所知的元素。我只添加已知与集合(集合)不相等的元素。

@Test
public void testInequalities() {
    Inequality inequality = new Inequality();
    inequality.add("A", "B");
    inequality.add("A", "D");
    inequality.add("B", "D");
    assertThat("unknown elements", inequality.get("E", "F"), is(Arrays.asList(0, 0)));
    assertThat("unknown inequality", inequality.get("A", "C"), is(Arrays.asList(0, 0)));
    assertThat("known inequality", inequality.get("B", "D"), is(Arrays.asList(0, 1)));
    assertThat("commutativity", inequality.get("D", "B"), is(Arrays.asList(0, 1)));
    assertThat("unknown triple", inequality.get("E", "F", "G"), is(Arrays.asList(0, 0, 0)));
    assertThat("known triple", inequality.get("A", "B", "D"), is(Arrays.asList(0, 1, 2)));
}