排序考试的最佳算法

时间:2012-03-16 16:47:00

标签: sorting

我是统计学课程的评分员,并以随机顺序给我一系列的纸质作业。我的部分工作是按字母顺序排列它们。我一直在使用类似于快速排序的方法,但其他评分者使用了不同的方法。我需要一种有效的排序方法,并且有正当理由,因为当我进行“大量”考试时,提供了理由。以下是我使用的一些细节:

  • 我有一个名单,其中包含我应该看到的所有名字的按字母顺序排列的列表。
  • 我不想让名字比第一个字母更像字母顺序。例如,如果“史密斯,约翰”出现在“Salk,Jonas”之前,我很好。
  • 我永远不会对300多个物品进行分类。

到目前为止,我的方法是查找班级名单的中位数最后一个字母(即:如果有60篇论文,选择与第30个人相对应的姓氏字母),将其作为支点,并将其全部放入一堆中位数以上的字母,另一堆中的所有字母。如果一个字母与中位数相同,我将它放在中间桩中。我现在对上/下中位数桩做同样的事情。当堆足够小以至于堆栈中只有三个或四个字母时,我为每个字母创建一个堆栈,然后按字母顺序将堆栈折叠成主堆栈。

是否有专门针对字母顺序设计的算法,或平均比我的方法更有效的方法?一种似乎没问题的方法是为每个字母制作一个堆栈(26堆,最坏的情况),但这会消耗很多空间,以至于一个桌面不可行。

9 个答案:

答案 0 :(得分:4)

这是一个很好的问题!我们进行了一个小实验,以便更接近答案。

我们的设置包括

  • 3个分拣机(A,B和C)。

  • 3堆40个学生问题集(每个分拣机一个)。问题集的张数介于1到5之间。这些床单是装订好的,学生姓名写在第一页的顶部。

  • 3种排序算法,按字母顺序对堆栈进行排序:

    • 插入:从未分类的桩中取出顶部物品,然后插入分拣堆中的正确位置。允许扇出分类堆。
    • 铲斗:将每个项目分为五个铲斗中的一个(A-E,F-J,K-O,P-T,U-Z)。然后使用插入排序对每个桶进行排序结合分类桶。
    • 合并:将项目分为10堆。使用插入排序对每个堆排序。将10个分类堆成5对。通过反复查看该对的顶部项目并将字母顺序较高的一个放在该对的底部,合并每一对。将10个桩合并为5个,合并5个桩中的2个,这样就剩下4个桩。然后,重复合成,直到单个排序的桩仍然存在。
  • 尺寸:

    • 排序算法完成的时间。
    • 错放物品的数量(由其他分拣机测量)。
  • 排序算法的顺序是随机的。

  • 问题集堆栈的每一轮新的回合都在分拣机之间交换,并且洗牌几分钟。

  • 分拣机A和B各进9轮,分拣机C进行3轮。

  • 在每个分拣机的桌子上放了一张带有字母和铲斗分类截止的表格。

这是我们设置的图片。

Experimental set-up (including sorters A, B and C and beautiful sunset)

以下是结果。

Experimental results

立即得出两个结论。

  1. 相对复杂的合并排序算法表现不佳。合并排序一直比排序器桶/插入排序平均值长57到125%,没有明显的准确性增益。
  2. 我们推测,首先将问题集堆栈分成10堆的初始步骤可能会导致合并排序的低迷结果。未来的研究人员可能会发现,类似合并的算法与更有效的设置程序相结合是有效的。

    1. 尽管存储桶和插入排序都表现良好,但存储桶排序比排序器中的插入排序快13到25%。这个差异对应于每个40个问题集排序节省的大约一分钟时间。
    2. 我们推测,随着要排序的问题集数量增加到40以上,并且插入排序将在30或更少的堆栈中占主导地位,铲斗排序的相对效率会提高,尽管需要更多测试。铲斗和插入件之间的准确性没有明显差异。

      最后,我们注意到我们的测试对象在排序能力方面存在重要的个体差异。分拣机B的分拣机A和C分别优于39和101秒。这表明尽管所采用的分类程序对于分选速度很重要,但是能力可以解释个体结果中方差的至少一小部分。探索是什么让德国人如此出色的分拣机是未来研究的一个有前途的领域。

答案 1 :(得分:2)

我正在寻找一些讨论人类使用算法的网站,我看到的是一种插入排序,你把它放在堆中直接放在正确的地方。订购应该是。

