【问题标题】:Circular clustering with fixed length固定长度的圆形聚类
【发布时间】:2013-06-21 09:14:56
【问题描述】:

假设我有一个循环时间线(24 小时周期),在这 24 小时内有 n 个点。我想以给定的固定长度 k (

如果我们不允许间隔“环绕”,那么它变得容易(我们可以简单地贪婪地安排第一个间隔从第一个点开始,覆盖尽可能多的点并为下一个间隔选择下一个点等等)。

一个天真的二次解决方案是尝试将每个点作为“第一个”区间的起点并按照上述方式进行操作,但我觉得我们可以做一些更聪明的事情?

【问题讨论】:

  • 一个可能微不足道的问题:是否允许间隔重叠?如果 24/k 不是整数且区间不能重叠且所有区间的长度 k 相同,则可能无解。
  • 哦,是的,如果需要,它们可以重叠。
  • 我的直觉是,在点之间最长的空白间隙的端点之一开始第一个间隔的贪婪方法应该是最佳的,但我很难想出一个证明。任何人都有任何有助于证明/反驳的见解?

标签: algorithm scheduling intervals


【解决方案1】:

请注意您建议的朴素二次解法:您需要将每个点视为区间开始或区间结束。


我不确定这是不是最优解,但它比朴素的二次方要好:

让我们为点命名{P1, ..., Pn}。

由于任何点都必须被至少一个区间所覆盖,因此找到所有可能覆盖点 P1 的区间(假设一个区间要么从 Pi 开始,要么在 Pi)。对于这些间隔中的每一个,贪婪地继续,就像在线性时间线上一样。

为了进一步优化它,我们需要找到最好的起点,而不是从 P1 开始——这将是可以被最小数量的间隔覆盖的点。我不知道我们是否可以在线性时间内做到这一点,但一个好的启发式方法可能是从它与两个邻居的距离之和最大这一点开始。

编辑:寻找最佳起点的 O(nlogn) 方法:

我们可以建立一个可能的 2n 个段的列表(对于任何点 Pi,一个间隔可以从 Pi 开始或在 结束>Pi)。接下来,将这些间隔插入segment tree。

不要使用常规的段树,而不是将区间存储在规范子集中,只需存储它们的数量(参见 Wikipedia 文章中的注释部分)。

树的构建需要 O(nlogn) 时间。现在,对于每个点 Pi,计算它落入的段数(区间)。每个点需要 O(logn),或者总共需要 O(nlogn)。

选择间隔数最少的点。如上所述,对于每个区间继续使用贪心方法。

【讨论】:

    【解决方案2】:

    简单的答案是……约束规划:

    1. 给你一组 P 点(比如从午夜开始的分钟数)和 k 间隔长度
    2. 你想要长度为 k 的最小间隔数(一组 S,表示间隔的开始),使得

      一个。对于所有 p elem P,在 S st p >= s && p

      b.对于所有 S 不存在 S' st,S' 中的元素数小于 S 中的元素数。换句话说,结果集具有最小基数。

    将它输入到 gecode...你就完成了。

    区间有多种可能的表示形式,K Apt 的《约束编程原理》一书中很好地解释了这些权衡。

    【讨论】:

      【解决方案3】:

      也许您可以使用空间填充曲线和带有四键的层次聚类。有一个法国网站按照空间填充曲线排序日子:http://lapin-bleu.net/riviera/?p=78。但是二次算法的问题是什么?

      【讨论】:

      • 其实,我只是觉得应该更容易找到最佳起点。提议的解决方案可能有效,但我觉得它们对我来说太复杂了,因为我可能不必处理那么多问题。可能只是做二次方。
      • 空间填充曲线不是无用,而是困难。在东部,它将复杂性降低了一个维度。
      猜你喜欢
      • 1970-01-01
      • 2012-11-12
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 2013-07-19
      • 2019-02-26
      • 2020-03-29
      相关资源
      最近更新 更多