【问题标题】:Optimal 9-element sorting network that reduces to an optimal median-of-9 network?最优的 9 元素排序网络可以简化为最优的中值 9 网络?
【发布时间】:2018-01-09 05:57:27
【问题描述】:

我正在研究完全基于两个输入最小/最大操作的九个元素的排序和中值选择网络。克努特,TAOCP 卷。 3,第 2 版。声明(第 226 页)九元素排序网络需要至少 25 次比较,这意味着相同数量的 SWAP() 原语或 50 分钟/最大操作。显然,通过消除冗余操作,可以将排序网络转换为中值选择网络。传统观点似乎是,这不会产生最优的中值选择网络。虽然这似乎在经验上是正确的,但我在文献中找不到任何证据证明这必然如此。

Lukáŝ Sekanina,“中值电路的进化设计空间探索”。在:EvoWorkshops,2004 年 3 月,第 240-249 页,给出了最佳九输入中值选择网络所需的最小/最大操作数为 30(表 1)。我证实这是通过 John L. Smith 给出的著名的中值选择网络实现的,“在 XC4000E FPGA 中实现中值滤波器”。 XCELL 杂志,卷。 1996 年,第 23 期,第 23 页。 16,以及来自 Chaitali Chakrabarti 和 Li-Yu Wang 早期工作的 9 中值网络,“Novel tracking network-based architectures for rank order filters”。 IEEE 超大规模集成系统汇刊,卷。 2, No. 4 (1994), pp. 502-507,后者通过简单地消除冗余组件转换为前者。请参阅下面代码中的变体 4 和 5。

检查已发布的最佳九元素排序网络是否适合通过消除冗余操作转换为有效的中值选择网络,我设法找到的最佳版本来自 John M. Gamble 的online generator,需要 32 分钟/最大值操作,因此仅比最佳操作数少两个。这在下面的代码中显示为变体 1。其他最佳排序网络分别减少到 36 min/max 操作(变体 2)和 38 min/max 操作(变体 3)。

是否有任何已知的九元素排序网络(即具有 50 个二输入最小/最大操作)通过消除只做冗余操作?

下面的代码使用float 数据作为测试用例,因为许多处理器为浮点数据而不是整数数据提供最小/最大操作,GPU 是一个例外。由于特殊浮点操作数的问题(在我的实际用例中不会出现),最佳代码序列通常需要使用编译器提供的“快速数学”模式,例如Godbolt testbed

#include <cstdlib>
#include <cstdio>
#include <algorithm>

#define VARIANT     1
#define FULL_SORT   0

typedef float T;

#define MIN(a,b) std::min(a,b)
#define MAX(a,b) std::max(a,b)
#define SWAP(i,j) do { T s = MIN(a##i,a##j); T t = MAX(a##i,a##j); a##i = s; a##j = t; } while (0)
#define MIN3(x,y,z)  MIN(a##x,MIN(a##y,a##z))
#define MAX3(x,y,z)  MAX(a##x,MAX(a##y,a##z))
#define MED3(x,y,z)  MIN(MAX(MIN(a##y,a##z),a##x),MAX(a##y,a##z))
#define SORT3(x,y,z) do { T s = MIN3(x,y,z);  T t = MED3(x,y,z);  T u = MAX3(x,y,z); a##x=s; a##y=t; a##z=u; } while (0)

