我有一个数组A [],其中包含4个元素A = { 8 1 2 4}。如何以最小的成本对其进行排序。标准定义如下 -
一个。可以交换任何2个元素。
湾任何交换的成本是元素值的总和,就像我交换8和4的成本是12一样,结果数组看起来像A = {4 1 2 8},它仍然是未分类的,因此需要更多的交换。
℃。需要找到一种以最低成本对数组进行排序的方法。
根据我的观察,贪婪将不起作用,就像在每一步中将任何元素以最小成本放置在数组中的排序位置。因此需要DP解决方案。 任何人都可以帮忙吗?
答案 0 :(得分:4)
交换2和1,然后是1和4,然后是1和8?或者这是一般性问题?
对于更通用的方法,您可以尝试:
如果它们是完美的交换,则交换每对2个元素(具有最高总和)(即交换它们将使它们都在它们的正确位置)。个
使用最低元素作为交换的轴心(通过交换其占据点的元素),直到它到达最终点
然后,您有两种可能性:
重复步骤2:使用不在最终位置的最低元素作为枢轴,直到它到达最终位置,然后返回步骤3
或者将最终点(l2)中的最低元素与最低元素(l1)交换,重复步骤2直到l1到达l2的最终点。然后:
当完成所有这些操作后,如果一个相反的交换一个接一个地执行(例如,从第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)
排序开始。并建立在此之上。
我不想为您提供解决方案,而是想用自己的语言解释动态编程的工作原理。
将每个递归调用视为部分解决方案的快照。在最终的最优解决方案中,确定每个递归调用如何组合在一起是你的工作。
我建议你这样做:
为了能够回答您需要维护共享内存区域所需的最后一个问题,您可以根据您在递归算法中的位置进行索引。如果有一个预先计算的成本,你只需返回该值,不要继续处理(这是修剪,这使得它很快)。
使用这种方法,您甚至可以将解决方案基于置换暴力算法,它可能会非常慢或占用内存,因为当您分支或时它是愚蠢的修剪,但你真的不需要一个特定的排序算法来使这个工作,这样做会更有效率。
祝你好运!答案 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))
一种非常好的方法是递归地将最大值放在顶部。