<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 1. NFA的確定化 ### 1.1. 明確NFA的定義 一個非確定的有窮自動機(NFA)M是一個五元式: - M=(S,∑,δ,S0,F) - S是一個有限集,它額每個元素稱為一個狀態。 - ∑是一個有窮字母表,它的每個元素稱為一個輸入字符 - δ是一個從S×∑?至S子集額單值映射。即:δ:S×∑?→2?S - S0?S,是一個非空的初態集 - F? S , 是一個終態集(可空) ### 1.2. 定義運算 定義對狀態集合I的幾個有關運算: - 狀態集合I的ε-閉包,表示為ε-closure(I),定義為一狀態集,是狀態集I中的任何狀態s經任意條ε弧而能到達的狀態的集合。狀態集合I的任何狀態s都屬于ε-closure(I)。 - 狀態集合I的a弧轉換,表示為move(I,a)定義為狀態集合J,其中J是所有那些可從I的某一狀態經過一條a弧而到達的狀態的全體。 定義Ia = ε-closure(move(I,a)) ### 1.3. 算法描述 - 每次從隊頭取出一個集合,**(開始隊列內只有初態集合I的ε-閉包(I) )**,然后得到它對于任意一個字符a的Ia=ε?closure(move(I,a)) - 然后如果當前狀態之前沒有出現過,那么當前狀態作為一個新的狀態I,放入隊列。 - 一直做如上操作,直到隊列為空 ### 1.4. 代碼如下: ~~~ #include <iostream> #include <cstdio> #include <algorithm> #include <fstream> #include <queue> #include <vector> #include <string> #include <cstring> #include <set> #define MAX 500 #define M 1000007 using namespace std; struct Set { set<int> elements; int state; }I[MAX]; vector<int> e[MAX]; vector<int> edge[MAX]; vector<int> val1[MAX]; vector<int> val2[MAX]; vector<int> hash[M]; vector<int> types; int vis[MAX][MAX]; int cntp,cnts,start,finish,used[MAX]; void _clear( ); void clear( ); void _add( int u , int v , int x ); void add( int u , int v , int x ); void dfs ( set<int>& elements , int u , int d , int flag ); void ensure(); void minimize(); int get_hash( set<int>& item ); //#define DEBUG int main ( ) { int m; puts("給出NFA的邊的條數:"); while ( ~scanf ( "%d" , &m ) ) { _clear(); clear(); puts("給出NFA的始態和終態:"); scanf ( "%d%d" , &start , &finish ); puts("給出所有的邊,每行一條:"); for ( int i = 0 ; i < m ; i++ ) { int u,v,x; scanf ( "%d%d%d" , &u , &v , &x ); _add ( u , v , x ); } #ifdef DEBUG set<int> temp; int num[]={2,3,6,7,8}; //for ( int i = 2 ; i < 6 ; i++ ) // dfs ( temp , i , 0 , 2 ); for ( int i = 0 ; i < 5 ; i++ ) dfs ( temp , num[i] , 0 , 1 ); set<int>::iterator it = temp.begin(); for ( ; it != temp.end() ; it++ ) printf ( "%d " , *it); puts(""); #else ensure(); puts("計算結果如下:"); printf ( "%d\n" , cnts ); for ( int i = 0 ; i < cnts ; i++ ) for ( int j = 0 ; j < edge[i].size() ; j++ ) printf ( "edges : %d %d %d\n" , i , edge[i][j] , val2[i][j] ); puts("\n給出DFA的邊的條數:"); #endif } } void _clear() { for ( int i = 0 ; i < MAX ; i++ ) { e[i].clear(); val1[i].clear(); } types.clear(); memset ( used , 0 , sizeof ( used ) ); } void clear() { for ( int i = 0 ; i < MAX ; i++ ) { edge[i].clear(); val2[i].clear(); } } void _add ( int u , int v , int x ) { e[u].push_back ( v ); val1[u].push_back ( x ); if ( !used[x] ) { types.push_back ( x ); used[x] = types.size(); } } int get_hash ( set<int>& item ) { int sum = 0; set<int>::iterator it = item.begin(),it1,it2; for ( ; it!= item.end() ; it++ ) { sum += (*it)*(*it)%M; sum %= M; } for ( int i = 0 ; i < hash[sum].size() ; i++ ) { int x = hash[sum][i]; set<int>& temp = I[x].elements; it = temp.begin(); bool flag = true; if ( temp.size() != item.size() ) continue; for ( it1 = temp.begin() , it2 = item.begin(); it2!= item.end() ; it1++,it2++ ) if ( *it1 != *it2 ) { flag = false; break; } if ( flag ) return x; } return -1; } int make_hash ( set<int>& item ) { int sum = 0; set<int>::iterator it = item.begin(); for ( ; it!= item.end() ; it++ ) { sum += (*it)*(*it)%M; sum %= M; } hash[sum].push_back ( cnts ); return cnts++; } void add ( int u , int v , int x ) { edge[u].push_back ( v ); val2[u].push_back ( x ); } void dfs ( set<int>& elements , int u , int d , int flag ) { if ( vis[u][d] ) return; vis[u][d] = 1; if ( d == 1 ) elements.insert ( u ); if ( d == 2 ) return; int len = e[u].size(); for ( int i = 0 ; i < len ; i++ ) { int v = e[u][i],dd; int x = val1[u][i]; if ( x == flag ) dd = d+1; else if ( x == 0 ) dd = d; else continue; dfs ( elements , v , dd , flag ); } } void ensure ( ) { I[0].elements.insert(start); cnts = 1; for ( int i = 0 ; i < cnts ; i++ ) { set<int>& cur = I[i].elements; for ( int j = 0 ; j < types.size() ; j++ ) { if ( types[j] == 0 ) continue; memset ( vis , 0 , sizeof ( vis ) ); set<int>& temp = I[cnts].elements; temp.clear(); set<int>::iterator it = cur.begin(); for ( ; it != cur.end() ; it++ ) dfs ( temp , *it , 0 , types[j] ); if ( temp.empty() ) continue; int x = get_hash ( temp ); if ( x == -1 ) x = make_hash ( temp ); add ( i , x , types[j] ); } set<int>::iterator it = cur.begin(); printf ( "I%d :" , i ); for ( ; it!= cur.end() ; it++ ) printf ( "%d " , *it ); puts (""); } } ~~~ ## 2. DFA的最小化 ### 2.1. 明確DFA的定義 一個確定的有窮自動機(DFA)M是一個五元式: - M=(S, ∑, δ, s0, F)其中 - S是一個有限集,它的每個元素稱為一個狀態。 - ∑是一個有窮字母表,它的每個元素稱為一個輸入字符 -δ是一個從S×∑至S的單值映射。δ(s,a)=s’意味著:當現行狀態-為s、輸入字符為a時,將轉換到下一個狀態s’。我們稱s’為s的一個后繼狀態。 - s0∈S,是唯一的初態。 - F ? S,是一個終態集(可空) ### 2.2 算法描述 - DFA M =(K,∑,f, k0,, kt),最小狀態DFA M’ - 1.構造狀態的初始劃分∏0:終態kt 和非終態K- kt兩組 - 2.對∏施用傳播性原則 構造新劃分∏new - 3.如∏new=∏,則令∏new=∏并繼續步驟4,否則∏:=∏new重復2 - 4.為∏final中的每一組選一代表,這些代表構成M’的狀態。若k是一代表且f(k,a)=t,令r是t組的代表,則M’中有一轉換f’(k,a)=r M’ 的開始狀態是含有K0的那組的代表 M’的終態是含有Kt的那組的代表 - 5.去掉M’中的死狀態. ### 2.3 代碼實現 ~~~ #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <string> #include <vector> #include <map> #include <queue> #include <fstream> #define MAX 507 using namespace std; struct Node { int x; int type; Node(){} Node( int a , int b ) :x(a),type(b){} bool operator < ( const Node& a ) const { return type < a.type; } }; int mp[MAX][MAX]; vector<int> _edge[MAX]; vector<int> _val[MAX]; vector<int> edge[MAX]; vector<int> val[MAX]; vector<int> point; vector<pair<int,int> > ans1; vector<int> ans2; vector<Node> col; int fa[MAX]; int type[MAX]; int state[MAX]; int used[MAX]; int kinds; int groups_num; int n; int m; void init (); int _find( int x ); void _union ( int x , int y ); void _add ( int u , int v , int x ); void add ( int u , int v , int x ); void minimize ( ); void make_csv(); int main ( ) { init ( ); scanf ( "%d%d" , &n , &m ); for ( int i = 1 ; i <= n ; i++ ) scanf ( "%d" , &type[i] ); for ( int i = 0 ; i < m ; i++ ) { int u,v,x; scanf ( "%d%d%d" , &u , &v , &x ); _add ( u ,v , x ); } minimize(); //最小化后的點的保留結果 puts ("points : " ); printf ( "%d\n" , (int)point.size() ); for ( int i = 0 ; i < point.size(); i++ ) printf ( "%d " , point[i] ); puts(""); //最小化后的邊的保留結果 puts ( "edge: "); m = ans1.size(); for ( int i = 0 ; i < ans1.size() ; i++ ) printf ( "%d %d %d\n" , ans1[i].first , ans1[i].second , ans2[i] ); puts(""); make_csv(); } void init ( ) { for ( int i = 0 ; i < MAX ; i++ ) { edge[i].clear(); _edge[i].clear(); } point.clear(); memset ( type , 255 , sizeof ( type ) ); memset ( used , 0 , sizeof ( used ) ); kinds = 0; groups_num = 2; col.clear(); for ( int i = 0 ; i < MAX ; i++ ) fa[i] = i; } void _add ( int u , int v , int x ) { _edge[u].push_back ( v ); _val[u].push_back ( x ); if ( used[x] ) return ; used[x] = x; kinds++; } void add ( int u , int v , int x ) { edge[u].push_back ( v ); val[u].push_back ( x ); } int _find ( int x ) { return x == fa[x]? x: fa[x] = _find ( fa[x] ); } void _union ( int x , int y ) { x = _find ( x ); y = _find ( y ); fa[x] = y; } void minimize ( ) { queue<vector<Node> > q[2]; col.clear(); for ( int i = 1 ; i <= n ; i++ ) { if ( type[i] == 0 ) col.push_back ( Node( i , 0 ) ); } q[1].push ( col ); col.clear(); for ( int i = 1 ; i <= n ;i++ ) { if ( type[i] == 1 ) col.push_back ( Node ( i , 1 ) ); } q[1].push( col ); col.clear(); for ( int i = 1 ; i <= kinds ; i++ ) { int cur = i%2; int next = (i+1)%2; while ( !q[next].empty() ) q[next].pop(); while ( !q[cur].empty() ) { vector<Node> front = q[cur].front(); q[cur].pop(); for ( int j = 0 ; j < front.size() ; j++ ) { Node& temp = front[j]; int u = temp.x; for ( int k = 0 ; k < _edge[u].size() ; k++ ) { int v = _edge[u][k]; int x = _val[u][k]; if ( x != i ) continue; temp.type = type[v]; } } sort ( front.begin() , front.end() ); if ( front[0].type == front[front.size()-1].type ) q[next].push ( front ); else { col.clear(); col.push_back ( front[0] ); for ( int j = 1 ; j < front.size() ; j++ ) { if ( front[j].type != front[j-1].type ) { q[cur].push ( col ); col.clear(); groups_num++; } type[front[j].x] = groups_num; col.push_back ( front[j] ); } q[cur].push( col ); } } } //#define DEBUG #ifdef DEBUG int id = (kinds+1)%2; int num = 1; while ( !q[id].empty() ) { vector<Node> temp = q[id].front(); q[id].pop(); printf ( "%d : ", num++ ); for ( int i = 0 ; i < temp.size() ; i++ ) printf ( "%d " , temp[i].x ); puts(""); } #else int id = (kinds+1)%2; while ( !q[id].empty() ) { vector<Node> temp = q[id].front(); q[id].pop(); for ( int i = 1 ; i < temp.size() ; i++ ) _union ( temp[i].x , temp[i-1].x); } memset ( used , 0 , sizeof ( used ) ); memset ( mp , 0 , sizeof ( mp ) ); for ( int i = 1 ; i <= n ;i++ ) { int x = _find(i); if ( used[x] ) continue; used[x] = 1; point.push_back ( x ); } ans1.clear(); for ( int i = 1 ; i <= n ; i++ ) for ( int j = 0 ; j < _edge[i].size() ; j++ ) { int v = _edge[i][j]; int x = _val[i][j]; int a = _find(i); int b = _find(v); if ( mp[a][b] ) continue; mp[a][b] = 1; add ( a , b , x ); ans1.push_back ( make_pair ( a , b ) ); ans2.push_back ( x ); } #endif } void make_csv ( ) { freopen ( "g1.csv" , "w" , stdout ); printf ( "%d,%d, \n" , n , m ); for ( int i = 0 ; i < point.size() ; i++ ) if ( i == 0 ) printf ( "%d" , point[i] ); else printf ( ",%d" , point[i] ); puts(""); for ( int i = 0 ; i < m ; i++ ) printf ( "%d,%d,%d\n" , ans1[i].first , ans1[i].second , ans2[i] ); fclose(stdout); } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看