/* Recursive reconquest: tries to reconquest all adjacents. If it does, calls reconquest on them */ void reconquest_recursive(Subgraph *sg, int predecessor, int node, int* oldNodes){ // Tags the current node as 'old', i.e., already tried to reconquer it oldNodes[node] = 1; // Clones the list of adjacents Set* p = CloneSet(sg->node[node].incAdj); // Tries to reconquer the node (check if new pathval would be smaller than current pathval) float reconquerorPathval = opf_ArcWeight(sg->node[predecessor].feat, sg->node[node].feat, sg->nfeats) + sg->node[predecessor].pathval; if (sg->node[node].pathval >= reconquerorPathval){ // Destroy adjacents, will be refilled as reconquest advances DestroySet(&(sg->node[node].incAdj)); sg->node[node].incAdj = NULL; // Reconquer the node sg->node[node].pred = predecessor; sg->node[node].pathval = reconquerorPathval; InsertSet(&(sg->node[predecessor].incAdj),node); InsertSet(&(sg->node[node].incAdj),predecessor); // Tries to reconquer its neighbours while(p != NULL){ if (!oldNodes[p->elem]){ reconquest_recursive(sg, node, p->elem, oldNodes); } p = p->next; } DestroySet(&p); } }
void UnionSet(Set S1, Set S2, Set *S3) { int i; CopySet(S1,&*S3); for (i=1;i<=SetNbElmt(S2);i++) { InsertSet(&*S3,S2.T[i]); } }
Set *ForestRemoval(ImageForest *fst, Set *Rm, AdjRel *A) { int i, p, q, n = fst->cost->ncols*fst->cost->nrows; Image *cost=fst->cost,*pred=fst->pred,*root=fst->root; Pixel u,v; Set *Frontier=NULL, *aux=NULL; BMap *RemRoot = BMapNew(n), *inFrontier = BMapNew(n); int *RemNode=AllocIntArray(n),first=0,last=0; /* Mark all removal roots, whose trees will be removed, reinitialize cost and predecessor values of those roots, and insert them in RemNode, in order to reinitialize the cost and predecessor values of the remaining nodes of the removed trees. */ aux = Rm; while (aux != NULL) { p = root->val[aux->elem]; // get a removal root p if (_fast_BMapGet(RemRoot,p)==0){ // p is not in RemRoot cost->val[p] = INT_MAX; pred->val[p] = NIL; RemNode[last]=p; last++; _fast_BMapSet1(RemRoot,p); } aux = aux->next; } /* Forest removal: reinitialize nodes of the removed trees and create frontier set for the next DIFT. */ while (first != last) { p = RemNode[first]; first++; u.x = p % cost->ncols; u.y = p / cost->ncols; for (i=1; i < A->n; i++) { v.x = u.x + A->dx[i]; v.y = u.y + A->dy[i]; if (ValidPixel(cost,v.x,v.y)){ q = v.x + cost->tbrow[v.y]; if (pred->val[q]==p){ cost->val[q]=INT_MAX; pred->val[q] = NIL; RemNode[last]=q; last++; }else{ if (_fast_BMapGet(RemRoot,root->val[q])==0){ if (_fast_BMapGet(inFrontier,q)==0){ InsertSet(&Frontier,q); _fast_BMapSet1(inFrontier,q); } } } } } } BMapDestroy(inFrontier); BMapDestroy(RemRoot); free(RemNode); return(Frontier); }
Set* arrayToSet(int* array, int size){ Set* S = NULL; int i; for (i = 0; i < size; i++){ InsertSet(&S, array[i]); } return S; }
// Create adjacent list in subgraph: a knn graph void opf_CreateArcs(Subgraph *sg, int knn){ int i,j,l,k; float dist; int *nn=AllocIntArray(knn+1); float *d=AllocFloatArray(knn+1); /* Create graph with the knn-nearest neighbors */ sg->df=0.0; for (i=0; i < sg->nnodes; i++) { for (l=0; l < knn; l++) d[l]=FLT_MAX; for (j=0; j < sg->nnodes; j++) { if (j!=i) { if (!opf_PrecomputedDistance) d[knn] = opf_ArcWeight(sg->node[i].feat,sg->node[j].feat,sg->nfeats); else d[knn] = opf_DistanceValue[sg->node[i].position][sg->node[j].position]; nn[knn]= j; k = knn; while ((k > 0)&&(d[k]<d[k-1])) { dist = d[k]; l = nn[k]; d[k] = d[k-1]; nn[k] = nn[k-1]; d[k-1] = dist; nn[k-1] = l; k--; } } } for (l=0; l < knn; l++) { if (d[l]!=INT_MAX) { if (d[l] > sg->df) sg->df = d[l]; //if (d[l] > sg->node[i].radius) sg->node[i].radius = d[l]; InsertSet(&(sg->node[i].adj),nn[l]); } } } free(d); free(nn); if (sg->df<0.00001) sg->df = 1.0; }
void IntersectionSet(Set S1, Set S2, Set *S3) { int i; if (SetNbElmt(S2)>=SetNbElmt(S1)) { for (i=1;i<=SetNbElmt(S1);i++) { if (IsSetMember(S2,S1.T[i])) InsertSet(&*S3,S1.T[i]); } } else { for (i=1;i<=SetNbElmt(S2);i++) { if (IsSetMember(S1,S2.T[i])) InsertSet(&*S3,S2.T[i]); } } }
/* FIRST VERSION!!!!! WARNING */ void INSERT(Subgraph* sg, int z, int r, int* t, int* oldNodes) { //printf("\t\tINSERT: z is %d, r is %d, t is %d\n", z, r, *t); oldNodes[r] = 1; // mark as 'old' int m = r; // aresta (r,z); int k; // for each vertex w adjacent to 'r' Set *w = sg->node[r].incAdj; while (w != NULL) { // if adjacent node is new and of same label if (!oldNodes[w->elem]) { INSERT(sg, z, w->elem, t, oldNodes); // insert on w->elem double costWR = opf_ArcWeight(sg->node[w->elem].feat, sg->node[r].feat, sg->nfeats); double costT = opf_ArcWeight(sg->node[*t].feat, sg->node[z].feat, sg->nfeats); double costK, costM; // max edge (t, (w,r)) if (costT > costWR) { // insert WR InsertSet(&sg->node[r].incAdj, w->elem); sg->node[r].pred = w->elem; k = *t; costK = opf_ArcWeight(sg->node[*t].feat, sg->node[z].feat, sg->nfeats); } else { // insert TZ InsertSet(&sg->node[z].incAdj, *t); sg->node[z].pred = *t; k = w->elem; costK = opf_ArcWeight(sg->node[w->elem].feat, sg->node[z].feat, sg->nfeats); } costM = opf_ArcWeight(sg->node[m].feat, sg->node[z].feat, sg->nfeats); if (costK < costM) m = k; // deixa a outra para avaliar depois } w = w->next; } *t = m; }
/* Rechecking prototypes function checks if a new node is closer to its own prototype (becoming a new node) or if it is closer to the other prototype (becoming the new prototype) */ void recheckPrototype(Subgraph* sg, int newNode, int predecessor){ // Clarification: 'inner prototype': prototype of newNode's tree // 'outer prototype': prototype of the closest distinct tree; pair of inner-prototype // If the inner prototype is alone (has no outer prototype), simply inserts if (sg->node[predecessor].prototypePair == NIL) { //insert(); return; } // Measures the distance between newNode's prototype and its own pair float prototypesDistance = opf_ArcWeight(sg->node[sg->node[predecessor].prototypePair].feat, sg->node[predecessor].feat, sg->nfeats); // Measures the distance between newNode and its prototype's pair float newNodeDistance = opf_ArcWeight(sg->node[newNode].feat, sg->node[sg->node[predecessor].prototypePair].feat, sg->nfeats); // If newNode is closer to the outer prototype than the inner prototype, it becomes the new prototype if (newNodeDistance < prototypesDistance){ // newNode becomes a prototype and begins reconquest sg->node[newNode].pred = NIL; sg->node[newNode].pathval = 0; //adds its former prototype as an adjacent and updates its pathval InsertSet(&(sg->node[newNode].incAdj), predecessor); sg->node[predecessor].pred = newNode; sg->node[predecessor].pathval = opf_ArcWeight(sg->node[predecessor].feat, sg->node[newNode].feat, sg->nfeats); //printf("\tThe new node is the new prototype! Begin the reconquest..."); reconquest(sg, newNode); } else { // else, newNode simply gets inserted in the tree int* oldNodes = (int*)calloc(sg->nnodes, sizeof(int)); int t = 0; //printf("\tThe new node is not a prototype! Begin INSERT...\n"); INSERT(sg, newNode, predecessor, &t, oldNodes); free(oldNodes); } }
void opf_OPFClustering(Subgraph *sg){ Set *adj_i,*adj_j; char insert_i; int i,j; int p, q, l; float tmp,*pathval=NULL; RealHeap *Q=NULL; Set *Saux=NULL; // Add arcs to guarantee symmetry on plateaus for (i=0; i < sg->nnodes; i++){ adj_i = sg->node[i].adj; while (adj_i != NULL){ j = adj_i->elem; if (sg->node[i].dens==sg->node[j].dens){ // insert i in the adjacency of j if it is not there. adj_j = sg->node[j].adj; insert_i = 1; while (adj_j != NULL){ if (i == adj_j->elem){ insert_i=0; break; } adj_j=adj_j->next; } if (insert_i) InsertSet(&(sg->node[j].adj),i); } adj_i=adj_i->next; } } // Compute clustering pathval = AllocFloatArray(sg->nnodes); Q = CreateRealHeap(sg->nnodes, pathval); SetRemovalPolicyRealHeap(Q, MAXVALUE); for (p = 0; p < sg->nnodes; p++){ pathval[ p ] = sg->node[ p ].pathval; sg->node[ p ].pred = NIL; sg->node[ p ].root = p; InsertRealHeap(Q, p); } l = 0; i = 0; while (!IsEmptyRealHeap(Q)){ RemoveRealHeap(Q,&p); sg->ordered_list_of_nodes[i]=p; i++; if ( sg->node[ p ].pred == NIL ){ pathval[ p ] = sg->node[ p ].dens; sg->node[p].label=l; l++; } sg->node[ p ].pathval = pathval[ p ]; for ( Saux = sg->node[ p ].adj; Saux != NULL; Saux = Saux->next ){ q = Saux->elem; if ( Q->color[q] != BLACK ) { tmp = MIN( pathval[ p ], sg->node[ q ].dens); if ( tmp > pathval[ q ] ){ UpdateRealHeap(Q,q,tmp); sg->node[ q ].pred = p; sg->node[ q ].root = sg->node[ p ].root; sg->node[ q ].label = sg->node[ p ].label; } } } } sg->nlabels = l; DestroyRealHeap( &Q ); free( pathval ); }
// OPFClustering computation only for sg->bestk neighbors void opf_OPFClusteringToKmax(Subgraph *sg) { Set *adj_i,*adj_j; char insert_i; int i,j; int p, q, l, ki,kj; const int kmax = sg->bestk; float tmp,*pathval=NULL; RealHeap *Q=NULL; Set *Saux=NULL; // Add arcs to guarantee symmetry on plateaus for (i=0; i < sg->nnodes; i++) { adj_i = sg->node[i].adj; ki = 1; while (ki <= kmax) { j = adj_i->elem; if (sg->node[i].dens==sg->node[j].dens) { // insert i in the adjacency of j if it is not there. adj_j = sg->node[j].adj; insert_i = 1; kj = 1; while (kj <= kmax) { if (i == adj_j->elem) { insert_i=0; break; } adj_j=adj_j->next; kj++; } if (insert_i) { InsertSet(&(sg->node[j].adj),i); sg->node[j].nplatadj++; //number of adjacent nodes on //plateaus (includes adjacent plateau //nodes computed for previous kmax's) } } adj_i=adj_i->next; ki++; } } // Compute clustering pathval = AllocFloatArray(sg->nnodes); Q = CreateRealHeap(sg->nnodes, pathval); SetRemovalPolicyRealHeap(Q, MAXVALUE); for (p = 0; p < sg->nnodes; p++) { pathval[ p ] = sg->node[ p ].pathval; sg->node[ p ].pred = NIL; sg->node[ p ].root = p; InsertRealHeap(Q, p); } l = 0; i = 0; while (!IsEmptyRealHeap(Q)) { RemoveRealHeap(Q,&p); sg->ordered_list_of_nodes[i]=p; i++; if ( sg->node[ p ].pred == NIL ) { pathval[ p ] = sg->node[ p ].dens; sg->node[p].label=l; l++; } sg->node[ p ].pathval = pathval[ p ]; const int nadj = sg->node[p].nplatadj + kmax; // total amount of neighbors for ( Saux = sg->node[ p ].adj, ki = 1; ki <= nadj; Saux = Saux->next, ki++ ) { q = Saux->elem; if ( Q->color[q] != BLACK ) { tmp = MIN( pathval[ p ], sg->node[ q ].dens); if ( tmp > pathval[ q ] ) { UpdateRealHeap(Q,q,tmp); sg->node[ q ].pred = p; sg->node[ q ].root = sg->node[ p ].root; sg->node[ q ].label = sg->node[ p ].label; } } } } sg->nlabels = l; DestroyRealHeap( &Q ); free( pathval ); }
// Create adjacent list in subgraph: a knn graph. // Returns an array with the maximum distances // for each k=1,2,...,kmax float* opf_CreateArcs2(Subgraph *sg, int kmax) { int i,j,l,k; float dist; int *nn=AllocIntArray(kmax+1); float *d=AllocFloatArray(kmax+1); float *maxdists=AllocFloatArray(kmax); /* Create graph with the knn-nearest neighbors */ sg->df=0.0; for (i=0; i < sg->nnodes; i++) { for (l=0; l < kmax; l++) d[l]=FLT_MAX; for (j=0; j < sg->nnodes; j++) { if (j!=i) { if(!opf_PrecomputedDistance) d[kmax] = opf_ArcWeight(sg->node[i].feat,sg->node[j].feat,sg->nfeats); else d[kmax] = opf_DistanceValue[sg->node[i].position][sg->node[j].position]; nn[kmax]= j; k = kmax; while ((k > 0)&&(d[k]<d[k-1])) { dist = d[k]; l = nn[k]; d[k] = d[k-1]; nn[k] = nn[k-1]; d[k-1] = dist; nn[k-1] = l; k--; } } } sg->node[i].radius = 0.0; sg->node[i].nplatadj = 0; //zeroing amount of nodes on plateaus //making sure that the adjacent nodes be sorted in non-decreasing order for (l=kmax-1; l >= 0; l--) { if (d[l]!=FLT_MAX) { if (d[l] > sg->df) sg->df = d[l]; if (d[l] > sg->node[i].radius) sg->node[i].radius = d[l]; if(d[l] > maxdists[l]) maxdists[l] = d[l]; //adding the current neighbor at the beginnig of the list InsertSet(&(sg->node[i].adj),nn[l]); } } } free(d); free(nn); if (sg->df<0.00001) sg->df = 1.0; return maxdists; }