【发布时间】:2021-05-13 22:43:29
【问题描述】:
给定字母表 {0,1} 上的 5 个状态,可以构造多少个 DFA。鉴于初始状态不固定。
【问题讨论】:
标签: dfa
给定字母表 {0,1} 上的 5 个状态,可以构造多少个 DFA。鉴于初始状态不固定。
【问题讨论】:
标签: dfa
对于字母表中的每个符号,DFA 最多可以有一个转换。因此,我们可以通过为状态分配所有有效选项来枚举 DFA。
例如,我将使用以下表示法,即 2 元组的 5 元组,以及 {0, 1} 中符号的转换目标。
((None, 4), (4, 3), (1, None), (None, 0), (3, 3))
这给你一个 FST,它从状态 0 到状态 4(符号 1),从状态 4 到状态 3 到状态(符号 0 或 1),然后从那里回到状态 0(符号1)。但这没有连接,没有使用所有的 5 状态。如果计算所有此类 DFA,答案是 (6^2)^5 = 60466176,因为每个符号都可以带您进入 5 个状态之一或从给定状态中丢失(公式中的 6),有两个符号(2 在公式),有5个状态(公式中有5个指数)。
如果我们想要一个可以生成 5 个状态的 FST,并且所有状态都可达,那么我们可以生成上述 FST 并过滤那些连接的 FST。
def is_connected(dfa):
N = len(dfa)
reached = [False] * N
nReached = 0
stack = [0]
while len(stack):
s = stack.pop()
if not reached[s]:
reached[s] = True
nReached += 1
if nReached == N:
return True
t, u = dfa[s]
if t is not None:
stack.append(t)
if u is not None:
stack.append(u)
return False
import itertools
all_dfas = list(itertools.product(
list(itertools.product([None, 0, 1, 2, 3, 4],
repeat=2)
), repeat=5))
num_connected = sum(1 if is_connected(dfa) else 0 for dfa in all_dfas[:])
它给出15184800。
您可以尝试找到与重新标记状态等效的 DFA,因为这不会更改 DFA 定义的语言,通常我们只关注转换而不是状态,但情况似乎并非如此因为您要求考虑所有可能的初始状态。
【讨论】:
5 的乘数)以及哪些状态正在接受(2^5 的乘数)。