这种效率低下可能是因为当堆变大时必须扫描堆积以找到位置,所以我想要为此进行调整,你可以添加一个标记或某些东西作为一个特定字母位置的索引。由于除了第一个字母之外你不关心字母顺序,这基本上会使你的插入成本为O(1)

这只是我在考虑它时的一个想法,所以我自己没有真正尝试过,而且无法说出足够大的堆有多么有效。但我认为它应该可以很好地工作,因为标签可以让您即时访问要插入的位置。

答案 2 :(得分:2)

我使用桶排序。使用四个桶并再次使用另一个4桶分类对每个桶进行分类,通过暴力对每个子桶(1/16)进行排序!

答案 3 :(得分:2)

  • 将第一个字母排序为M
  • 一旦您需要> = M桩:将所有带有不匹配的开头字母的物品放在垃圾堆上
  • 在第一次运行结束时:M桩已完成
  • 使用垃圾堆中的残羹剩饭进行递归

可以调整常量M以匹配您匹配并初看多个字母的能力。 (和可用的磁盘空间)

在实践中,对于合理的M值,您不需要多次运行。 (Zipf / Pareto法)

答案 4 :(得分:2)

我的算法基于这样一个前提,即确定两个元素的正确顺序所花费的时间并不一致。例如,我很容易说A属于D之前,但是让我决定Q是否在T之前出现,反之亦然(一般来说,字母越接近字母表的末尾,并且相互之间,我更有可能在精神上背诵字母表以确定。)

鉴于此,我发现如果我将测试划分为字母"块"

,它会减少繁琐的字母朗诵。
  • 开始(A-F ish)
  • 早期中期(G-K ish)
  • 中晚期(L-P ish)
  • 结束(Q-Z ish)。这个更大,因为(a)它是我决定字母顺序最差的部门和(b)这些字母中的一些不经常开始姓氏

有重叠 - 即有时我觉得Q是中晚期,有时候我觉得它已经结束了。这有点取决于那一点上的桩有多大以及我最后排序的那封信......我的理论是,不是一直在我脑海中拼出字母表所节省的时间大于以后排序所花费的额外时间。上。

然而,到目前为止,我已经得到了这个。除了最初的分块之外,我永远无法真正决定最有效的......

答案 5 :(得分:2)

我的部门有一门基础课程,通常有500-600名学生参加考试。从小径和错误的方法似乎我们通过首先进行每个字母大约一个桶的桶排序来最快地完成排序。字母S通常可以分为两个桶,而字母(x,y,z)末尾的字母通常可以共享一个桶。然后我们通过插入排序在每个桶中进行排序,并通过堆叠桶来完成。

对于小班级(最多约30个),直接插入排序是可行的,但是当堆积增长时,找到快速插入的正确位置所需的时间就会失控。

答案 6 :(得分:1)

您的最后一段是插入排序。如果26桩是两堆,请使用24 :)。如果26桩太多,将字母表和考试分成5堆。然后对每一堆进行排序,你将有5个案例(一个有6个)。

答案 7 :(得分:0)

Quicksort可能不是最好的,因为它的效率取决于枢轴选择。无论如何,只有300次考试,我要做的就是创造26个桩(每个字母一个),并为所有考试制作一个通道,将它们放入适当的桩中

答案 8 :(得分:0)

从问题的描述中,我认为最有效的方法类似于Donald Knuth关于如何使用两种桶类别对卡片进行排序的建议:

  1. 首先将测试分配到26个桶中。
  2. 以相反的顺序收集桩,Z桩在顶部,A桩在底部。
  3. 将测试(从第2步的单个大堆的顶部开始)分配到最后一个初始的26个桶中。
  4. 按顺序收集桩,A桩在顶部,Z桩在底部。
  5. 恭喜,您的考试现在根据您的规格进行分类。排序可以在时间O(n)完成,每次测试完成两次。

    通过处理类列表,可以减少步骤1中的桶数。桶之间的边界仅用于分离共享相同的最后一个初始的第一个首字母。例如,如果类中的首字母列表是AM,BD,LD,RM,CN,BH,则只需要在第一遍中将BD与LD和AM从RM分开,因此存储桶AK和LZ就足够了第一关。然而,对于大型班级来说,桶数量的减少可能很小,并且无论如何都不会提供太多优势,因为无论如何你必须处理这一步的所有300个测试。此外,它使情况复杂化,要求计算机程序最后处理该类,并使情况不稳定,如果类列表改变则需要改变。由于你在步骤3中需要大约26个桩的空间,所以你可以在步骤1中将它们分成26堆。

    你可以让学生在进行测试时自己做第1步。