【问题标题】:Partition a set into k groups with minimum number of moves以最少的移动数将集合划分为 k 个组
【发布时间】:2012-09-05 09:13:35
【问题描述】:

你有一组 n 个对象,它们给出了整数位置。对象的 是同一位置的一组对象(不一定是该位置的所有对象:单个位置可能有多个组)。对象可以向左或向右移动,目标是移动这些对象以形成 k 个组,并且移动的距离最小。

例如:

  • 初始位置为 [4,4,7],k = 3:最小成本为 0。
  • [4,4,7] 和 k = 2:最小成本为 0
  • [1,2,5,7] 和 k = 2:最小成本为 1 + 2 = 3

我一直在尝试使用贪婪的方法(通过计算哪个动作最短),但这不会奏效,因为每一步都涉及两个可以以任一方式移动的元素。我还不能制定动态编程方法,但我正在努力。

【问题讨论】:

  • 难道不是:Set::[1,2,5,9]--->分成2组:::Min Moves=1+3=4?
  • 不是真的,位置 2 会有 2 个元素.....所以 Moves=1+3*2=7
  • 为什么不能把 5 和 1 移到 2?

标签: algorithm


【解决方案1】:

让我们看看 k=1。

对于 k=1 和 n 奇数,所有点都应该移动到中心点。对于 k=1 和 n 偶数,所有点都应该移动到中心点或它们之间的任何点。我所说的“中心”是指两侧的点数,即中位数。

您可以看到这一点,因为如果您选择一个目标点 x,其右侧的点多于左侧的点,那么 x 右侧的新目标 1 将导致成本降低(除非恰好多了一个指向右侧而不是左侧,并且目标点是一个点,在这种情况下,n 是偶数,并且目标位于两个中心点上/之间)。

如果您的点已经排序,这是一个 O(1) 操作。如果不是,我相信它是 O(n)(通过顺序统计算法)。

一旦你找到了所有点都移动到的位置,就需要 O(n) 才能找到成本。

因此无论点是否排序,这都是O(n)。

