以最低成本对阵列进行排序

时间:2011-09-11 13:36:30

标签: algorithm sorting

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

  

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

     

湾任何交换的成本是元素值的总和,就像我交换8和4的成本是12一样,结果数组看起来像A = {4 1 2 8},它仍然是未分类的,因此需要更多的交换。

     

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

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

4 个答案:

答案 0 :(得分:4)

交换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,下一个最低元素不在其最终位置。
  4. 当完成所有这些操作后,如果一个相反的交换一个接一个地执行(例如,从第2步到第3.2步可能会发生。),删除它们。

    还有一些事情要注意,但这已经是一个非常好的近似值。第一步和第二步应始终有效,第三步是在某些边缘情况下改进的步骤。

    正在使用的算法示例:

    {8 4 5 3 2 7} :(目标阵列{2 3 4 5 7 8})

    • 步骤2:2<> 7,2< 2> 8

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

    • 3.1和3.2之间的选择:

      • 3.1给出3<>。 5,3< 5> 4

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

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

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

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

    • 你已经开始第三步了

    • 3.1和3.2之间的选择:

      • 3.1给出6<>。 9,6和6。 7,6> 8(总计:42)

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

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

答案 1 :(得分:2)

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

贪婪的算法尽管有这项工作,但你要做的就是先通过交换最便宜的算法来解决问题(找出它所属的列表中的位置)。然而,这不一定是最佳的。

只要您从不交换相同的元素两次,贪婪算法应该是最佳的。

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

如果你是一个更复杂的排序算法,那么在动态编程的同时你会遇到更多困难,所以我建议你从一个简单的慢O(n^2)排序开始。并建立在此之上。

我不想为您提供解决方案,而是想用自己的语言解释动态编程的工作原理。

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

将每个递归调用视为部分解决方案的快照。在最终的最优解决方案中,确定每个递归调用如何组合在一起是你的工作。

我建议你这样做:

  1. 编写递归排序算法
  2. 在递归函数中添加一个参数,以维护此执行路径的开销,在对数组进行排序时,添加此开销。对于任何给定点的每个可能的交换,执行另一个递归调用(这将分支您的解决方案树)
  3. 每当您意识到您正在探索的解决方案的成本超出了其他地方的成本时,请中止(只返回)。
  4. 为了能够回答您需要维护共享内存区域所需的最后一个问题,您可以根据您在递归算法中的位置进行索引。如果有一个预先计算的成本,你只需返回该值,不要继续处理(这是修剪,这使得它很快)。

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

    祝你好运!

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

要找到绝对最低成本,您必须尝试各种方式进行交换,然后找到最快的成本。

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))

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