不确定标题。
这就是我需要的。
让我们举例说明这套元素有20 * A,10 * B,5 * C,5 * D,2 * E,1 * F 我需要混合它们,因此彼此之间没有两个相同的元素,我也可以说我不希望B和C彼此相邻。元素必须均匀分布(如果有2个E应该接近开始/在第一个半个和第二个近端/在后半部分。元素的数量当然可以改变。
我还没有做过这样的事情。是否有一些这种算法的知识库,我可以找到一些提示和方法来解决这类问题,还是我必须自己做所有的数学运算?
答案 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
(似乎合理。)