【讨论】:

    【解决方案2】:

    这个问题是k-medians problem的一维实例,可以表述如下。给定一组点 x_1...x_n,将这些点划分为 k 个集合 S_1...S_k 并选择 k 个位置 y_1...y_k,以使 |x_i - y_f(i)| 的所有 x_i 的总和最小化。 ,其中 y_f(i) 是 x_i 被分配到的集合对应的位置。

    由于中位数是population minimizer for absolute distance (i.e. L_1 norm),因此每个位置 y_j 将是相应集合 S_j 中元素 x 的中位数(因此得名 k-medians)。由于您正在查看整数值,因此如果 S_j 包含偶数个元素,则中位数可能不是整数,但在这种情况下,选择高于或低于中位数的下一个整数将给出相同的总和绝对距离。

    解决 k 中位数(以及相关且更常见的k-means 问题)的标准启发式方法是迭代的,但这并不能保证产生最佳或什至好的解决方案。解决一般度量空间的 k-median 问题是 NP-hard,找到 k-median 的有效近似是一个开放的研究问题。例如,谷歌搜索“k-medians approximation”会导致一堆给出近似方案的论文。 http://www.cis.upenn.edu/~sudipto/mypapers/kmedian_jcss.pdf http://graphics.stanford.edu/courses/cs468-06-winter/Papers/arr-clustering.pdf

    在一维中,事情变得更容易,您可以使用动态编程方法。在this paper 中描述了相关一维k-means 问题的DP 解决方案,R 中的源代码在here 可用。有关详细信息,请参阅论文,但该想法与@SajalJain 提出的想法基本相同,并且可以很容易地适应解决 k-medians 问题而不是 k-means。对于 j

    D(j,m) = min (D(j-1,q) + Cost(x_{q+1},...,x_m)
    

    其中 q 的范围从 j-1 到 m-1,Cost 等于距中位数的绝对距离之和。使用Cost 的简单 O(n) 实现,这将产生一个 O(n^3k) DP 解决方案来解决整个问题。但是,这可以改进到 O(n^2k),因为 Cost 可以在恒定时间内更新,而不是每次都从头开始计算,使用以下事实:对于排序序列:

    Cost(x_1,...,x_h) = Cost(x_2,...,x_h) + median(x_1...x_h)-x_1   if h is odd
    Cost(x_1,...,x_h) = Cost(x_2,...,x_h) + median(x_2...x_h)-x_1   if h is even
    

    有关详细信息,请参阅文章。除了 Cost function 的更新不同之外,k-median 的实现与 k-means 的实现相同。 http://journal.r-project.org/archive/2011-2/RJournal_2011-2_Wang+Song.pdf

    【讨论】:

      【解决方案3】:

      任务 0 - 以非递减顺序对对象的位置进行排序

      让我们将'center'定义为shifted to.所在的对象的位置

      现在我们有两个观察结果;

      1. For N positions the 'center' would be the position which is nearest to the mean of these N positions. 例如,让 1,3,6,10 为位置。然后均值 = 5。最近的位置是 6。因此这些元素的中心是 6。这为我们提供了当所有元素需要分组为 1 组时移动成本最低的位置。

      2. 让 N 个位置“最佳”地分成 K 个组。 When N+1 th object is added,则只干扰第K组,即first K-1 groups will remain unchanged.

      根据这些观察,我们构建了一种动态规划方法。

      Let Cost[i][k] and Center[i][k] be two 2D arrays. 
      Cost[i][k] = minimum cost when first 'i' objects are partitioned into 'k' groups
      Center[i][k] stores the center of the 'i-th' object when Cost[i][k] is computed.
      

      Let {L} be the elements from i-L,i-L+1,..i-1 which have the same center.
      (Center[i-L][k] = Center[i-L+1][k] = ... = Center[i-1][k])
      这些是计算第 i 个元素时唯一需要考虑的对象(来自观察 2)

      现在

      Cost[i][k] will be 
      min(Cost[i-1][k-1] , Cost[i-L-1][k-1] + computecost(i-L, i-L+1, ... ,i))
      Update Center[i-L ... i][k]
      

      computecost() 可以通过找到中心轻松找到(来自观察 1)

      时间复杂度:

      Sorting O(NlogN)
      Total Cost Computation Matrix = Total elements * Computecost = O(NK * N)
      Total = O(NlogN + N*NK) = O(N*NK)
      

      【讨论】:

      • 观察 1 是错误的。假设你的分数是 1、2、3、4、10。平均值是 4,所以你会选择 4。这花费了 3+2+1+6=12,但是如果你选择了 3,那么成本就是 2+1 +1+7=11。事实上,如果所有点都移动到一个点,那么它应该是一个点,其两侧的点数相同。我在回答中进一步解释了这一点。
      【解决方案4】:

      据我了解,问题是:

      我们在一条线上有 n 个点。 我们想在线上放置 k 个位置。我称它们为目的地。 将n个点中的每一个移动到k个目的地之一,使距离之和最小。我把这个总和称为总成本。 目的地可以重叠。

      一个明显的事实是,对于每个点,我们应该在左边寻找最近的目的地,在右边寻找最近的目的地,然后选择最近的。

      另一个重要的事实是所有目的地都应该在点上。因为我们可以在不增加总距离的情况下将它们沿直线向右或向左移动以到达一个点。

      根据这些事实考虑以下 DP 解决方案:

      DP[i][j] 表示第一个 i 点所需的最小总成本,此时我们只能使用 j 个目的地,并且必须将一个目的地放在第 i 个点上。

      计算 DP[i][j] 将目的地固定在第 i 个点之前(我们有 i 个选择),并为每个选择(例如第 k 个点)计算第 i 个点之间所需的距离th 点和添加的新点(第 k 点)。将其与 DP[k][j - 1] 相加并找到所有 k 的最小值。

      初始状态(例如 j = 1)和最终答案的计算留作练习!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-09
        • 1970-01-01
        • 1970-01-01
        • 2018-07-28
        • 2016-01-09
        • 1970-01-01
        • 2014-12-18
        • 1970-01-01
        相关资源
        最近更新 更多