Petri网可达分析算法
来源:互联网 发布:mac导入铃声 编辑:程序博客网 时间:2024/06/06 02:22
Petri网导论这本教材第三章的算法
C++实现
输入 为 库所和变迁个数 以及关联矩阵
4 4
1 -1 0 0
-1 1 1 0
1 0 -1 -1
0 -1 -1 1
1 0 0 0
3 4
-1 1 0
1 -1 0
0 1 -1
0 -1 1
0 1 0
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod %100000007#define mp make_pair#define fi first#define se second#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define mid int m=(l+r)>>1using namespace std;const int nmax = 1000 + 10;const int tmax = 100 + 10;const int pmax = 100 + 10;int np, nt;//输入库所和变迁个数int A[tmax][pmax];//输入关联矩阵int A1[tmax][pmax], A2[tmax][pmax];//输出矩阵A+ 和输入矩阵A-int M0[pmax];//输入初始标识int M[pmax], M1[pmax];//当前标识struct Node {//CT节点 int m[pmax];//标识向量 struct Node* parent;//指向父节点的指针 int t;//变迁编号 1,2……,nt(对应下标+1) int flag;//标记 0为新,1为旧,-1为端点 Node() { memset(m, 0 ,sizeof(m)); parent = NULL; t = 0; flag = 0; };} Tr[nmax];bool repeat(int i) {//true为M是重复节点 for(int j = 0; j < np; ++j) { if(M[j] != Tr[i].m[j]) return false; } return true;//M(j) == m[j] j=1,2,...,np}bool check(int i) {// true为ti可发生 for(int j = 0; j < np; ++j) { if(M[j] < A2[i][j]) return false; } return true;//M[ti> 充要条件:M(j)>=aij j=1,2,...,np}int main() { freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); int cases = 0; /* 输入库所个数np和变迁个数nt,0 0结束输入 */ while(~scanf("%d %d", &np, &nt) && (np != 0 || nt != 0)) { printf("Case %d:\n", ++cases); int CR = 0;//1为可覆盖树,0为可达树 int k = 0;//记录CT中节点的个数 /* 清理上一组数据 */ memset(Tr, 0, sizeof(Tr)); memset(A, 0, sizeof(A)); memset(A1, 0, sizeof(A1)); memset(A2, 0, sizeof(A2)); memset(M0, 0, sizeof(M0)); memset(M, 0, sizeof(M)); memset(M1, 0, sizeof(M1)); /* 输入关联矩阵A和初始标识M0 */ for(int i = 0; i < nt; ++i) { for(int j = 0; j < np; ++j) { scanf("%d", &A[i][j]); if(A[i][j] == 1) A1[i][j] = A[i][j]; if(A[i][j] == -1) A2[i][j] = -A[i][j]; } }//关联矩阵 /* step0 以初始标识为CT的根节点,并标为新=0 */ Node *head;//空的头节点 head = (Node*)malloc(sizeof(struct Node)); head->parent = NULL; Tr[k].parent = head;//根节点(初始标识)M0=Tr[0] 指向空的头节点head for(int i = 0; i < np; ++i) { scanf("%d", &M0[i]); Tr[k].m[i] = M0[i];//Tr[0]为CT根节点 }//初始标识 k++;//目前只有一个根节点k=1 /* step1 是否存在新=0的节点,任选一个新的节点为当前节点=M */ while(1) { int nnew = -1;//当前节点(标识)的下标 for(int i = 0; i < k; ++i) { if(Tr[i].flag == 0) { nnew = i;//有新节点,下标为i break; } }if(nnew == -1) {//判断没有新的节点,结束while break; }//step1 结束,否则继续 /* 将任意一个新节点设置为当前节点=M */ for(int i = 0; i < np; ++i) { M[i] = Tr[nnew].m[i]; } /* step2 根节点=head 到 当前节点=M 的路径上 如果有重复标为旧flag=1 */ int rep = 0; Node *q = Tr[nnew].parent;//q指向当前节点M的父节点 while(q->parent != NULL) { int f = 0; for(int j = 0; j < np; ++j) { if(M[j] != q->m[j]) f = 1; }if(f == 0) {//M是重复节点 Tr[nnew].flag = 1;//标为旧=1 rep = 1; break; } q = q->parent; }if(rep == 1) { continue;//返回while,step1 }//step2 结束,不标为旧则继续 /* step3 当前节点=M 如果所有的变迁都是死的标为端点=-1 */ int dead = -1; for(int i = 0; i < nt; ++i) { if(check(i)) {//存在可发生的变迁ti dead = i; break; } }if(dead == -1) { Tr[nnew].flag = -1;//所有的变迁都不可发生,标为端点=-1 continue;//返回while,step1 }//step3 结束,不标为端点则继续 /* step4 对每个可发生的t */ for(int i = 0; i < nt; ++i) {//遍历每一个变迁t if(check(i)){//ti可发生 for(int j = 0; j < np; ++j) { /* 计算M1 */ if(M[j] == 'w') M1[j] = M[j]; else M1[j] = M[j] + A[i][j]; Tr[k].m[j] = M1[j]; } /* 插入w分量 */ Node *p = &Tr[nnew];//p指向当前节点M while(p->parent != NULL) { int f = 0; for(int j = 0; j < np; ++j) { if(p->m[j] > M1[j]) { f = -1;//不满足条件 break; } }if(f == 0) { for(int j = 0; j < np; ++j) { if(p->m[j] < M1[j]) { Tr[k].m[j] = 'w'; CR = 1;//存在w分量 } } } p = p->parent; }//判断是否有无穷w /* 插入新节点 */ Tr[k].parent = &Tr[nnew];//有向弧 Tr[k].t = i + 1;//有向弧旁标 Tr[nnew].flag = 2;//抹去标注 k++;//节点个数增加 } }//step4 结束,创建了新节点,继续找标为新=1的节点 }//无标为新的节点,while结束 /* step1 结束,算法结束 */ /* 输出得到可覆盖树CT或者可达树RT */ if(CR == 0) printf("The tree is reachability tree "); else printf("The tree is coverability tree "); printf("of %d nodes.\n", k); for(int i = 0; i < k; ++i) { for(int j = 0; j < np; ++j) { if(j == 0) printf("M%d = [", i); if(Tr[i].m[j] != 'w') printf("%d", Tr[i].m[j]); else printf("%c", Tr[i].m[j]); if(j != np - 1) printf(","); else printf("]"); } if(Tr[i].t != 0) printf(" t%d", Tr[i].t); if(Tr[i].parent != head) { for(int j = 0; j < np; ++j) { if(j == 0) printf(" parent = ["); if(Tr[i].parent->m[j] != 'w') printf("%d", Tr[i].parent->m[j]); else printf("%c", Tr[i].parent->m[j]); if(j != np - 1) printf(","); else printf("]"); } } printf("\n"); } printf("\n"); } return 0;}
16年12月完成 现在只是存一下(主要比较好找)
0 0
- Petri网可达分析算法
- Petri
- Petri网
- Petri Net
- Petri网
- petri net
- petri net
- Petri网
- [刷题]算法竞赛入门经典(第2版) 6-7/UVa804 - Petri Net Simulation
- Petri网的介绍
- Petri网描述语言
- Petri网介绍
- Petri网简介
- Petri网入门
- 初识Petri网
- Petri网笔记
- color petri net tool
- 804 - Petri Net Simulation
- Flink DataSet API Programming Guide学习&译文(未完待续)
- 【LeetCode】 160. Intersection of Two Linked Lists C语言
- 数据库
- 文章标题
- iOS之正则表达式的使用和谓词(NSPredicate)的使用(三)
- Petri网可达分析算法
- SIFT学习记录
- pip install urllib2不能安装
- 桥接模式下socket回应
- 文章标题
- iOS之实现按钮拖动/tableViewcell多选,拖动/collectionviewcell多选,拖动(交换位置)
- Android辅助功能AccessibilityService与抢红包辅助
- 二维码的生成,扫描(ZXing开源的依赖库)
- 关于mysql和orcal相关问题