簡體   English   中英

從給定DFA打印所有接受的字符串(如果無限量,則為上限)的算法

[英]Algorithm for printing all accepted strings (to an upper bound if infinite amount) from a given DFA

如標題所示,我正在嘗試編寫一種算法,該算法可在輸入時從給定的DFA(確定性有限自動機)生成可接受的字符串,直到上限。

如果它包含循環模式,則它生成的字符串不應超過上限n,因為顯然我無法打印無限數量的字符串,這導致了我的問題。

具有有限語言的機器非常簡單,因為我可以執行DFS搜索並遍歷圖形並以遞歸方式連接連接狀態的所有字母,但是我不知道如何處理無限語言DFA,除非我對限制進行硬編碼DFS應該遍歷多少次可能導致周期的狀態。

所以我的問題是; 如何解決這個問題。 我可以使用任何已知的算法來解決此任務嗎? 邊界指定字符串的數目,而不是字符串的長度。 字符串的長度不允許超過5000個字符,但最好不要接近字符串的長度,因為最大界限n在測試中最多為1000。

我當前非常幼稚的解決方案如下:

public void generateStrings(int currentStateNum, Set<String> output, String prefix, Set<Integer> traversedStates){

    State currentState, tempState;
    String nextString;
    currentState = dfa.get(currentStateNum);

    //keeps track of recursion track, i.e the states we've already been to.
    //not in use because once there are cyclic patterns the search terminates too quickly
    //traversedStates.add(currentStateNum);

    //My current, bad solution to avoid endless loops is by checking how many times we've already visited a state
    currentState.incrementVisited();


    //if we're currently looking at an accepted state we add the current string to our list of accepted strings
    if(currentState.acceptedState){
        output.add(prefix);
    }


    //Check all transitions from the current state by iterating through them.
    HashMap<Character, State> transitions = currentState.getTransitions();


    for (Map.Entry<Character, State> table : transitions.entrySet()) {

        //if we've reached the max count of strings, return, we're done.
        if (output.size() == maxCount) {
            return;
        }

        tempState = table.getValue();

        //new appended string. I realize stringbuilder is more efficient and I will switch to that
        //once core algorithm works
        nextString = prefix + table.getKey().toString();

        //my hardcoded limit, will now traverse through the same states as many times as there are states
        if (tempState.acceptedState || tempState.getVisitedCount() <= stateCount) {

            generateStrings(tempState.getStateNum(), output, nextString, traversedStates);

        }

    }


}

這並不是真正的dfs,因為我不檢查我已經訪問過的狀態,因為如果這樣做,將打印的所有內容都是到最近的接受狀態的最簡單路徑,這不是我想要的。 我想根據需要生成盡可能多的字符串(如果DFA的語言不是有限的,那就是)。

該解決方案一直有效,直到我任意選擇的“訪問限制”不再削減該限制為止,因此我的解決方案在某種程度上或完全不正確。

如您所見,我代表自動機的數據結構是一個帶有狀態的ArrayList,其中State是一個單獨的類,其中包含帶有過渡的HashMap,其中鍵是邊緣char,值是過渡導致的狀態。

有誰知道我應該如何處理這個問題? 我努力尋找類似的問題,但是除了一些github倉庫代碼之外,我找不到其他有用的東西,因為代碼太復雜了,我無法從中學習任何東西。

在此先多謝!

我將使用表示當前狀態和到目前為止生成的字符串的對象的有界隊列,然后繼續執行以下操作,

  1. 將{“”,start}添加到隊列中,代表到目前為止創建的字符串(為空)和DFA的開始狀態。
  2. 只要隊列中有東西
    1. 彈出隊列
    2. 如果當前狀態正在接受,則將currentString添加到結果集中。
    3. 對於從此狀態開始的每次轉換,請將條目添加到{currentString + nextCharacter,nextState}形式的隊列中
  3. 當您敲了足夠多的字符串,字符串太長或隊列為空(有限語言)時,請停止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM