茶袋香精混合算法

时间:2018-11-30 14:21:40

标签: algorithm

我买了树箱的茶袋,它们有不同的口味(A,B,C)。

我希望以这样的方式混合它们-永远不会有两个连续的相同风味的袋子(避免使用ABCCAB); -混合是“最”随机的,即避免使用诸如ABCABCABC ...或ABABAB ... BCBCBC ... CACACA之类的模式。

这种混合是否有已知算法?

目前,我随机地对许多“ ABC”进行随机混排并连接结果,如果先前混排的最新字母与新混排的开头相同(... ABCCAB => ... ABCACB),则交换前几个字母

我想我可以通过预先计算ABC的排列来改进此算法,并在与上一个排列不同的字母开头的排列中画一个排列。

我试图“谷歌”这个问题,但是作为一个讲法语的人,我可能会错过适当的关键词。

PS:我以前在scicomp.stackexchange.com上发布了这个问题,建议在这里重复。

3 个答案:

答案 0 :(得分:2)

类似的事情应该起作用:

amount_of_teabags_per_flavour = x
choices = {
    A : amount_of_teabags_per_flavour,
    B : amount_of_teabags_per_flavour,
    C : amount_of_teabags_per_flavour
}
previous_choice = 0
picks_left = amount_of_teabags_per_flavour * choices.size

function select_available_choices() :
    mandatory_choice = [ key from choices where key != previous_choice and value <= picks_left/2 ] 
    if mandatory_choice == [] :
        available_choices = [ key from choices where key != previous_choice and value > 0 ]
    otherwise
        available_choices = mandatory_choice


result = []
select_available_choices()
while available_choices != [] :
    choice = pick_randomly_from(available_choices)
    result[last] = choice
    previous_choice = choice
    choices[choice]--
    picks_left--
    select_available_choices()

答案 1 :(得分:0)

对于第一种口味,您可以从三个字母ABC中随机选择一个开始,然后根据其他两种可能性之一计算下一个(因为您不希望口味重复出现。

python3中的快速脚本:

from random import randint

rand = lambda x: randint(0,x)

flavors = ['A', 'B', 'C']
freq = [0, 0, 0]

index = rand(2)
mix = flavors[index]

for i in range(1000):
        index = (index + 1 + rand(1)) % 3
        mix += flavors[index]
        freq[index] += 1

print(mix)
print(freq)

您会发现随机性很好(考虑到频率和足够宽的范围),并且连续两次没有字符重复。

答案 2 :(得分:0)

避免边界重复是一个图形问题。您有一个从每个节点(排列)到每个其他节点的有向边……除了加倍的边界。您需要通过该图的哈密顿路径;解决方案随时在线提供。然后根据需要复制或截断该路径,以匹配每个包装箱中的行李数量。

如果您想简化问题,则生成边缘以将每个节点(仅 )与以上一个节点的 second 包开头的节点连接。例如,以您的3盒设计...

ABC -> BAC, BCA
CBA -> BAC, BCA
BAC -> ABC, ACB
CAB -> ABC, ACB
ACB -> CAB, CBA
BCA -> CAB, CBA

从完整排列集构建的任何图都具有哈密顿路径,并且查找起来要快得多。一个简单的递归算法(带有回溯)应该易于编码。如果您按照二阶可用性对您的选择进行排序,我认为,该问题可以自动解决,而无需回溯。

例如,如果您在节点ABC上,请查看以B开头的可用选项:BACBCA看看其中的第二个字母:{ {1}}仅给您一个剩余的选择(A已被使用),但是ABC仍然有两个选择。因此,您移至C。如果您的首要选择受束缚,那么请决定您希望采用的任何方式...保持返回末尾的起始节点的能力。

能解决您的问题吗?