繁体   English   中英

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

[英]Sorting a permutation with minimum cost

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

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

这会是最佳的:

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

如果搜索是微不足道的,那么最小交换次数将由周期数决定。 它将遵循类似于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)}的唯一时间当x在{2,3}和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)
}

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


如果你真的想排序反复交换的范围内,可以反复“提前和循环”:提前在已经排序范围(其中a[i] == i ),然后交换a[i]a[a[i]]直到你完成循环。 重复直到你到达终点。 这最多需要N -1次交换,并且它基本上执行置换的循环分解。

嗯。 一个有趣的问题。 我想到的一个快速算法是使用元素作为索引。 我们首先找到一个元素的索引,该元素的值为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++
    }
}

使用桶大小为1的桶排序。
成本为零,因为没有发生掉期。 现在通过bucket数组,并将每个值交换回它在原始数组中的相应位置。
这是N掉期。
N的总和为N(N + 1)/ 2,为您提供确切的固定成本。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM