Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 霍普克罗夫特';s算法&DFA最小化_Java_Algorithm_Computation Theory - Fatal编程技术网

Java 霍普克罗夫特';s算法&DFA最小化

Java 霍普克罗夫特';s算法&DFA最小化,java,algorithm,computation-theory,Java,Algorithm,Computation Theory,我想实现Hopcroft算法来最小化DFA。到目前为止,我可以删除无法访问的状态。问题是我不理解这个算法。我不知道如何实施它。有人能解释一下吗?或者扩展算法,使其更易于实现。我根本不了解算法的以下部分: let X be the set of states for which a transition on c leads to a state in A for each set Y in P for which X ∩ Y is nonempty and Y \ X is non

我想实现Hopcroft算法来最小化DFA。到目前为止,我可以删除无法访问的状态。问题是我不理解这个算法。我不知道如何实施它。有人能解释一下吗?或者扩展算法,使其更易于实现。我根本不了解算法的以下部分:

 let X be the set of states for which a transition on c leads to a state in A
      for each set Y in P for which X ∩ Y is nonempty and Y \ X is nonempty do
           replace Y in P by the two sets X ∩ Y and Y \ X
算法如下:

到目前为止,我已经实现了什么(写得很糟糕,完成后会进行清理):

package-dregout;
导入java.io.*;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.Iterator;
公共级dfamin{
//保存文件中数据的全局变量
纽姆州、纽马尔哈贝茨州、纽姆芬纳州的私营企业;
专用字符字母[];
私人国际财务报表[];
私有int[][]可传递;
/**
*@param args
*@抛出异常
*@throws NumberFormatException
*/
公共静态void main(字符串[]args)引发NumberFormatException,IOException{
国际新州、新墨西哥州、新墨西哥州;
字符字母表[];
国际最终状态[];
int[][]可传递;
/*
*输入文件格式:NumberOfState numberofAlphabets转换1转换2…NumberOfFinalState最终状态
*例如:
*          8 2 1 5 6 2 0 2 2 6 7 5 2 6 6 4 6 2 2 2 6
*          5 2 0 1 0 1 3 4 3 4 2 4 3 0 2 3
*          8 2 1 0 0 2 3 1 3 0 3 5 6 4 5 6 6 3 1 3
*          9 2 1 4 2 5 3 7 4 7 5 8 6 1 7 1 8 2 0 4 3 2 5 8
*/
//获取文件名并打开一个流来读取它
FileInputStream fileStream=newfileinputstream(“/path/to/file”);
BufferedReader br=新的BufferedReader(新的InputStreamReader(fileStream));
//存储文件中的每一行
弦线;
//从文件中读取每一行
而((line=br.readLine())!=null){
//从每行读取单间隔数据
String[]splittedLine=line.split(“”);
//从这行读numStates,nummalphabets
numStates=Integer.parseInt(splittedLine[0]);
numAlphabets=Integer.parseInt(splittedLine[1]);
//对于(int a=0;a如果无法单独从接受/拒绝行为中分辨出DFA所处的状态,则调用两个DFA状态等效。对于每种语言,接受该语言的最小DFA没有等效状态

Hopcroft的DFA最小化算法通过计算未最小化DFA状态的等价类来工作。这种计算的核心是一个迭代,在每一步中,我们都有一个比等价更粗糙的状态分区(即,等价状态总是属于同一个分区集)

  • 最初的划分是接受状态和拒绝状态。很明显,它们是不等价的

  • 假设我们在当前分区的同一集合中有状态q1和q2。如果存在符号σ,则转移函数为δ,使得δ(q1,σ)和δ(q2,σ)在不同的划分集合中,通过粗糙度不变量,我们知道这些状态是不等价的,也就是说,存在一个字符串x,使得delta(delta(q1,sigma),x)和delta(delta(q2,sigma),x)在是否接受/拒绝方面不同。但是delta(delta(q1,sigma),x)=delta(q1,sigma x),因此字符串sigma x区分q1和q2。您引用的逻辑是适当地分割一个分区集

  • 正确性证明中有趣的部分是,当第2步不可能时,我们得到了真正的等价类


  • 伪代码看起来比这更复杂,因为它关系到我们找到步骤2的应用程序的效率。

    阅读原始文章中给出的示例可能有助于将此算法可视化

    在中指定该算法之前,我们通过一个示例对该算法进行了说明 详细信息。广泛使用列表处理来减少 计算时间


    如果不画出DFA并在白板上浏览它,很难以直观的方式解释算法。就实现而言,它是最好的(以我的经验)将伪代码作为注释放入,并编写代码来实现每一部分。对于这个特定的算法,使用实际的数学风格的集合类(支持并集和交集等)非常有帮助,这样您就可以逐字实现(请注意,这不一定是最有效的方法,但它可以让您更轻松地翻译伪代码)。谢谢。我正在使用此逻辑实现我的代码,希望它是正确的!
        package dRegAut;
    import java.io.*;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Iterator;
    
    
    public class dfamin {
    
        // Global variables to hold data from the file
        private int numStates,numAlphabets,numFinalStates;
        private char alphabets[];
        private int finalStates[];
        private int [][] transitionTable;
    
    
    
        /**
         * @param args
         * @throws IOException 
         * @throws NumberFormatException 
         */
        public static void main(String[] args) throws NumberFormatException, IOException {
    
            int numStates,numAlphabets,numFinalStates;
            char alphabets[];
            int finalStates[];
            int [][] transitionTable;
    
            /*
             * INPUT FILE FORMAT: numberOfStates numberofAlphabets transitions1 transtions2 ... numberOfFianlStates FinalState(s)
             * Example: 
             *          8 2 1 5 6 2 0 2 2 6 7 5 2 6 6 4 6 2 2 2 6
             *          5 2 0 1 0 1 3 4 3 4 2 4 3 0 2 3
             *          8 2 1 0 0 2 3 1 3 0 3 5 6 4 5 6 6 3 1 3
             *          9 2 1 4 2 5 3 7 4 7 5 8 6 1 7 1 8 2 0 4 3 2 5 8
             */
    
            // Take file name and open a stream to read it
            FileInputStream fileStream = new FileInputStream("/path/to/file");
            BufferedReader br = new BufferedReader(new InputStreamReader(fileStream));
    
            // Store each line from the file
            String line;
    
            // Read each line from file
            while((line = br.readLine()) != null){
    
                // Read single spaced data from each line
                String [] splittedLine = line.split(" ");
    
                // Read numStates,numAlphabets from the line
                numStates = Integer.parseInt(splittedLine[0]);
                numAlphabets = Integer.parseInt(splittedLine[1]);
                //for(int a=0;a<numAlphabets;a++){
                    //alphabets[a] = '0';
                //}
                transitionTable = new int[numStates][numAlphabets];
                int tt= 2;
                // Loop thorough the line and read transition table
                for(int row=0;row<numStates;row++){
    
                    for(int col=0;col<numAlphabets;col++){
                        transitionTable[row][col] = Integer.parseInt(splittedLine[tt]);
    
                        tt++;
    
                    }// End of for-loop to go thorough alphabets
                }// End of for-loop to go thorough states
    
                // Read number of final states
                numFinalStates = Integer.parseInt(splittedLine[2+numStates*numAlphabets]);
                //System.out.println(numFinalStates);
                // Read final states
                int z=0;
                finalStates = new int[numFinalStates];
                int start = 3+numStates*numAlphabets ;
                int end = (3+(numStates*numAlphabets))+numFinalStates;
                for(int fs=start;fs<end;fs++){
                    finalStates[z] = Integer.parseInt(splittedLine[fs]);
                    //System.out.println(finalStates[z]);
                    z++;
                }// End of for-loop to read all final states
                dfamin x = new dfamin(numStates,numAlphabets,numFinalStates,finalStates,transitionTable);
                x.minimizer();
                System.out.println(x);
    
    
    
            }// End of while-loop to read file
    
            // Close the stream
            br.close();
    
        }
    
        dfamin(int nS,int nA,int nFS,int fS[], int [][] tT){
            numStates = nS;
            numAlphabets = nA;
            numFinalStates = nFS;
            //alphabets = a;
            finalStates = fS;
            transitionTable = tT;
    
        }// End of DFAMinimizer constructor
    
        /*
         * A method to minmize the dfa  
         */
    
        public void minimizer(){
    
            // Remove unreachable States
            ArrayList<Integer> reachableStates = reachableStates(numStates, numAlphabets,transitionTable);
    
            // Store all final states
            ArrayList<Integer> fStates = new ArrayList<Integer>();
            // Loop thorugh finalStates array and transfer its data to array list
            for(int fs:finalStates){
                fStates.add(fs);
            }// End of for-loop
    
            // Store all non final states
            ArrayList<Integer> nonFStates = new ArrayList<Integer>();
    
            // Store only non final states in nonFstates
            nonFStates = nonFinalStates(reachableStates,fStates);
    
            //TODO: IMPLEMENT HOPCROFT's ALGORITHM
    
    
        }// End of minimizer method
    
        /*
         * unreachableStates - A method to find unreachable states of a DFA 
         * 
         */
        public ArrayList<Integer> reachableStates(int numStates, int numAlphabets, int [][] transitionTable){
    
            // Initialize a list to hold temporary list of states in it
            ArrayList<Integer> reachableStates =new ArrayList();
            ArrayList<Integer> newStates = new ArrayList();
    
    
            // Start from the state zero
            reachableStates.add(0);
            newStates.add(0);
            // Temporary array to hold reachable states
            ArrayList<Integer> temp = new ArrayList();
            // Loop until there is data in newStates
            do{
                // Empty temp array
                temp.clear();
                // Loop thorough all the states, and check for {p such that p=δ(q,c)};
                for(int j=0;j<newStates.size();j++){
    
                    for(int i=0; i<numAlphabets;i++){
                        // If found add it to the temp set
                        temp.add(transitionTable[newStates.get(j)][i]);
    
                    } // End of for-loop to go thorough all characters
    
                }// End of for-loop to go thorough all elements of the newStates array list
    
                // Clear newStates list
                newStates.clear();
    
                // Add the elements that are in temp, but are not in reachableStates to newStates
                // new_states := temp \ reachable_states;
                for(int z=0;z<temp.size();z++){
    
                    for(int z1=0; z1<reachableStates.size();z1++){
    
    
                        // If the state was already present, don't add
                        if(temp.get(z) == reachableStates.get(z1)){
                            break;
                        }
                        if(temp.get(z) != reachableStates.get(z1) && z1 == reachableStates.size()-1){
                            // Only from temp to newstates if its not in reachablestates currently
                            newStates.add(temp.get(z));
    
                        }
    
    
                    }// End of for-loop to go thorough all reachableStates elements and check if a match
                }// End of for-loop thorugh all temp states
    
                // If newStates list is not empty then add it to the reachableStates
                if(!newStates.isEmpty()){
                    // Add the newStates elements to reachable states
                    for(int y=0;y<newStates.size();y++){
                        //System.out.printf("newStates:%d newStatesSize:%d in %d",newStates.get(y),newStates.size(),y);
                        reachableStates.add(newStates.get(y));
                    }
                }
    
            }while(!newStates.isEmpty());
    
            reachableStates = removeDuplicate(reachableStates);
    
            return reachableStates;
    
        }// End of unreachableStates method
    
        /*
         * removeDuplicate - a function to remove duplicate entries from an ArrayList
         * 
         */
        ArrayList<Integer> removeDuplicate(ArrayList<Integer> input){
    
            // Remove duplicate entries from reachableStates list
            // Compare the first index, with all other indexes, compare the second with all other indexes
            for(int i=0;i<input.size()-1;i++){
    
                for(int j=i+1;j<input.size();j++){
                    // If dupblicate states remove it
                    if(input.get(i) == input.get(j)){
                        input.remove(j);
                    }
                }
            }// End of for-loop to remove duplicate entries from reachableList
    
            // Sort the list before returning
            Collections.sort(input);
            // Return the list
            return input;
        }// End of removeDuplicate method
    
    
        /*
         * nonFinalStates - a method to return an array list of nonfinal states, given all and final states
         * 
         */
        ArrayList<Integer> nonFinalStates(ArrayList<Integer> allStates, ArrayList<Integer> finalStates){
            // All non final States
            ArrayList<Integer> nonFinalStates = new ArrayList<Integer>();
            // Loop thorough allStates, and compare each state with the list of finalstates
            for(int i=0; i<allStates.size();i++){
                // Loop thorough list of final states
                for(int j=0; j<finalStates.size();j++){
                    // If a state is final state
                    if(allStates.get(i) == finalStates.get(j)){
                        // Then remove it from the list
                        allStates.remove(i);
                    }
                }// End of for-loop to travers finalstates
            }// End of for-loop to traverse allstates
    
            return nonFinalStates;
    
        }
    
    
    
        // returns a string that is compatible with our input file specification
        public String toString()    {
            StringBuffer buf = new StringBuffer();
            //buf.append(" "+ numStates +" ");
            //buf.append ( numAlphabets + " " );
            buf.append("Transition Table: ");
            for ( int i = 0; i < numStates; i++ )   {
                for ( int j = 0; j < numAlphabets; j++ )    {
                    buf.append ( " "+ transitionTable[i][j] + " " );
                }
            }
    
            buf.append ( "Number of Final State(s): "+numFinalStates + " Final State(s): " );
            for ( int i = 0; i < numFinalStates; i++ )
    
                    buf.append ( finalStates[i] + " " );
            return buf.toString();
        }
    
    }