Algorithm 在阵列中均匀放置不同的项目

Algorithm 在阵列中均匀放置不同的项目,algorithm,sorting,standard-deviation,deviation,Algorithm,Sorting,Standard Deviation,Deviation,我想知道是否有可能以某种方式对数组中的项进行“排序”,以使它们的间隔“相等” 一个例子是数百个单词,因此: Apple - 1 Banana - 2 Pineapple - 3 Orange - 4 这是一个数组: [ 'Apple', 'Apple', 'Banana', 'Pineapple', 'Pineapple', 'Pineapple', 'Orange' ] [ 1, 1, 2, 3, 3, 3, 4 ] 我想要达到的目标与此类似: [ 'Apple', 'Pineapple'

我想知道是否有可能以某种方式对数组中的项进行“排序”,以使它们的间隔“相等”

一个例子是数百个单词,因此:

Apple - 1
Banana - 2
Pineapple - 3
Orange - 4
这是一个数组:

[ 'Apple', 'Apple', 'Banana', 'Pineapple', 'Pineapple', 'Pineapple', 'Orange' ]
[ 1, 1, 2, 3, 3, 3, 4 ]
我想要达到的目标与此类似:

[ 'Apple', 'Pineapple', 'Banana', 'Apple', 'Pineapple', 'Orange', 'Pineapple' ]
[ 1, 3, 2, 1, 3, 4, 3 ] 
通过此转换,
菠萝
在其他“菠萝”和
Apple
之间有1个项目偏移,苹果位于[0]和[3]位置


在开始实施之前,我正在寻找一种已经发明的解决方案——它应该与标准偏差有关?

首先,按出现次数对单词进行排序。然后对它们进行迭代,首先填充所有偶数索引,然后填充所有奇数索引。
第一个单词最多可以填充所有偶数索引。在大多数现代阵列中,索引为偶数的插槽的数量应至少与索引为奇数的插槽的数量相同。如果您的语言不符合该条件(即基于一的数组),请根据可用插槽的数量选择偶数或奇数。
第二个最常见的单词最多只能出现与最常见的单词相同的次数,因此同一个单词不可能以这种方式出现在相邻的两个插槽中。
简单的python实现如下所示:

import math

def spaced_ordering(words):
    words = sorted(words, key=words.count, reverse=True)
    output = [None] * len(words)

    for i in range(0, math.ceil(len(words) / 2)):
        output[i * 2] = words[i]

    for i in range(0, math.floor(len(words) / 2)):
        output[i * 2 + 1] = words[math.ceil(len(words) / 2) + i]

    return output

注意:上述实现既不完全是性能的,也不完全是花哨的,也不包括检查有效输入(例如,如果一个单词出现超过
math.ceil(len(words)/2)
次,会发生什么情况)。它仅用于演示基本原理。

您正在寻找的算法类别称为多路复用。多路复用器接收多个输入流,并创建单个输出流,每次从输入中选择一个项目。有许多不同的多路复用策略。我将描述一个易于实现且性能良好的

一般的想法是,每个项目都有一个名称比率累加器,然后选择累加器中值最大的项目。在问题中给出的示例中,比率为苹果2,香蕉1,菠萝3,橘子1。费率之和为期间,即7

该算法的操作如下:

initialize all accumulators to 0
for each slot in one period:
    choose the item with the largest accumulator, and add it to the output
    update each accumulator by adding the rate to the accumulator
    subtract the period from the accumulator of the chosen item
下表显示了算法的进展情况。插槽标记为S1至S7。对于每个插槽,有两列数字、每个项目的累加器值和累加器的调整

在插槽1中,选择橙色,因此累加器的调整为
+1-7=-6
(加上速率,减去周期)。对于其他项目,调整等于费率。请注意,所有蓄能器都从0开始,在第七个插槽后返回0。因此,该算法可以针对任意数量的插槽运行,并且只需重复相同的模式即可

 Name    Rate  __S1__   __S2__   __S3__   __S4__   __S5__   __S6__   __S7__
Orange    1/7   0  -6   -6  +1   -5  +1   -4  +1   -3  +1   -2  +1   -1  +1   0
Banana    1/7   0  +1    1  +1    2  +1    3  -6   -3  +1   -2  +1   -1  +1   0
Apple     2/7   0  +2    2  +2    4  -5   -1  +2    1  +2    3  -5   -2  +2   0
Pineapple 3/7   0  +3    3  -4   -1  +3    2  +3    5  -4    1  +3    4  -4   0

Selected item: Orange    Pine     Apple   Banana    Pine     Apple    Pine
下面是Python的一个实现:

items = ['Apple', 'Apple', 'Banana', 'Pineapple', 'Pineapple', 'Pineapple', 'Orange']

# Convert the list of items into a list that contains the [name, rate, accumulator]
# for each item. The initial value for the accumulator is 0
counts = {}
for item in items:
    counts[item] = counts.get(item, 0) + 1
rates = counts.items()
rates = [[name, rate, 0] for (name, rate) in rates]
rates.sort(key=lambda x:x[1])

# Run the multiplexer, which
#    adds the item with the largest accumulator to the output
#    updates all the accumulators by adding the rate to the accumulator
#    subtracts the period from the chosen accumlator
output = []
period = len(items)
for i in range(period):
    best = 0
    for j in range(len(rates)):
        if rates[j][2] > rates[best][2]:  # compare accumulators
            best = j
        rates[j][2] += rates[j][1]        # update accumulator
    rates[best][2] -= period
    output.append(rates[best][0])         # add an item to the output

print output  # ['Orange', 'Pineapple', 'Apple', 'Banana', 'Pineapple', 'Apple', 'Pineapple']

随机洗牌对你有用吗?到目前为止你都尝试了什么?请展示你的onw代码,这样人们就更容易发现你的错误。看起来这正是我想要的,只需要将算法重写为JS:)谢谢!我正在寻找网络中的
多路复用
算法,但是有很多例子,也许这个问题有一个具体的多路复用名称?你的
项目的算法=['橙色','橙色','苹果','香蕉','香蕉','香蕉']
在某种程度上消除了橙色的第二次出现,制造了更多的苹果,这是故意的吗?@JohnDoe这个多余的苹果是个虫子。我已经更新了答案。这是我一直在寻找的东西,你是自己计算出来的还是基于某种算法的?@JohnDoe我是自己想出来的。