/* Use sorting/median network to fully or partially sort array of nine values
   and return the median value
*/
T network9 (T *a)
{
    // copy to scalars
    T a0, a1, a2, a3, a4, a5, a6, a7, a8;
    a0=a[0];a1=a[1];a2=a[2];a3=a[3];a4=a[4];a5=a[5];a6=a[6];a7=a[7];a8=a[8];

#if VARIANT == 1
    // Full sort. http://pages.ripco.net/~jgamble/nw.html
    SWAP (0, 1);   SWAP (3, 4);   SWAP (6, 7);   SWAP (1, 2);   SWAP (4, 5);
    SWAP (7, 8);   SWAP (0, 1);   SWAP (3, 4);   SWAP (6, 7);   SWAP (0, 3);
    SWAP (3, 6);   SWAP (0, 3);   SWAP (1, 4);   SWAP (4, 7);   SWAP (1, 4);
    SWAP (2, 5);   SWAP (5, 8);   SWAP (2, 5);   SWAP (1, 3);   SWAP (5, 7);
    SWAP (2, 6);   SWAP (4, 6);   SWAP (2, 4);   SWAP (2, 3);   SWAP (5, 6);
#elif VARIANT == 2
    // Full sort. Donald E. Knuth, TAOCP Vol. 3, 2nd ed., Fig 51
    SWAP (0, 1);   SWAP (3, 4);   SWAP (6, 7);   SWAP (1, 2);   SWAP (4, 5);
    SWAP (7, 8);   SWAP (0, 1);   SWAP (3, 4);   SWAP (6, 7);   SWAP (2, 5);
    SWAP (0, 3);   SWAP (5, 8);   SWAP (1, 4);   SWAP (2, 5);   SWAP (3, 6);
    SWAP (4, 7);   SWAP (0, 3);   SWAP (5, 7);   SWAP (1, 4);   SWAP (2, 6);
    SWAP (1, 3);   SWAP (2, 4);   SWAP (5, 6);   SWAP (2, 3);   SWAP (4, 5);
#elif VARIANT == 3
    // Full sort. Vinod K Valsalam and Risto Miikkulainen, "Using Symmetry 
    // and Evolutionary Search to Minimize Sorting Networks". Journal of 
    // Machine Learning Research 14 (2013) 303-331
    SWAP (2, 6);   SWAP (0, 5);   SWAP (1, 4);   SWAP (7, 8);   SWAP (0, 7);
    SWAP (1, 2);   SWAP (3, 5);   SWAP (4, 6);   SWAP (5, 8);   SWAP (1, 3);
    SWAP (6, 8);   SWAP (0, 1);   SWAP (4, 5);   SWAP (2, 7);   SWAP (3, 7);
    SWAP (3, 4);   SWAP (5, 6);   SWAP (1, 2);   SWAP (1, 3);   SWAP (6, 7);
    SWAP (4, 5);   SWAP (2, 4);   SWAP (5, 6);   SWAP (2, 3);   SWAP (4, 5);
#elif VARIANT == 4
    // Chaitali Chakrabarti and Li-Yu Wang, "Novel sorting network-based 
    // architectures for rank order filters." IEEE Transactions on Very
    // Large Scale Integration Systems, Vol. 2, No. 4 (1994), pp. 502-507
    // sort columns
    SORT3 (0, 1, 2);
    SORT3 (3, 4, 5);
    SORT3 (6, 7, 8);
    // sort rows
    SORT3 (0, 3, 6);  // degenerate: MAX3 -> a6
    SORT3 (1, 4, 7);  // degenerate: MED3 -> a4
    SORT3 (2, 5, 8);  // degenerate: MIN3 -> a2
    // median computation
    SORT3 (2, 4, 6);  // degenerate: MED3 -> a4 has rank 4
#elif VARIANT == 5
    // John L. Smith, "Implementing median filters in XC4000E FPGAs", 
    // XCELL magazine, Vol. 23, 1996, p. 16
    SORT3 (0, 1, 2);
    SORT3 (3, 4, 5);
    SORT3 (6, 7, 8);
    a3 = MAX3 (0, 3, 6);  // a3 has rank 2,3,4,5,6
    a4 = MED3 (1, 4, 7);  // a4 has rank 3,4,5
    a5 = MIN3 (2, 5, 8);  // a5 has rank 2,3,4,5,6
    a4 = MED3 (3, 4, 5);  // a4 has rank 4
#else 
#error unknown VARIANT
#endif

#if FULL_SORT
    // copy back sorted results
    a[0]=a0;a[1]=a1;a[2]=a2;a[3]=a3;a[4]=a4;a[5]=a5;a[6]=a6;a[7]=a7;a[8]=a8;
#endif

    // return median-of-9
    return a4;
}

