【问题标题】:Sorting an array in minimum cost以最低成本对数组进行排序
【发布时间】:2011-09-11 13:36:30
【问题描述】:

我有一个包含 4 个元素 A={ 的数组 A[] 8 1 2 4}。如何以最小的成本对其进行排序。标准定义如下-

一个。可以交换任意 2 个元素。

b.任何交换的成本都是元素值的总和,如果我交换 8 和 4,成本是 12,结果数组看起来像 A={4 1 2 8},它仍然是未排序的,所以需要更多的交换。

c。需要找到一种方法以最小的成本对数组进行排序。

根据我的观察,贪婪是行不通的,就像在每一步中,以最小的成本将任何元素放在数组中的排序位置。所以需要一个DP解决方案。 有人可以帮忙吗??

【问题讨论】:

  • 我看不到如何构建 DP 解决方案。没有明显的方法可以将其分解为子问题。但是,我可以在搜索问题方面看到解决方案。不过,这将是一次详尽的搜索。
  • 这是一种计算“成本”的有趣方式
  • 真的没有DP方案吗???
  • 元素值为正且小于1000,元素个数最大可达1000。
  • 我没有看到任何空间限制...所以算法可以是 O(n) 并创建一个单独的索引? (它需要创建一个与 A 大小相同的 B 数组)

标签: algorithm sorting


【解决方案1】:

交换 2 和 1,然后交换 1 和 4,然后交换 1 和 8?还是一般性问题?

对于更通用的方法,您可以尝试:

  1. 如果它们是完美的交换,则交换每对 2 个元素(总和最高)(即交换它们会使它们都在正确的位置)。时间

  2. 使用最低元素作为交换的枢轴(通过交换它所占据的位置的元素),直到它到达其最终位置

  3. 那么,你有两种可能:

    1. 重复第 2 步:使用不在其最终位置的最低元素作为枢轴,直到它到达其最终位置,然后返回第 3 步

    2. 或者将不在其最终位置 (l2) 的最低元素与最低元素 (l1) 交换,重复步骤 2 直到 l1 到达 l2 的最终位置。然后:

      1. 再次交换 l1 和 l2,转到步骤 3.1
      2. 或者再次转到步骤 3.2,使用不在其最终位置的下一个最低元素。

当所有这些都完成后,如果一些相反的交换一个接一个地执行(例如它可能发生在从第 2 步到第 3.2 步),请将它们删除。

还有一些需要注意的地方,但这已经是一个很好的近似值。第一步和第二步应该始终有效,但在某些临界情况下,第三步将是改进的一步。

使用的算法示例:

使用 {8 4 5 3 2 7}:(目标数组 {2 3 4 5 7 8})

  • 第2步:2 7, 2 8

  • 数组现在是 {2, 4, 5, 3, 7, 8}

  • 在 3.1 和 3.2 之间进行选择:

    • 3.1 给出 3 5, 3 4

    • 3.2 给出 2 3, 2 5, 2 4, 2 3

    • 3 5, 3 4 是更好的结果

结论:2 7, 2 8, 3 5, 3 4 是最好的答案。

使用 {1 8 9 7 6}(结果数组 {1 6 7 8 9})

  • 你已经从第三步开始了

  • 在 3.1 和 3.2 之间进行选择:

    • 3.1 给出 6 9, 6 7, 6 8(总计:42)

    • 3.2 给出 1 6, 1 9, 1 7, 1 8, 1 6(总计:41)

所以 1 6, 1 9, 1 7, 1 8, 1 6 是最好的结果

【讨论】:

  • 我对你的答案理解有问题,如果你举个例子会更好。假设 A={8 4 5 3 2 7} 。
  • 第 1 步看起来不错,很有帮助。但是与最低元素交换不会产生最佳答案。
  • 第 1 步看起来不错,很有帮助。但是与最低元素交换不会产生最佳答案。假设 A={1,8,9,7,6}-lowes 元素交换是 {8,6} 所以成本=14,结果 A={1,6,9,7,8},下一个交换{7, 9} cost=(14)+16=30 , next swap {8,9}=17 所以总成本=30+17=47.其中最优解是 42。
  • 你的源数组是 8 4 5 3 2 7,你的目标是 2 3 4 5 7 8。所以:用 7 交换 2,用 8 交换 2。现在你在第 3 步。你有数组 [2 4 5 3] 转换为 [2 3 4 5]。所以你可以选择交换 3 和 5,然后是 3 和 4;或再次交换 2 和 3、2 和 5、2 和 4、2 和 3。除非我错过了算法给出的 2 7, 2 8, 3 5, 3 4,看起来还不错。
  • 大约 1 8 9 7 6。您已经从第 3 步开始了。因此,在这种情况下,您应该选择步骤 3 的第二个选项:将最低元素 (1) 与不在其最终位置 (6) 的最低元素交换,继续,然后将它们交换回来。 16、19、17、18、16,成本:40。
