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

时间:2012-10-26 16:47:02

标签: algorithm

我获得了元素{1, 2, 3, ..., N}的排列,我必须使用交换操作对其进行排序。交换元素x,y的操作具有成本min(x,y)。

我需要找出排序排序的最低成本。我讨论了从N1的贪婪,并使用交换操作将每个元素放在它的位置上,但这不是一个好主意。

5 个答案:

答案 0 :(得分:2)

这会是最佳的吗?

Find element 2
If it is not at correct place already

    Find element at position 2
    If swapping that with 2 puts both to right place

        Swap them
        Cost = Cost + min(2, other swapped element)

repeat

   Find element 1
   If element 1 is at position 1

      Find first element that is in wrong place
      If no element found

          set sorted true

      else

         Swap found element with element 1
         Cost = Cost + 1

   else

      Find element that should go to the position where 1 is
      Swap found element with element 1
      Cost = Cost + 1

until sorted is true

答案 1 :(得分:1)

如果寻求是微不足道的,那么最小交换次数将由周期数决定。它将遵循类似于Cuckoo Hashing的原则。您在置换中获取第一个值,并查看原始索引处值的索引处的值。如果那些匹配,则交换单个操作。

[ 3 2 1]:值3在索引1处,因此请查看索引3处的值。
[3 2 1 ]:值1在索引3处,因此存在两个索引循环。交换这些值。

如果没有,将第一个索引推入堆栈并查找第二个索引值的索引。最终会有一个循环。此时,通过从堆栈中弹出值来开始交换。这将需要等于n-1的多个交换,其中n是周期的长度。

[ 3 1 2]:值3在索引1处,因此请查看索引3处的值。
[3 1 2 ]:值2在索引3处,因此将3添加到堆栈并寻找索引2.还存储3作为循环的起始值。
[3 1 2]:值1在索引2处,因此将2添加到堆栈并寻求索引1.
[ 3 1 2]:值3是循环的开始,因此从堆栈中交换弹出2并交换值1和2.
[1 3 2]:从堆栈弹出3并交换2和3,产生一个带有2个交换的排序列表。
[1 2 3]

使用此算法,最大交换数将为N-1,其中N是值的总数。当存在N个长度周期时会发生这种情况。

编辑:此算法提供最小交换次数,但不一定是使用min(x,y)函数的最小值。我没有做过数学计算,但我相信不应该使用swap(x,y)= {swap(1,x),swap(1,y),swap(1,x)}的唯一时间是当{2,3}中的x和n < 2;应该很容易把它写成一个特例。最好明确检查并放置2和3,然后按照注释中提到的算法实现两次操作的排序。

编辑2:非常确定这会抓住所有情况。

while ( unsorted ) {
    while ( 1 != index(1) )
        swap (1 , index (1) )

    if (index(2) == value@(2))
        swap (2, value@(2) )

    else
        swap (1 , highest value out of place)
}

答案 2 :(得分:0)

如果你有数字1,2,......, N 排列,那么排序集合将精确为1, 2,..., N 。因此,您知道复杂度为O(0)的答案(即您根本不需要算法)。


如果你真的想通过重复交换对范围进行排序,你可以反复“前进和循环”:在已经排序的范围内前进(a[i] == i),然后用{{a[i]交换a[a[i]] 1}}直到你完成循环。重复直到你到达终点。最多需要 N - 1个交换,它基本上执行排列的循环分解。

答案 3 :(得分:0)

嗯。一个有趣的问题。我想到的一个快速算法是使用元素作为索引。我们首先找到一个元素的索引,该元素的值为1,并将其与该数字的元素交换。最终这将以1出现在第一个位置,这意味着您必须将1与尚未处于该位置的某个元素交换,然后继续。最高位于2 * N-2,排列下限为N-1(2,3,...,N,1),但确切的成本会有所不同。

好的,考虑到上面的算法和例子,我认为最优化的是跟随交换1直到它第一次到达第一位,然后如果它已经没有到位则用第二位交换2,然后继续交换1任何尚未到位的东西,直到排序。

set sorted=false
while (!sorted) {
    if (element 1 is in place) {
        if (element 2 is in place) {
            find any element NOT in place
            if (no element found) sorted=true 
            else {
                swap 1 with element found
                cost++
            }
        } else {
            swap 2 with element at second place
            cost+=2
        }
    } else {
        find element with number equals to position of element 1
        swap 1 with element found
        cost++
    }
}

答案 4 :(得分:-1)

使用铲斗尺寸为1的铲斗分类 成本为零,因为没有发生掉期。 现在进行一个桶数组的传递,并将每个值交换回它在原始数组中的相应位置 那是N个掉期 N的总和为N(N + 1)/ 2,为您提供精确的固定成本。

不同的解释是,您只需从存储桶阵列存储回原始数组。这不是互换,因此成本为零,这是一个合理的最小值。