我在分拣机上工作,为了使复杂性最小化,我想将移动部件的数量减至最少。我来了以下设计:
机器的目标是从输入堆栈中取出所有项目,并最终将它们全部按排序顺序移至输出堆栈。第二个目标是将“堆栈退货”的数量减少到最少,因为在我的机器中,这是需要用户干预的部分。理想情况下,机器应在没有用户帮助的情况下尽可能多地进行排序。
我遇到的问题是我似乎找不到合适的算法来进行实际排序。我能找到的几乎所有算法都依赖于能够交换任意元素。分发/外部排序似乎很有希望,但是我发现的所有算法似乎都依赖于一次访问多个输入。
由于机器已经知道所有项目,因此我可以利用这一优势,对所有项目进行“内存中”排序。我尝试了从未排序状态到已排序状态的“寻路”,但是我无法使它真正收敛于解决方案。 (通常只是卡在一个循环中,来回移动堆栈。)
最好,我希望有一个至少可以使用2个输出堆栈的解决方案,但是如果有可用的话,可以使用更多的堆栈。
有趣的是,这是可以使用标准扑克牌玩的“游戏”:
答案 0 :(得分:1)
这可以通过将输出返回到输入的O(log(n))
来完成。更准确地说,如果2 ceil(log_2(n)) - 1
返回1 < n
。
让我们调用输出堆栈A和B。
首先考虑最简单的算法。我们遍历它们,将最小的卡片放在B上,将其余的卡片放在A上。然后将A放在输入上并重复。 n
通过后,您将获得按排序的顺序。效率不高,但是可以。
现在我们可以做到了,这样每张通行证可以抽出2张卡吗?好吧,如果我们在上半部有卡1、4、5、8、9、12,...,其余在下半部,那么第一遍将在卡2之前找到卡1,将它们反向,第二遍则找到卡3之前的卡3,将它们反转,依此类推。每张通行证2张。但是通过1次返还2次返回,我们可以将所需的所有卡放在堆栈A的上半部分,其余的放在堆栈B上,返回堆栈A,返回堆栈B,然后开始提取。这需要2 + n/2
次通过。
每张通行证有4张卡片怎么样?好吧,我们希望将其分为几个部分。上四分之一有纸牌1、8、9、16...。第二个四分之一有纸牌2、7、10、15...。第三个四分之一有3、6、11、14,...。最后一个有4、5、12、13...。基本上,如果您要对它们进行交易,则按顺序对前四个进行交易,对第二个按相反顺序进行交易,对后一个按顺序进行交易。
我们可以将它们分为2个季度。我们能弄清楚如何到达那里吗?倒退,在第二遍之后,我们希望A具有2,1的四分之一。和乙有宿舍4,3。然后我们返回A,返回B,我们很成功。因此,在第一遍之后,我们希望A具有2,4的四分之一,而B具有1,3的四分之一,返回A返回B。
转过来工作,在第1遍中,将组2,4放在A上,在B上1,3。返回A,返回B。然后在第2遍中,我们将组1,2放在A,3,4上在B上,返回A,然后返回B。然后我们开始进行交易,每遍通过4张牌。因此,现在我们使用4 + n/4
返回。
如果继续进行逻辑运算,则在3次通过(6次返回)中,您可以弄清楚如何在提取阶段每次获得8张卡。在4张通行证(8张回程)中,每张通行证可获得16张卡。等等。逻辑很复杂,但是您要做的就是记住要让它们按顺序结束... 5,4,3,2,1。从最后一遍倒退到第一遍,弄清楚您必须如何完成了。然后您有了正向算法。
如果您玩数字游戏,如果n
是2的幂,则同样可以很好地获得log_2(n) - 2
和2 log_2(n) - 4
的通行证,然后获得4
的提取通行证与3
之间的退回,以获得2 log_2(n) - 1
返回,或者如果您接受log_2(n) - 1
返回的2 log_2(n) - 2
传递,然后2
返回的1
抽取传递它们之间的2 log_2(n) - 1
返回。 (当然,这是假设n
足够大,可以将其进行除法。对于第二版算法,其含义为“非1”。)我们很快就会看到一个较小的理由偏爱使用如果是2 < n
,则为该算法的旧版本。
好的,如果您获得2的幂的倍数,这很好。但是,如果您有10张卡怎么办?插入假想卡,直到我们达到最接近的2的幂为止。我们为此遵循算法,只是不实际执行虚卡上的操作,除了虚卡不存在外,我们会得到应有的准确结果。
因此,我们有一个不超过2 ceil(log_2(n)) - 1
个退货的一般解决方案。
现在我们知道为什么更喜欢将其分成4个组而不是2个。如果我们分成4个组,则第4个组可能只是虚构的牌,而我们又跳过了另一组。如果我们分成两组,那么每个组中总是有真实的牌,并且我们就无法保存回报。
如果n为3, 5, 6, 9, 10, 11, 12, 17, 18, ...
,这会使我们加快1。
计算确切的规则将变得很复杂,我不会尝试编写代码来做到这一点。但是您应该可以从这里弄清楚。
我无法证明这一点,但是就卡的排列而言,您可能无法做得更好,因此该算法可能是最优的。 (当然,可以使用此算法克服一些排列。例如,如果我将所有内容反向传递,则将它们全部提取都比该算法要好。)但是,我希望找到针对给定排列的最佳策略是一个不错的选择。 NP完全问题。