【问题标题】:Algorithm to compute total area covered by a set of overlapping segments?计算一组重叠段覆盖的总面积的算法?
【发布时间】:2011-11-12 15:56:16
【问题描述】:

我有一个可能重叠区间的端点列表,我想要一种有效的方法来计算 k 区间覆盖的总面积,k=1,2,...(不进行所有成对比较)。或者,这不可能吗?

例如,假设 x 是起点列表,y 是终点列表, 还有那个x[i] < y[i],和

x = (1.5, 2, 3, 5)
y = (3, 4, 4, 6)

使得至少一个区间所覆盖的总面积为3.5,至少两个区间所覆盖的总面积为1。

谢谢,博士。

【问题讨论】:

  • "至少一个区间覆盖的总面积是 3.5" 我遗漏了一些东西 - 你是怎么计算的?
  • "区间覆盖的区域" — 尺寸不匹配?
  • 我指的是一般意义上的“面积”(这里是“长度”)。 @davmac 画图?

标签: algorithm math computational-geometry range


【解决方案1】:

这是计算几何中的经典线扫描问题。

在每个起点加上 +1,在每个终点加上 -1。然后想象一下从负无穷到正无穷的数轴上行走。

每次遇到 +1 时,将身高增加 1。每次遇到 -1 时,降低身高。当您在数轴上从 p1 移动到 p2 时,将 p2 - p1(扫过的长度)添加到给定高度所覆盖的数量。

然后,您将得到一个由每个高度精确覆盖的长度直方图。如果您想处理“至少两个间隔”的情况,您可以累积总数。

【讨论】:

  • Rad,就可以了。正是我想要的!
【解决方案2】:

我不知道@rrenaud 在我写同样的东西时发布了他的解决方案,所以我将省略解释,只给你代码。这是一个 javascript 版本的线扫描:

// x and y inputs are your start and end points for ranges,
// as in the example data
function countOverlapRanges(x, y) {
    var ranges = [];
    var n = x.length;
    if (n !== y.length) {
        throw "Input arrays must be the same length!";
    }
    var i;

    // iterate over all inputs, pushing them into the array
    for (i = 0; i < n; ++i) {
        ranges.push({
            value: x[i],
            change: 1
        });
        ranges.push({
            value: y[i],
            change: -1
        });
    }

    // sort the array into number-line order
    ranges.sort(function (a, b) {
        return a.value - b.value;
    });

    var result = {};
    var k = 1;
    var maxK = 1;
    n = ranges.length;

    // iterate over the sorted data, counting the size of ranges
    var cur, value, lastValue = ranges[0].value;
    for (i = 1; i < n; ++i) {
        cur = ranges[i];
        value = cur.value;
        if (k) {
            var difference = value - lastValue;
            result[k] = (result[k] || 0) + difference;
        }
        k += cur.change;
        maxK = Math.max(maxK, k);
        lastValue = value;
    }

    // so far we've counted the ranges covered by exactly k intervals.
    // adjust the results to get the size of ranges covered by
    // at least k intervals.
    var sum = 0;
    for (i = maxK; i > 0; --i) {
        sum = result[i] = sum + result[i];
    }

    return result;
}

它返回一个将 k 值映射到沿线距离的对象。

【讨论】:

    猜你喜欢
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 2013-12-21
    • 2021-09-04
    • 2018-05-16
    相关资源
    最近更新 更多