2

我正在使用马尔可夫模型创建一个伪随机文本生成器。基本上,我使用哈希表来存储 k 阶(马尔可夫模型的顺序)的子串列表,然后对于每个子串,我有一个后缀的 TreeMap 及其在整个子串中的频率。

我正在努力生成随机后缀。对于每个子字符串,我都有一个包含所有可能后缀及其频率的 TreeMap。我无法使用它为每个后缀创建概率,然后根据概率生成伪随机后缀。

对此概念以及如何进行此操作的任何帮助表示赞赏。如果您有任何问题或需要澄清,请告诉我。

4

1 回答 1

1

我不确定 aTreeMap是否真的是最好的数据结构,但是 . . .

您可以使用Math.random()方法获取0.0(包含)和1.0(不包含)之间的随机值。然后,迭代地图的元素,累积它们的频率,直到超过该值。第一个超过这个值的后缀就是你的结果。假设您的地图元素的频率加起来为1.0,这将选择与其频率成比例的所有后缀。

例如:

public class Demo
{
    private final Map<String, Double> suffixFrequencies =
        new TreeMap<String, Double>();

    private String getRandomSuffix()
    {
        final double value = Math.random();
        double accum = 0.0;
        for(final Map.Entry<String, Double> e : suffixFrequencies.entrySet())
        {
            accum += e.getValue();
            if(accum > value)
                return e.getKey();
        }
        throw new AssertionError(); // or something
    }

    public static void main(final String... args)
    {
        final Demo demo = new Demo();
        demo.suffixFrequencies.put("abc", 0.3);  // value in [0.0, 0.3)
        demo.suffixFrequencies.put("def", 0.2);  // value in [0.3, 0.5)
        demo.suffixFrequencies.put("ghi", 0.5);  // value in [0.5, 1.0)

        // Print "abc" approximately three times, "def" approximately twice,
        // and "ghi" approximately five times:
        for(int i = 0; i < 10; ++i)
            System.out.println(demo.getRandomSuffix());
    }
}

笔记:

  • 由于舍入误差,throw new AssertionError()可能实际上经常发生,尽管很少发生。所以我建议你用总是选择第一个元素或最后一个元素或其他东西的东西替换该行。
  • 如果频率加起来不是getRandomSuffix()1.0,那么您应该在开头添加一个通道,以确定所有频率的总和。然后,您可以value相应地进行缩放。
于 2012-11-19T22:16:21.120 回答