元素混合算法

时间:2013-02-20 19:37:19

标签: algorithm mixing

不确定标题。

这就是我需要的。

让我们举例说明这套元素有20 * A,10 * B,5 * C,5 * D,2 * E,1 * F 我需要混合它们,因此彼此之间没有两个相同的元素,我也可以说我不希望B和C彼此相邻。元素必须均匀分布(如果有2个E应该接近开始/在第一个半个和第二个近端/在后半部分。元素的数量当然可以改变。

我还没有做过这样的事情。是否有一些这种算法的知识库,我可以找到一些提示和方法来解决这类问题,还是我必须自己做所有的数学运算?

3 个答案:

答案 0 :(得分:1)

我认为解决方案非常简单。

首先将数组x初始化为empty值,以便为每个项目添加一个空格。

然后,对于频率降序的每个(item, frequency)对,请在从第一个item广告位开始的交替广告位中将x值分配给empty

以下是它适用于您的示例的方式:

20*A    A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A
10*B    ABABABABABABABABABABA_A_A_A_A_A_A_A_A_A
 5*C    ABABABABABABABABABABACACACACACA_A_A_A_A
 2*E    ABABABABABABABABABABACACACACACAEAEA_A_A
 1*F    ABABABABABABABABABABACACACACACAEAEAFA_A

此时我们失败了,因为x仍然有一个空插槽。请注意,我们可以从一开始就识别出这一点,因为我们需要在A之间至少有19个插槽,但我们只有18个其他项。

<强>更新

Leonidas现在已经解释过这些项目应该“均匀”分配(也就是说,如果我们有k个特定类型的项目,并且有n个槽要填充,那么n / k槽的每个“桶”必须包含一个项目那种。

我们可以通过分配我们的分配来适应这种约束,而不是简单地选择交替的时隙。在这种情况下(假设我们可以解决2 Fs),我们就可以了

20*A    A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A_A
10*B    ABA_ABA_ABA_ABA_ABA_ABA_ABA_ABA_ABA_ABA
 5*C    ABACABA_ABACABA_ABACABA_ABACABA_ABACABA
 2*E    ABACABAEABACABA_ABACABAEABACABA_ABACABA
 2*F    ABACABAEABACABAFABACABAEABACABAFABACABA

答案 1 :(得分:0)

您可以递归地解决此问题:

def generate(lastChar, remDict):
    res = []
    for i in remDict:
        if i!=lastChar):
            newRemDict = remDict
            newRemDict[i]-=1
            subres = generate(i,newRemDict)
            res += [i+j for j in subres]
    return res

请注意,我遗漏了角落条件和许多需要完成的检查。但只显示了核心递归。如果超过半数+ 1的剩余字母是同一个字母,您也可以退出追求分支。

答案 2 :(得分:0)

我遇到了类似的问题,在评估了各种指标之后,我想出了抓住第一个项目的想法,通过源数组的比例小于通过结果数组的比例。有一种情况是所有这些值都可以表示为1,例如在合并一组偶数数组的中途 - 一切都完成了一半 - 所以我在这种情况下从第一个数组中获取了一些东西。

此解决方案确实使用了源数组顺序,这是我想要的。如果调用例程想要合并数组A,B和C,其中A有3个元素但B和C有2个,我们应该得到A,B,C,A,B,C,A,而不是A,C,B ,A,C,B,A或其他可能性。我发现选择我的第一个源数组已经过期&#34;过期&#34; (通过比例低于我们的整体进度),我得到了与所有阵列的良好间距。

Python中的来源:     @classmethod     def intersperse_arrays(cls,arrays:list):         #一般的想法是在我们下去的时候产生一个尽可能平衡所有数组之间的结果。

    # Make sure we don't have any component arrays of length 0 to worry about.
    arrays = [array for array in arrays if len(array) > 0]

    # Handle basic cases:
    if len(arrays) == 0:
        return []
    if len(arrays) == 1:
        return arrays[0]

    ret = []
    num_used = []
    total_count = 0
    for j in range(0, len(arrays)):
        num_used.append(0)
        total_count += len(arrays[j])

    while len(ret) < total_count:
        first_overdue_array = None
        first_remaining_array = None
        overall_prop = len(ret) / total_count

        for j in range(0, len(arrays)):
            # Continue if this array is already done.
            if len(arrays[j]) <= num_used[j]:
                continue
            current_prop = num_used[j] / len(arrays[j])
            if current_prop < overall_prop:
                first_overdue_array = j
                break
            elif first_remaining_array is None:
                first_remaining_array = j

        if first_overdue_array is not None:
            next_array = first_overdue_array
        else:
            # Think this only happens in an exact tie.  (Halfway through all arrays, for example.)
            next_array = first_remaining_array

        if next_array is None:
            log.error('Internal error in intersperse_arrays')
            break   # Shouldn't happen - hasn't been seen.

        ret.append(arrays[next_array][num_used[next_array]])
        num_used[next_array] += 1

    return ret

当用于给出的例子时,我得到了:

ABCADABAEABACABDAFABACABADABACDABAEABACABAD

(似乎合理。)