【解决方案2】:

这闻起来像家庭作业。您需要做的是对数组进行排序,但这样做的同时最大限度地降低交换成本。所以,这是一个优化问题,而不是排序问题。

尽管有这项工作,但贪心算法会通过首先交换最便宜的(找出它属于列表中的哪个位置)来修复解决方案。然而,这不一定是最佳的。

只要你从不交换同一个元素两次,贪心算法应该是最优的。

无论如何,回到动态编程的内容,只需使用递归构建解决方案树,然后在找到更优化的解决方案时修剪树。这是非常基本的递归。

如果您使用更复杂的排序算法,您将很难将其与动态编程一起使用,因此我建议您从简单、缓慢的O(n^2) 排序开始。并以此为基础。

比起给你提供解决方案,我想用我自己的话来解释一下动态编程是如何工作的。

  • 您需要做的第一件事是找出一种能够探索所有可能解决方案的算法(这可能是一个非常愚蠢的蛮力算法)。
  • 然后您可以使用递归来实现这一点,因为动态编程的基础是能够快速找出重叠的子问题,因此递归。
  • 在每次递归调用时,您都会查找您在解决方案中的位置,并检查您之前在哪里计算过解决方案树的这一部分,如果您这样做了,您可以测试当前解决方案是否更优化,如果是,那么你继续,否则你已经完成了问题的这个分支
  • 当您得出最终解决方案时,您将解决问题。

将每个递归调用视为部分解决方案的快照。您的工作是弄清楚每个递归调用如何在最终的最佳解决方案中组合在一起。

我建议你这样做:

  1. 编写递归排序算法
  2. 向您的递归函数添加一个参数,以维护此执行路径的成本,当您对数组进行排序时,添加到此成本。对于任何给定点的每一个可能的交换,做另一个递归调用(这将分支你的解决方案树)
  3. 当您意识到您当前正在探索的解决方案的成本超过了您在其他地方已有的成本时,请放弃(直接返回)。

为了能够回答最后一个问题,您需要维护共享内存区域,您可以根据递归算法在其中建立索引。如果那里有预先计算的成本,您只需返回该值而不继续处理(这是修剪,这使它更快)。

使用这种方法,您甚至可以将您的解决方案基于置换蛮力算法,它可能会非常缓慢或占用大量内存,因为当您分支时它是愚蠢的修剪,但您并不需要特定的排序算法来完成这项工作,这样做会更有效率。

祝你好运!

【讨论】:

  • 事实上,我正在寻找一个表格解决方案,而不是 bruteforce+ pruning 。是不是不能得到一个最优子问题导致最优解??
  • 表格是什么意思?使用蛮力算法是最容易开始的事情,如果你使用更多的切割器,那么你将拥有一个更快但更复杂的算法。
  • 是的,蛮力比较容易,但它的时间复杂度是多少。它适用于 1000 元素吗??
  • 如果您计算的第一个解决方案是最优的,或者是一个很好的近似值,那么蛮力并不慢。这就是为什么动态规划和适当的近似可以用来快速解决问题的原因,尽管初始搜索算法在很大程度上只是蛮力。
【解决方案3】:

如果你做一个高-低选择排序,你可以保证第 N 个最大的元素不会被交换超过 N 次。这是一个简单的算法,具有非常简单和诱人的保证……也许可以通过几个例子来检查一下,看看如何调整它。注意:这可能不会导致最佳答案...

【讨论】:

    【解决方案4】:

    要找到绝对最低的成本,您必须尝试所有交换方法,然后找到最快的。

    def recsort(l, sort):
      if sorted(l2):
        if min>cost:
          cost=min
          bestsort=sort
      if(len(sort) > len(l)*len(l)): //or some other criteria
        return
    
      for p1 in (0,len(l)):
        for p2 in (0,len(l)):
          cost += l[p1] + l[p2]
          l2 = swap(l, p1,p2)
          if cost<min:
            recsort(l2, append sort (p1,p2))
    

    一种非常好的方法是递归地将最大的值放在顶部。

    【讨论】:

    • 是什么让你说你必须尝试所有方法?这种说法需要证明。
    • 是的。这是一个 NP 与 P 的问题,因此无法证明。对不起,我不是指所有方式,而是非多项式数量的方式。此处描述的所有其他算法都是 NP 中的搜索算法。
    • 证明某事是 NP 是可行的。这就是你必须做的。
    • 这意味着我必须证明 P 中没有算法可以解决这个问题,这是不可能的吗?我只能证明一个算法在 NP 中,而不是一个问题。
    • 如果我们将问题重述为:有多项式数量的解决方案,找到最快的。它们没有内在的顺序,因此需要检查它们的 NP 数量,因此问题是 NP 难的。现在我只需要证明它们没有内在的顺序......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 2016-07-03
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多