Petri網可覆蓋性樹的構造演算法
阿新 • • 發佈:2018-12-21
#include<iostream> #include<algorithm> #include<stdio.h> using namespace std; typedef struct Node { int m[300] = { 0 };//標識 int flag = 0;//新0,舊1,端點2 int isfirable[300] = { 0 };//儲存可以發生的變遷名字 struct Node *parent;//該節點的父節點 int t = 0;//儲存生成這個節點所發生的變遷名字 }; int main() { int m = 4;//庫所個數 int n = 4;//變遷個數 int A[4][4] = { {1,-1,0,0},{-1,1,1,0},{1,0,-1,-1},{0,-1,-1,1} };//關聯矩陣 int A1[4][4] = { {1,0,0,0},{0,1,1,0},{1,0,0,0},{0,0,0,1} };//輸出矩陣 int A2[4][4] = { {0,1,0,0},{1,0,0,0},{0,0,1,1},{0,1,1,0} };//輸入矩陣 int M0[4] = { 1,0,0,0 };//初始標識 /*另一個例子 int m = 3; int n = 4; int A[4][3] = { {-1,1,0},{1,-1,0},{0,1,-1},{0,-1,1} }; int A1[4][3] = { {0,1,0},{1,0,0},{0,1,0},{0,0,1} }; int A2[4][3] = { {1,0,0},{0,1,0},{0,0,1},{0,1,0} }; int M0[4] = { 0,1,0,0 }; */ int k = 0;//當前可達樹中節點數目 Node Tree[500];//可達樹中所有節點 //頭結點 Node *head = new Node; head->parent = NULL; //M0是根節點 for (int i = 0; i < m; i++) { Tree[k].m[i] = M0[i];//把初始標識M0賦值給Tree[0] } Tree[k].parent = head; Tree[k].flag = 0; k++; int newNode; int exist; int test = 0; while (1) { //判斷存在標識為新的節點newNode,即flag為0的節點 exist = 0; newNode = 0; for (int i = 0; i < k; i++) { if (Tree[i].flag == 0) {//找到標識為新的節點 exist = 1; newNode = i; break; } } if (exist == 0) {//不存在標識為新的節點 break; } //任選標識為新的節點newNode,設為M int M[5] = { 0 }; int M1[5] = { 0 }; for (int i = 0; i < m; i++) { M[i] = Tree[newNode].m[i];//將標識為新的節點設為M } //if從M0到M的有向路上出現過M Node *q = Tree[newNode].parent; int repeated = 1; while (q) { for (int i = 0; i < m; i++) { repeated = 1;//新加的 if ( M[i]!= q->m[i]) { repeated = 0; break; } } if (repeated == 1) { break; } q = q->parent; } if (repeated == 1) {//路徑上有一個節點的標識為M Tree[newNode].flag = 1;//then M的標識改為舊,返回step1 continue; } //if 在M下所有變遷都不能發生 int enable; int enableNum=0 ; for (int i = 0; i < n; i++) {//對於所有的變遷 enable = -1; for (int j = 0; j < m; j++) { if (M[j] <A2[i][j]) {//變遷ti不能發生 enable = 0; break; } } //變遷從t0開始編號 if (enable == -1) {//變遷ti可以發生 Tree[newNode].isfirable[enableNum] = i; enableNum++; } } //標記M為端點 if (enableNum == 0) { Tree[newNode].flag = 2; continue; } //對於在M下每個可發生的變遷 for (int i = 0; i < enableNum; i++) { //可發生變遷ti的編號i為hang //計算M1 for (int j = 0; j < m; j++) { if (M[j] == 'w') M1[j] = M[j]; else { int hang = Tree[newNode].isfirable[i]; M1[j] = M[j] + A[hang][j]; } } //路徑上是否存在M2,使得M2<M1 Node *pp = Tree[newNode].parent; int flagW;//標識是否存在無界量 while (pp&&pp!=head) { flagW = 0; for (int ii = 0; ii < m; ii++) { if (pp->m[ii] > M1[ii]) { flagW = 1; break; } } if (flagW == 0) { for (int ii = 0; ii < m; ii++) { if (pp->m[ii] < M1[ii]) { M1[ii] = 'w';//標識無界量w } } } pp = pp->parent; } //引入新節點M1 for (int z = 0; z < m; z++) { Tree[k].m[z] = M1[z]; } Tree[k].flag = 0;//新節點M1標記為新 Tree[k].parent = &Tree[newNode];//新節點的父節點 Tree[k].t = Tree[newNode].isfirable[i];//通過發生哪個變遷得到的Tree[k] Tree[newNode].flag = 1;//擦去節點的新標註 k++;//可達樹中節點個數加一 } } cout << k<< endl; system("pause"); return 0; }