一次一个字母生成名字的有限状态机
Finite State Machine for Generating Names One Letter at a Time
我记得几年前 class 我得到了一个有趣的有限状态机示例,其中每个状态都包含一个字母,并且有多条路径通向通常跟随它们的其他字母一个字。一些字母也有通往终止的路径,并且通过从有限状态机中的任意点开始并遵循通往终止的有效路径,您可以将字母链接在一起并且(几乎)总是以有效结束单词。当然,这只是语言中单词的一个子集(不幸的是,我忘记了 FSM 是指什么语言)。我的问题涉及多个相关问题:
- 这是随机生成 "pseudo" 单词的可行方法吗?我的意思是一个不一定有效但拼写方式看起来有效的词。
- 此技术是否用于任何著名的随机词生成算法或作为其一部分,如果是,是哪些?
- 是否有其他常见的替代方法可以一次生成一个随机单词一个字母,或者可能采用以这种方式生成的随机字符串并将其强制转换为 "pseudo" 个单词?
规则
您案例的正确答案取决于 "pseudo-word" 的含义,以及您希望生成的多个伪词如何相互关联。既然你已经用 "procedural generation" 标记了这个问题,我假设你想要构建一种假的自然语言;所以:
- 每个词都应该是可发音的。例如,'gotrobit' 可以接受,但 'grrhjklmpp' 则不行。
- 一般'feel'不同词应该有可比性;您不希望一组听起来像芬兰语的单词与听起来像法语的单词混在一起。
FSM 的一般问题
你当然可以使用有限状态机来做到这一点,但有两个可能的陷阱:
- 如果 FSM 包含循环,则字长可能变化很大;这对于要求 #2 来说可能非常糟糕。如果您的 FSM 不包含循环,您最终会得到一个巨大的 FSM,以便生成合理的词典。
- 构建 FSM 时需要非常小心,否则最终会得到不满足 #1 的词。
您可以添加一个 post 处理步骤来过滤掉 'stupid' 结果,但正如我稍后将展示的那样,还有更好的选择。
马尔可夫链
考虑到这些陷阱,一种常见的 FSM 播种方法是使用 Markov chains。
例如,您可以生成一个不确定的 FSM,其中每个状态代表一个字符(或终止符);然后你分析一个语料库英文文本计算特定字符后跟另一个字符的可能性,并使用它来创建您的过渡。
使用马尔可夫链可以更轻松地实现目标 #2;通过使用例如一个德语文本语料库,你会得到一组完全不同的单词,但它们仍然有些相似。
如前所述,陷阱仍然存在。例如,查看单词 "art" 和 "train"。这意味着 't' 可以跟在 'r' 之后,而且 'r' 也可以跟在 't' 之后。基于这些例子,你可以得到像 "trtrtrain" 这样的词,在我看来这违反了#1。
让每个状态代表 2 个字符而不是一个字符的组合可以在一定程度上缓解这种情况,但这会很快导致状态爆炸。
音节
一个更有希望的方法是不是一个字母一个字母地生成你的单词,而是一个音节一个音节地生成你的单词。您首先生成一个允许的音节列表,确定您喜欢的音节单词长度,然后选择该数量的音节。
例如,您可以从使用所有辅音+元音音节的列表开始。这会给你像 "tokuga" 和 "potarovo" 这样的词。您还可以使用元音+辅音音节列表,这会给您 "otukag" 和 "opatorov" 之类的词:一个完全不同的 'language',具有相同的简单规则。
当然,这会变得很棘手,例如允许辅音+元音和单元音音节。现在你可以得到像 "tokuuauga" 这样的词,这可能是你想要的,也可能不是。
你可以更进一步,对音节的类型进行分类,并添加一些简单的规则,例如:"only two single-vowel syllables can follow each other";或 "every consonant-vowel syllable followed by a single-vowel syllable must be followed by a consonant-vowel-consonant syllable"。现在你可以得到像 "tokuugat".
这样的词
通过选择一组允许的音节和规则,您可以获得感觉有些连贯的不同 'languages'。
使用音素
如果你想写出更好的单词,你应该从使用 phonemes 而不是字母开始。这使您可以轻松地表示非 ASCII 声音,例如 "ng"、"sh" 和(舌头点击)。然后按照上述算法进行操作,然后是 "transliteration" 步骤,将音素更改为 'readable' 字母。
通过使用不同的音译,你可以获得更多'language'的感觉。例如,您可以将 /sh/ 音译为 'sh'(英语)或 'ch'(法语)或 'sch'(荷兰语)。
音韵规则
Phonological rules 基本上是描述上一节规则的正式方式,比我之前的例子更进一步。通过选择正确的规则集,您可以创建 'hard' 种语言、'soft' 种语言等。例如,您可以选择将 'vowel+r+k+vowel' 更改为 'vowel+r+r+vowel'(导致听起来像马达的语言)或更改为 'vowel+k+h+vowel'(导致典型的侏儒语言)。可能性是无止境。
语音学研究产生了很多这样的规则,帮助你创造出更像地球的语言。
这种方法的一个很好的例子是 Drift,这是一个 Python 程序,它使用音节列表和一组音系规则来生成 'real' 单词。
撇开随机性和计算机生成的方面不谈,我相信这或多或少是托尔金在生成他的精灵语和方言时使用的方法。
结论
总结答案:
- 是的,使用 FSM 是一种可行的方法
- 马尔可夫链是创建此类 FSM 的流行技术
- 通过使用音节和音韵学研究,您可以获得更好的结果
我记得几年前 class 我得到了一个有趣的有限状态机示例,其中每个状态都包含一个字母,并且有多条路径通向通常跟随它们的其他字母一个字。一些字母也有通往终止的路径,并且通过从有限状态机中的任意点开始并遵循通往终止的有效路径,您可以将字母链接在一起并且(几乎)总是以有效结束单词。当然,这只是语言中单词的一个子集(不幸的是,我忘记了 FSM 是指什么语言)。我的问题涉及多个相关问题:
- 这是随机生成 "pseudo" 单词的可行方法吗?我的意思是一个不一定有效但拼写方式看起来有效的词。
- 此技术是否用于任何著名的随机词生成算法或作为其一部分,如果是,是哪些?
- 是否有其他常见的替代方法可以一次生成一个随机单词一个字母,或者可能采用以这种方式生成的随机字符串并将其强制转换为 "pseudo" 个单词?
规则
您案例的正确答案取决于 "pseudo-word" 的含义,以及您希望生成的多个伪词如何相互关联。既然你已经用 "procedural generation" 标记了这个问题,我假设你想要构建一种假的自然语言;所以:
- 每个词都应该是可发音的。例如,'gotrobit' 可以接受,但 'grrhjklmpp' 则不行。
- 一般'feel'不同词应该有可比性;您不希望一组听起来像芬兰语的单词与听起来像法语的单词混在一起。
FSM 的一般问题
你当然可以使用有限状态机来做到这一点,但有两个可能的陷阱:
- 如果 FSM 包含循环,则字长可能变化很大;这对于要求 #2 来说可能非常糟糕。如果您的 FSM 不包含循环,您最终会得到一个巨大的 FSM,以便生成合理的词典。
- 构建 FSM 时需要非常小心,否则最终会得到不满足 #1 的词。
您可以添加一个 post 处理步骤来过滤掉 'stupid' 结果,但正如我稍后将展示的那样,还有更好的选择。
马尔可夫链
考虑到这些陷阱,一种常见的 FSM 播种方法是使用 Markov chains。
例如,您可以生成一个不确定的 FSM,其中每个状态代表一个字符(或终止符);然后你分析一个语料库英文文本计算特定字符后跟另一个字符的可能性,并使用它来创建您的过渡。
使用马尔可夫链可以更轻松地实现目标 #2;通过使用例如一个德语文本语料库,你会得到一组完全不同的单词,但它们仍然有些相似。
如前所述,陷阱仍然存在。例如,查看单词 "art" 和 "train"。这意味着 't' 可以跟在 'r' 之后,而且 'r' 也可以跟在 't' 之后。基于这些例子,你可以得到像 "trtrtrain" 这样的词,在我看来这违反了#1。
让每个状态代表 2 个字符而不是一个字符的组合可以在一定程度上缓解这种情况,但这会很快导致状态爆炸。
音节
一个更有希望的方法是不是一个字母一个字母地生成你的单词,而是一个音节一个音节地生成你的单词。您首先生成一个允许的音节列表,确定您喜欢的音节单词长度,然后选择该数量的音节。
例如,您可以从使用所有辅音+元音音节的列表开始。这会给你像 "tokuga" 和 "potarovo" 这样的词。您还可以使用元音+辅音音节列表,这会给您 "otukag" 和 "opatorov" 之类的词:一个完全不同的 'language',具有相同的简单规则。
当然,这会变得很棘手,例如允许辅音+元音和单元音音节。现在你可以得到像 "tokuuauga" 这样的词,这可能是你想要的,也可能不是。
你可以更进一步,对音节的类型进行分类,并添加一些简单的规则,例如:"only two single-vowel syllables can follow each other";或 "every consonant-vowel syllable followed by a single-vowel syllable must be followed by a consonant-vowel-consonant syllable"。现在你可以得到像 "tokuugat".
这样的词通过选择一组允许的音节和规则,您可以获得感觉有些连贯的不同 'languages'。
使用音素
如果你想写出更好的单词,你应该从使用 phonemes 而不是字母开始。这使您可以轻松地表示非 ASCII 声音,例如 "ng"、"sh" 和(舌头点击)。然后按照上述算法进行操作,然后是 "transliteration" 步骤,将音素更改为 'readable' 字母。
通过使用不同的音译,你可以获得更多'language'的感觉。例如,您可以将 /sh/ 音译为 'sh'(英语)或 'ch'(法语)或 'sch'(荷兰语)。
音韵规则
Phonological rules 基本上是描述上一节规则的正式方式,比我之前的例子更进一步。通过选择正确的规则集,您可以创建 'hard' 种语言、'soft' 种语言等。例如,您可以选择将 'vowel+r+k+vowel' 更改为 'vowel+r+r+vowel'(导致听起来像马达的语言)或更改为 'vowel+k+h+vowel'(导致典型的侏儒语言)。可能性是无止境。
语音学研究产生了很多这样的规则,帮助你创造出更像地球的语言。
这种方法的一个很好的例子是 Drift,这是一个 Python 程序,它使用音节列表和一组音系规则来生成 'real' 单词。
撇开随机性和计算机生成的方面不谈,我相信这或多或少是托尔金在生成他的精灵语和方言时使用的方法。
结论
总结答案:
- 是的,使用 FSM 是一种可行的方法
- 马尔可夫链是创建此类 FSM 的流行技术
- 通过使用音节和音韵学研究,您可以获得更好的结果