【问题讨论】:

    标签: algorithm median sorting-network


    【解决方案1】:

    我不确定这是否符合您正在寻找的所有标准,但这里有一种方法可以将变体 5 转换为 25 交换、50 分钟/最大排序网络,然后将其缩减为30 分钟/最大中值选择网络:

    我们从使用三个 SORT3、一个 MAX3、一个 MIN3 和两个 MED3 的中值选择网络(John L. Smith,1996)开始:

    我们把MAX3、MIN3、MED3全部改成SORT3,加上4个SWAP,得到一个完整的排序网络:

    (最后我们不需要对三元组 1,2,3 和 5,6,7 进行全排序,因为 2 不能同时小于 1 和 3,并且 6 不能同时大于 5和 7.)

    当我们用 SWAP 替换 SORT3 时,我们得到了这个标准的 25-swap 排序网络:

    然后我们可以将其简化为这个 30 分钟/最大的中值选择网络:

    MIN = Math.min; MAX = Math.max;
    
    function sortingNetwork9(a) {        // 50x min/max
        swap(0,1); swap(3,4); swap(6,7);
        swap(1,2); swap(4,5); swap(7,8);
        swap(0,1); swap(3,4); swap(6,7);
        swap(0,3); swap(3,6); swap(0,3);
        swap(1,4); swap(4,7); swap(1,4);
        swap(5,8); swap(2,5); swap(5,8);
        swap(2,4); swap(4,6); swap(2,4);  
        swap(1,3); swap(2,3);
        swap(5,7); swap(5,6);
    
        function swap(i,j) {var tmp = MIN(a[i],a[j]); a[j] = MAX(a[i],a[j]); a[i] = tmp;}
    }
    function medianSelection9(a) {       // 30x min/max
        swap(0,1); swap(3,4); swap(6,7);
        swap(1,2); swap(4,5); swap(7,8);
        swap(0,1); swap(3,4); swap(6,7);
         max(0,3);  max(3,6);  // (0,3);
        swap(1,4);  min(4,7);  max(1,4);
         min(5,8);  min(2,5);  // (5,8);
        swap(2,4);  min(4,6);  max(2,4);  
         // (1,3);  // (2,3);
         // (5,7);  // (5,6);
    
        function swap(i,j) {var tmp = MIN(a[i],a[j]); a[j] = MAX(a[i],a[j]); a[i] = tmp;}
        function min(i,j) {a[i] = MIN(a[i],a[j]);}
        function max(i,j) {a[j] = MAX(a[i],a[j]);}
    }
    var a = [5,7,1,8,2,3,6,4,0], b = [5,7,1,8,2,3,6,4,0];
    sortingNetwork9(a);
    medianSelection9(b);
    document.write("sorted: " + a + "<br>median: " + b[4]);

    【讨论】:

    • 所提议的排序网络如何“减少到最优的九输入中值选择网络(具有 30 个二输入最小/最大操作)仅通过消除冗余操作 “?从 Knuth-graph 表示来看,它看起来会简化为具有 36 两个输入最小/最大操作的中值选择网络?
    • @njuffa 仅当您将其转换为使用 3 操作数交换时才会这样做,因此它可能不是您想要的。
    • 我不确定您所说的三操作数交换是什么意思。正如问题所述,迄今为止最好的解决方案是变体 1,当从排序到中值网络时,它减少到 32 次最小/最大操作。我仍在我的测试脚手架中测试你的网络,看起来它实际上可能会减少到比图表所暗示的更少的操作,即它看起来很有希望。但我需要确保自己不会因为过快地检查这一点而感到困惑。在我做出最终裁决之前,我会花一些时间处理你的提议。
    • 有效!这是编译器资源管理器(godbolt)的链接以进行说明。当构建为sorting network 时,有 50 次最小/最大操作;但是当编译为extract the median 时,有 30 次最小/最大操作。我在我的测试脚手架中测试了这个函数,以确保它正常工作。
    • 我认为答案很好。您从最佳中值选择网络开始并添加最少数量的交换以使其成为完整排序网络的想法是解决我显然无法解决的问题的好方法;我太专注于相反的方向。逐步解释您的工作的图表也很棒。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2013-03-29
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多