最小最优+证明的贪婪算法是什么?

时间:2020-10-08 00:46:43

标签: algorithm greedy

细节有些畏缩,应该警告一下:

我想在我的建筑物的地板上设置仪表来接住某人;假设我的地板是一条从0到长度L的数字线。我设计的特定类型的仪表在-x和+ x方向的探测半径为4.7米(探测直径为9.4米)。我想以这样的方式进行设置:如果我要寻找的人踩到地板上的任何地方,我都会知道。但是,我不能随便安装一个电表(这可能会惹恼其他居民)。因此,只有n个有效位置可以设置仪表。此外,这些仪表制造起来既昂贵又费时,因此我想使用尽可能少的仪表。

为简单起见,您可以假定仪表的宽度为0,并且每个有效位置只是上述数字线上的一个点。什么是贪心算法,可以放置尽可能少的米,同时能够像我希望的那样检测长度为L的整个走廊,或者,如果无法检测整个走廊,则将为n个位置的集合输出false我有(并且,如果无法检测整个走廊,在尝试这样做时仍使用尽可能少的米)?

编辑:对是否能够检测整个走廊

的一些说明

2 个答案:

答案 0 :(得分:0)

要证明找到的解决方案是最优的,只需证明它找到了词典上的最优解。

您可以通过按字典顺序最后的最佳解决方案的大小进行归纳。地板长度为零且没有监视器的情况是微不足道的。否则,您将证明您找到了按字典顺序排列的最后一个解决方案的第一个元素。然后用剩下的元素覆盖其余部分,这是您的归纳步骤。

技术说明,要使其正常工作,必须允许您将监控站放置在生产线之外。

答案 1 :(得分:0)

给出:

  • L(走廊长度)
  • 用于放置半径为4.7的仪表(p_0 ... p_N-1)的N个有效位置的列表

您可以在O(N)中确定整个走廊的有效覆盖范围和最小覆盖范围(“良好”),或者在以下约束条件下(伪代码)确定不存在此类覆盖层的证明:

// total = total length; 
// start = current starting position, initially 0
// possible = list of possible meter positions
// placed = list of (optimal) meter placements, initially empty
boolean solve(float total, float start, List<Float> possible, List<Float> placed):

   if (total-start <= 0): 
        return true; // problem solved with no additional meters - woo!
   else:
        Float next = extractFurthestWithinRange(start, possible, 4.7);
        if (next == null):
             return false; // no way to cover end of hall: report failure
        else:
             placed.add(next); // placement decided
             return solve(total, next + 4.7, possible, placed); 

如果extractFurthestWithinRange(float start, List<Float> candidates, float range)的{​​{1}}中没有null,则candidates返回range,或者返回{{ 1}},这样start-并同时删除p和所有候选项candidates,这样p <= start + range

此处的关键是,通过始终选择将仪表放置在a)没有间隙且b)离先前放置的位置最远的下一个位置,我们同时创建了有效的覆盖范围(=没有间隙),并且最佳覆盖范围(=不可能使用有效的覆盖范围使用更少的仪表-因为我们的间隙已经尽可能大)。在每次迭代中,我们要么完全解决问题,要么贪婪地咬一口,将其减少到一个(保证的)较小的问题。

请注意,可能存在具有不同仪表位置的 other 最佳覆盖物,但是它们将使用与从该伪代码返回的仪表完全相同的仪表数目。例如,如果您将代码改编为从走廊的尽头而不是从头开始,则覆盖范围仍然不错,但是可以重新排列间隙。确实,如果您需要按字典顺序进行最小化的最佳覆盖,则应使用从末尾开始放置仪表的自适应算法:

p
相关问题