【问题标题】:Pseudo-random algorithm伪随机算法
【发布时间】:2018-08-13 13:53:44
【问题描述】:

我想在一个序列上创建一个伪随机算法。 序列如下所示:

A B C D E F A B C D E F A B C D E F A B C D E F...

该算法旨在创建这些字母的更短的随机序列,规则是:

  • 永远不要有 2 个相同的字母相互跟随(例如 A A B C D)。这个挺简单的,麻烦接踵而至。
  • 二元组只能重复两次(例如A B A B A C B D 可以,但A B C D A B A B 不行);
  • 不应重复尝试尝试(例如A B C D A B C 不行)。

我不是很擅长算法,我已经尝试了很长时间但没有成功,所以希望你能帮助我!

【问题讨论】:

  • 请提供您的代码。
  • 这只是记住已经生成的内容。 6 个字母有 36 个不同的 dyads 和 216 个不同的 tryads。
  • 您可以使用回溯算法,并在您发现违反其中一个约束时回溯。通过在每个级别以不同的顺序迭代字符来使其随机化。
  • 这有点类似于stackoverflow.com/q/37452547/56778,尽管这与在列表中均匀分布项目有关。您可能会使用用于解决该问题的技术。
  • 顺便说一句,你说对偶不能重复多次。所以A B A B D A B 是不允许的。 A B A B D B A 呢?也就是说,二元组中的项目顺序重要吗?

标签: algorithm random sequence


【解决方案1】:

您可以使用回溯算法,跟踪前两个字符以及到目前为止看到的字符对和三元组的计数。然后只需递归生成所有有效序列。为了使这更加随机,您可以对每个递归调用中尝试字符的顺序进行采样/打乱。

如果您将其实现为生成器(例如在 Python 中),则可以使用它来生成所有或仅生成下一个此类组合。否则,只需返回您找到的第一个解决方案。

Python 示例:

import collections, random
def backtrack(available, n, counts, last=None, lastlast=None):
    if n == 0:
        yield []
    else:
        for c in random.sample(list(available), len(available)):
            # check constraints
            if available[c] == 0: continue
            if c == last: continue
            if last is not None and counts[c+last] > 1: continue
            if lastlast is not None and counts[c+last+lastlast] > 0: continue
            # update counts
            available[c] -= 1
            if last: counts[c+last] += 1
            if lastlast: counts[c+last+lastlast] += 1
            # recursive call to get remainder
            for rest in backtrack(available, n-1, counts, c, last):
                yield [c] + rest
            # reset counts
            available[c] += 1
            if last: counts[c+last] -= 1
            if lastlast: counts[c+last+lastlast] -= 1

例子:

lst = "A B C D E F A B C D E F A B C D E F A B C D E F".split()
print(next(backtrack(collections.Counter(lst), 6, collections.Counter())))
print(next(backtrack(collections.Counter(lst), 6, collections.Counter())))
print(next(backtrack(collections.Counter(lst), 6, collections.Counter())))
res = list(backtrack(collections.Counter(lst), 6, collections.Counter()))
print(len(res))

输出:

['A', 'C', 'B', 'A', 'E', 'A']
['A', 'F', 'A', 'E', 'D', 'A']
['E', 'D', 'E', 'F', 'E', 'B']
18360

但是,根据您的列表和从中获取的元素数量,它也可能只从列表中生成随机样本并检查约束,直到找到一个有效的样本。

【讨论】:

  • 嗨,非常感谢,我的老板想让我在这个上使用 R,所以我会尽力翻译它,这很有帮助:)
猜你喜欢
  • 2010-12-05
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 2019-10-17
相关资源
最近更新 更多