【问题标题】:No. of DFA's that can be constructed可构建的 DFA 数量
【发布时间】:2021-05-13 22:43:29
【问题描述】:

给定字母表 {0,1} 上的 5 个状态,可以构造多少个 DFA。鉴于初始状态不固定。

【问题讨论】:

    标签: dfa


    【解决方案1】:

    对于字母表中的每个符号,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 个州

    如果我们想要一个可以生成 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 定义的语言,通常我们只关注转换而不是状态,但情况似乎并非如此因为您要求考虑所有可能的初始状态。

    【讨论】:

    • 您能解释一下您发现可以生成多少个 DFA 的部分吗?你是怎么得到 6^2^5 的?
    • 如果您在阅读公式后有说明,如果有帮助,我们就使用符号。 s 是状态集 ((|s|+1)^|A|)^|s| |s|+1 是每个转换的目的地数(任何状态,或不存在)|A|是字母表中符号的数量。指数 |s|是因为对于每个州,您都可以独立选择目的地。
    • 我们可能还需要考虑哪个状态是初始状态(5 的乘数)以及哪些状态正在接受(2^5 的乘数)。
    • 是的,这是有道理的。
    • 请查看this
    猜你喜欢
    • 2016-07-14
    • 1970-01-01
    • 2011-04-24
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 2021-12-21
    • 2016-08-25
    相关资源
    最近更新 更多