我希望这不是一个统计问题...
假设我有一个界面:
public interface PairValidatable<T>
{
public boolean isValidWith(T);
}
现在如果我有一个大型的PairValidatables数组,我怎样才能找到每个对通过isValidWith测试的那个数组的最大子集?
澄清一下,如果子集中有三个条目,那么元素0和1应该传递isValidWith,元素1和2应该传递isValidWith,元素0和2应该传递isValidWith。
实施例,
public class Point implements PairValidatable<Point>
{
int x;
int y;
public Point(int xIn, int yIn)
{
x = xIn;
y = yIn;
}
public boolean isValidWith(Point other)
{
//whichever has the greater x must have the lesser (or equal) y
return x > other.x != y > other.y;
}
}
The intuitive idea是保持点向量,添加数组元素0,并将每个剩余的数组元素与向量进行比较,如果它通过向量中的每个元素进行验证,如果是这样,则将其添加到向量中。 ..但问题是元素0可能非常严格。例如,
Point[] arr = new Point[5];
arr[0] = new Point(1000, 1000);
arr[1] = new Point(10, 10);
arr[2] = new Point(15, 7);
arr[3] = new Point(3, 6);
arr[4] = new Point(18, 6);
如上所述迭代将为我们提供仅包含元素0的子集,但是元素1,2和4的子集是更大的子集,其中每一对都通过验证。然后算法应该返回存储在元素1,2和4中的点。虽然元素3和4彼此有效并且元素1和4彼此有效,但元素2和3不是,元素1和3也不是。包含1,2和4的子集是比3和4更大的子集。
我猜一些树或图算法最适合解决这个问题,但我不确定如何设置它。
解决方案不必是特定于Java的,并且最好能够以任何语言实现,而不是依赖于Java内置函数。出于熟悉的原因,我上面只使用了类似Java的伪代码。
答案 0 :(得分:5)
大概isValidWith
是可交换的 - 也就是说,x.isValidWith(y)
然后是y.isValidWith(x)
。如果您只知道这一点,那么您将拥有maximum clique problem的实例,该实例已知为NP完全:
Skiena,S。S.“Clique and Independent Set”和“Clique”。算法设计手册中的§6.2.3和8.5.1。纽约:Springer-Verlag,第144和312-314页,1997年。
因此,如果你想要一个有效的算法,你将不得不希望你的特定isValidWith
函数具有更多结构而不仅仅是交换性,你将不得不利用这种结构。
针对您的具体问题,您应该能够执行以下操作:
每个操作都可以在O(n * log(n))时间内执行,因此您的特定问题可以有效解决。