int SetUnion(int set1,int set2){ if (set2==EMPTY_SET) { return set1; } else { return SetInsert(SetUnion(set1,setnodes[set2].parent),setnodes[set2].label,setnodes[set2].dest); } }
int CheckCycle( Vertex V1, Vertex V2 ) { /* 检查连接V1和V2的边是否在现有的最小生成树子集中构成回路 */ Vertex Root1 = Find(V1); /* 得到V1所属的连通集名称 */ Vertex Root2 = Find(V2); /* 得到V2所属的连通集名称 */ if(Root1==Root2) /* 若V1和V2已经连通,则该边不能要,返回0 */ return 0; else { /* 否则该边可以被收集,同时将V1和V2并入同一连通集 */ SetUnion(Root1, Root2); return 1; } }
void KruskalALG(ALGraph * G){ char v; int i,j,k,parent1,parent2,EdgeNum; EdgeNode * edge; SetType S[G->n]; MinHeap H; H = (MinHeap)CreateMinHeap(); int Visited[G->n]; // Initialization for(i=0; i<G->n; i++){ S[i].Data = G->Adjlist[i].Vertex; //将所有的顶点存入生成树的集合 S[i].Parent = -1; //一开始所有顶点都是一棵独立的树 Visited[i] = FALSE; edge = G->Adjlist[i].FirstEdge; while( edge ){ //将所有的边组成一个最小堆(越上面的元素值越小) MinHeapInsert(H,edge); edge = edge->Next; } } EdgeNum = 0; while( EdgeNum < (G->n) || !IsEmptyMin(H) ){ //为什么不是找到n-1条边就停下:因为按目前的写法边数的增加次数和点的输出次数保持一致 //要输出n个点,EdgeNum就必须++ n次【需改进】 edge = (EdgeNode*)DeleteMin(H); parent1 = SetFind(S,G->n,edge->Vertex); parent2 = SetFind(S,G->n,edge->AdjV); if( parent1!=parent2 || parent1==-1 ){ if( !Visited[edge->Vertex] ) { printf("Visited Vertex : %c \n",S[edge->Vertex]); Visited[edge->Vertex] = TRUE; EdgeNum++; } if( !Visited[edge->AdjV] ) { printf("Visited Vertex : %c \n",S[edge->AdjV]); Visited[edge->AdjV] = TRUE; EdgeNum++; } SetUnion(S,G->n,edge->Vertex,edge->AdjV); } } if( EdgeNum < G->n ) printf("图不连通\n"); return ; }
void Kruskal(Graph *g, TableInstance t, list<Edge> &edgeList) { Node *v; int edgeAccepted = 0; DisjSet disjSet = new SetType[g->Cells.size()]; InitializeDisjSet(disjSet, g->Cells.size()); PriorityQueue priorityQueue = Initialize(g->Size * 3); InitializeVertextQueue(priorityQueue, t, g->EdgeNumber); while(edgeAccepted < g->Cells.size() - 1) { Table edge = DeleteMin(priorityQueue); SetType set1 = FindInDisjSet(edge.CurrentNode->InternalNumber, disjSet); SetType set2 = FindInDisjSet(edge.ParentNode->InternalNumber, disjSet); if(set1 != set2) { SetUnion(disjSet, set1, set2); edgeList.push_back(Edge{edge.CurrentNode->RealName, edge.ParentNode->RealName, edge.Distance}); edgeAccepted ++; } } delete[] disjSet; }
void set_reduce_branching3(lts_t lts){ int tau,*map,count,*newmap,i,*tmp,iter,s,l,d,setcount,j,set; int itemcount,subitercount,*tmpmap; tau=lts->tau; if (tau_cycle_elim) { lts_tau_cycle_elim(lts); Warning(1,"size after tau cycle elimination is %d states and %d transitions",lts->states,lts->transitions); } if (tau_indir_elim) { lts_tau_indir_elim(lts); Warning(1,"size after trivial tau elimination is %d states and %d transitions",lts->states,lts->transitions); } map=(int*)malloc(sizeof(int)*lts->states); tmpmap=(int*)malloc(sizeof(int)*lts->states); newmap=(int*)malloc(sizeof(int)*lts->states); lts_set_type(lts,LTS_LIST); lts_sort(lts); lts_set_type(lts,LTS_BLOCK); for(i=0;i<lts->states;i++){ map[i]=0; } count=1; iter=0; for(;;){ SetClear(-1); iter++; for(i=0;i<lts->states;i++){ newmap[i]=EMPTY_SET; } for(i=0;i<lts->states;i++){ for(j=lts->begin[i];j<lts->begin[i+1];j++){ if (lts->label[j]!=tau || map[i]!=map[lts->dest[j]]) { newmap[i]=SetInsert(newmap[i],lts->label[j],map[lts->dest[j]]); } } tmpmap[i]=newmap[i]; } subitercount=0; itemcount=1; while(itemcount>0){ subitercount++; for(i=0;i<lts->states;i++){ for(j=lts->begin[i];j<lts->begin[i+1];j++){ if (lts->label[j]==tau && map[i]==map[lts->dest[j]] && tmpmap[i]!= newmap[lts->dest[j]]) { tmpmap[i]=SetUnion(tmpmap[i],newmap[lts->dest[j]]); } } } itemcount=0; for(i=0;i<lts->states;i++){ if (tmpmap[i]!=newmap[i]) { newmap[i]=tmpmap[i]; itemcount++; } } Warning(2,"sub iteration %d had %d changes",subitercount,itemcount); } Warning(1,"Needed %d sub iterations",subitercount); SetSetTag(newmap[lts->root],0); setcount=1; for(i=0;i<lts->states;i++){ set=newmap[i]; newmap[i]=SetGetTag(set); if (newmap[i]<0) { //fprintf(stderr,"new set:"); //PrintSet(stderr,set); //fprintf(stderr,"\n"); SetSetTag(set,setcount); newmap[i]=setcount; setcount++; } } Warning(2,"count is %d",setcount); if(count==setcount) break; count=setcount; tmp=map; map=newmap; newmap=tmp; } SetFree(); free(newmap); lts_set_type(lts,LTS_LIST); lts->root=map[lts->root]; lts->root2=map[lts->root2]; lts->states=count; count=0; for(i=0;i<lts->transitions;i++){ s=map[lts->src[i]]; l=lts->label[i]; d=map[lts->dest[i]]; if ((l==tau)&&(s==d)) continue; lts->src[count]=s; lts->label[count]=l; lts->dest[count]=d; count++; } lts_set_size(lts,lts->states,count); lts_uniq(lts); free(map); Warning(1,"reduction took %d iterations",iter); }
void set_reduce_branching(lts_t lts){ int tau,*map,count,*newmap,i,*tmp,iter,s,l,d,setcount,j,set; int this_union; #ifdef PREV_UNION int prev_union; #endif tau=lts->tau; tau_cycle_elim=1; if (tau_cycle_elim) { lts_tau_cycle_elim(lts); Warning(1,"size after tau cycle elimination is %d states and %d transitions",lts->states,lts->transitions); } if (tau_indir_elim) { lts_tau_indir_elim(lts); Warning(1,"size after trivial tau elimination is %d states and %d transitions",lts->states,lts->transitions); } lts_sort(lts); lts_set_type(lts,LTS_BLOCK); map=(int*)malloc(sizeof(int)*lts->states); newmap=(int*)malloc(sizeof(int)*lts->states); for(i=0;i<lts->states;i++){ map[i]=0; } count=1; iter=0; for(;;){ SetClear(-1); iter++; for(i=lts->states-1;i>=0;i--){ set=EMPTY_SET; #ifdef PREV_UNION prev_union=EMPTY_SET; #endif for(j=lts->begin[i];j<lts->begin[i+1];j++){ if (lts->label[j]==tau && map[i]==map[lts->dest[j]]) { this_union=newmap[lts->dest[j]]; #ifdef PREV_UNION if(this_union!=prev_union){ prev_union=this_union; #endif set=SetUnion(set,this_union); #ifdef PREV_UNION } #endif } else { set=SetInsert(set,lts->label[j],map[lts->dest[j]]); } } newmap[i]=set; } SetSetTag(newmap[lts->root],0); setcount=1; for(i=0;i<lts->states;i++){ set=newmap[i]; newmap[i]=SetGetTag(set); if (newmap[i]<0) { //fprintf(stderr,"new set:"); //PrintSet(stderr,set); //fprintf(stderr,"\n"); SetSetTag(set,setcount); newmap[i]=setcount; setcount++; } } Warning(2,"count is %d",setcount); if(count==setcount) break; count=setcount; tmp=map; map=newmap; newmap=tmp; } SetFree(); free(newmap); lts_set_type(lts,LTS_LIST); lts->root=map[lts->root]; lts->root2=map[lts->root2]; lts->states=count; count=0; for(i=0;i<lts->transitions;i++){ s=map[lts->src[i]]; l=lts->label[i]; d=map[lts->dest[i]]; if ((l==tau)&&(s==d)) continue; lts->src[count]=s; lts->label[count]=l; lts->dest[count]=d; count++; } lts_set_size(lts,lts->states,count); lts_uniq(lts); free(map); Warning(1,"reduction took %d iterations",iter); }
/* Find all nonterminals which will generate the empty string. ** Then go back and compute the first sets of every nonterminal. ** The first set is the set of all terminal symbols which can begin ** a string generated by that nonterminal. */ void FindFirstSets(struct lmno *lmnop) { int i; struct rule *rp; int progress; for(i=0; i<lmnop->nsymbol; i++) { lmnop->symbols[i]->lambda = B_FALSE; } for(i=lmnop->nterminal; i<lmnop->nsymbol; i++) { lmnop->symbols[i]->firstset = SetNew(); } /* First compute all lambdas */ do { progress = 0; for(rp = lmnop->rule; rp; rp = rp->next) { if(rp->lhs->lambda) continue; for(i=0; i<rp->nrhs; i++) { if( rp->rhs[i]->lambda==B_FALSE ) break; } if(i == rp->nrhs) { rp->lhs->lambda = B_TRUE; progress = 1; } } }while( progress ); /* Now compute all first sets */ do { struct symbol *s1, *s2; progress = 0; for(rp = lmnop->rule; rp; rp = rp->next) { s1 = rp->lhs; for(i=0; i<rp->nrhs; i++) { s2 = rp->rhs[i]; if(s2->type == TERMINAL) { progress += SetAdd(s1->firstset,s2->index); break; } else if(s1 == s2) { if(s1->lambda == B_FALSE) break; } else { progress += SetUnion(s1->firstset,s2->firstset); if( s2->lambda==B_FALSE ) break; } } } }while( progress ); return; }