【发布时间】:2017-02-21 18:09:29
【问题描述】:
我希望这不是一个统计问题...
假设我有一个接口:
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是保留一个Points的向量,添加数组元素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 的伪代码。
【问题讨论】:
-
-
@Stephan 不完全是。子集中的每一对都应该从 isValidWith 返回 true。例如,a 可能对 b 有效,b 可能对 c 有效,但 c 可能对 a 无效。这意味着必须省略 a 或 c。我不确定我的示例方法是否会以这种方式运行,但解决方案应该包含这样的方法。
-
您能否扩展您的问题以在示例中包含 3 个以上的条目,以及您期望的输出是什么?
-
绘制出来,看起来您正在寻找边缘具有非负斜率的最大元素子集。这听起来准确吗?
-
@Stephan 这是一个很好的观察,虽然我认为你的意思是说非正斜率。这样可以更轻松地解决该案例。