VGraph VGraphHemi(VGraph src,VLong hemi) { VString str; VGraph dest=NULL; int i,j,n,ncols,half=0; float x,y,z,val=0; VNode node,node1; int *table; half = 80; /* standard coordinate for inter-hemisperic cleft */ if (VGetAttr (VGraphAttrList (src), "ca", NULL,VStringRepn, (VPointer) & str) == VAttrFound) { sscanf(str,"%f %f %f",&x,&y,&z); ncols = (int) x; half = ncols/2; } table = (int *) VMalloc(sizeof(int) * (src)->lastUsed + 1); for (i=0; i<= src->lastUsed; i++) table[i] = 0; n = (src)->lastUsed/2; dest = VCreateGraph(n,VGraphNFields(src),VNodeRepn(src),src->useWeights); for (i=1; i<=(src)->lastUsed; i++) { node = (VNode) VGraphGetNode (src,i); if (node == 0) continue; VReadNode((src),node,&x,&y,&z,&val); if ((hemi == 0 && x <= half) || (hemi == 1 && x > half)) { n = VGraphAddNode(dest,(VNode) node); table[i] = n; } } for (i=1; i<=(src)->lastUsed; i++) { node = (VNode) VGraphGetNode (src,i); if (node == 0) continue; for (j=1; j<=(src)->lastUsed; j++) { node1 = (VNode) VGraphGetNode (src,j); if (node1 == 0) continue; if (table[i] == 0 || table[j] == 0) continue; if (VGraphIsAdjacent(src,i,j) == TRUE) { VGraphLinkNodes(dest,table[i],table[j]); } } } VFree(table); return dest; }
int VGraphVisitNodesFrom(VGraph graph, int i) { VAdjacency adj; VNode n, p; int cycles = 0; if (graph == 0 || (n = VGraphGetNode(graph, i)) == 0) return 0; if (n->base.hops > 0) return 1; n->base.hops++; for (adj = n->base.head; adj; adj = adj->next) { p = VGraphGetNode(graph, adj->id); if (p && p->base.hops > 0) continue; cycles += VGraphVisitNodesFrom(graph, adj->id); }; return cycles; }
int VGraphResizeFields (VGraph graph, int newfields) { VNode o, n; int i; int nsize = sizeof(VNodeBaseRec) + (newfields * VRepnPrecision(graph->node_repn)) / 8; int osize = VNodeSize(graph); if (newfields <= graph->nfields) return TRUE; for (i = 1; i <= graph->lastUsed; i++) { if (VGraphNodeIsFree(graph, i)) continue; o = VGraphGetNode(graph, i); n = VCalloc(1, nsize); memcpy(n, o, osize); VGraphGetNode(graph, i) = n; VFree(o); }; graph->nfields = newfields; return TRUE; }
int VGraphAddNodeAt (VGraph graph, VNode node, int position) { VDestroyNodeSimple(graph, position); VGraphGetNode(graph, position) = VCopyNodeShallow(graph, node); graph->nnodes++; if (position > graph->lastUsed) graph->lastUsed = position; return position; }
void VDestroyNode(VGraph graph, int i) { VAdjacency p, q; VNode n; n = VGraphGetNode(graph, i); if (n == 0) return; /* destroy adjacency list */ for (p = n->base.head; p; p = q) { /* remove connection from other node to this node */ VGraphUnlinkNodes(graph, p->id, i); q = p->next; VFree(p); }; VFree(n); VGraphGetNode(graph, i) = 0; graph->nnodes--; assert(graph->nnodes >= 0); }
static void VGraphRemoveNodes(VGraph graph) { int i; for (i = 1; i <= graph->lastUsed; i++) { VNode n = VGraphGetNode(graph, i); if (n && n->base.visited) VDestroyNode(graph, i); }; }
static VNode seqNode(VGraph graph, int i) { while (i <= graph->lastUsed) { VNode n = VGraphGetNode(graph, i); if (n) { graph->iter = i; return n; }; i++; }; return 0; }
void VGraphClearHops(VGraph graph) { int i; if (graph == 0) return; for (i = 1; i <= graph->lastUsed; i++) { VNode n = VGraphGetNode(graph, i); if (n) n->base.hops = 0; }; }
static void VDestroyNodeSimple(VGraph graph, int i) /* simple deletion: just look at structures of this node */ { VAdjacency p, q; VNode n; n = VGraphGetNode(graph, i); if (n == NULL) return; /* destroy adjacency list */ for (p = n->base.head; p; p = q) { q = p->next; VFree(p); }; VFree(n); VGraphGetNode(graph, i) = 0; graph->nnodes--; assert(graph->nnodes >= 0); }
void linkNodes(VGraph graph, VLong a, VLong b) // make bidrectional link between nodes a and b { VNode n; VAdjacency adj; if (a == 0 || b == 0 || a == b) return; n = VGraphGetNode(graph, a); if (n == 0) return; for (adj = n->base.head; adj; adj = adj->next) if (adj->id == (unsigned long)b) goto rev; VGraphLinkNodes(graph, a, b); rev: n = VGraphGetNode(graph, b); if (n == 0) return; for (adj = n->base.head; adj; adj = adj->next) if (adj->id == (unsigned long)a) return; VGraphLinkNodes(graph, b, a); }
static int firstUnvisitedNode(VGraph graph) { int i; for (i = 1; i <= graph->lastUsed; i++) { VNode n = VGraphGetNode(graph, i); if (n && n->base.hops == 0) return i; }; return 0; }
static VPointer VGraphEncodeDataMethod (VPointer value, VAttrList list, size_t length, VBoolean *free_itp) { VGraph graph = value; VAttrListPosn posn; VNode n; size_t len; VPointer p, ptr; VAdjacency adj; int i, nadj; #define pack(repn, cnt, dest) \ if (! VPackData (repn, cnt, dest, VMsbFirst, &len, &p, NULL)) return NULL; \ p = (char *) p + len; length -= len; len = length; /* Remove the attributes prepended by the VGraphEncodeAttrsMethod: */ for (VFirstAttr (list, & posn); strcmp (VGetAttrName (& posn), VRepnAttr) != 0; VDeleteAttr (& posn)); VDeleteAttr (& posn); /* Allocate a buffer for the encoded data: */ if (length == 0) { *free_itp = FALSE; return value; /* we may return anything != 0 here */ }; p = ptr = VMalloc (length); len = length; /* Pack each node: */ for (i = 1; i <= graph->size; i++) { n = VGraphGetNode(graph, i); if (n == 0) continue; /* Count the number of adjacencies : */ for (adj = n->base.head, nadj = 0; adj; adj = adj->next) nadj++; /* Pack the header */ pack(VLongRepn, 1, &i); pack(VLongRepn, 1, &nadj); /* Pack the adjacencies : */ for (adj = n->base.head; adj; adj = adj->next) { pack(VLongRepn, 1, &adj->id); if (graph->useWeights) { pack(VFloatRepn, 1, &adj->weight); }; }; /* Pack the node itself: */ if (graph->useWeights) { pack(VFloatRepn, 1, &(n->base.weight)); }; pack(graph->node_repn, graph->nfields, n->data); } *free_itp = TRUE; return ptr; }
void VGraphToggleNodesFrom(VGraph graph, int i) { VAdjacency adj; VNode n, p; /* find a valid starting point */ if (graph == 0 || (n = VGraphGetNode(graph, i)) == 0) return; /* mark this node and toggle the hops field */ if (n->base.visited == 1) return; n->base.visited = 1; n->base.hops = n->base.hops? 0: 1; /* now look at the neighbors */ for (adj = n->base.head; adj; adj = adj->next) { p = VGraphGetNode(graph, adj->id); if (p && p->base.visited) continue; VGraphToggleNodesFrom(graph, adj->id); }; }
VGraph VGraphExtractNodes (VGraph src) { VGraph dst; VAdjacency adj; VNode n; int i, j; /* create a destination graph much like src */ dst = VCreateGraph(src->size, src->nfields, src->node_repn, src->useWeights); /* copy selected nodes from src */ for (i = j = 1; i <= src->lastUsed; i++) { n = VGraphGetNode(src, i); if (n && n->base.hops) dst->table[j] = VCopyNodeShallow(src, n); }; /* set number of nodes used */ dst->nnodes = j-1; dst->lastUsed = j; /* now link nodes in new graph */ for (i = 1; i <= dst->lastUsed; i++) { n = VGraphGetNode(dst, i); if (n == 0) continue; j = VGraphLookupNode(src, n); if (j == 0) continue; n = VGraphGetNode(src, j); for (adj = n->base.head; adj; adj = adj->next) { n = VGraphGetNode(src, adj->id); j = VGraphLookupNode(dst, n); if (j) VGraphLinkNodes(dst, i, j); }; }; if (VGraphAttrList (dst)) VDestroyAttrList (VGraphAttrList (dst)); if (VGraphAttrList (src)) VGraphAttrList (dst) = VCopyAttrList (VGraphAttrList (src)); return dst; }
void VNodeRemoveLinks(VGraph graph, int pos) { VNode n; VAdjacency adj, nxt; if (VGraphNodeIsFree(graph, pos)) return; n = VGraphGetNode(graph, pos); for (adj = n->base.head; adj; adj = nxt) { nxt = adj->next; VFree(adj); }; n->base.head = 0; }
int VGraphLookupNode (VGraph graph, VNode node) { int n = (graph->nfields * VRepnPrecision(graph->node_repn)) / 8; int i; for (i = 1; i <= graph->lastUsed; i++) { if (VGraphNodeIsFree(graph, i)) continue; if (memcmp(node->data, VGraphGetNode(graph, i)->data, n) == 0) return i; }; return 0; }
void VGraphClearVisit(VGraph graph) { VNode n; int i; if (graph == 0) return; for (i = 1; i <= graph->lastUsed; i++) { if (VGraphNodeIsFree(graph, i)) continue; n = VGraphGetNode(graph, i); VNodeClearVisit(&n->base); }; }
int hasLink (VGraph graph, int a, int b) { VNode n; VAdjacency adj; if (a == 0 || b == 0 || a == b) return FALSE; n = VGraphGetNode (graph, a); for (adj = n->base.head; adj; adj = adj->next) if (adj->id == b) return TRUE; return FALSE; }
int VGraphLinkNodes (VGraph graph, int a, int b) { VNode n; VAdjacency adj; if (VGraphNodeIsFree(graph, a) || VGraphNodeIsFree(graph, b)) return FALSE; n = VGraphGetNode(graph, a); adj = VMalloc(sizeof(VAdjRec)); adj->id = b; adj->weight = 0; adj->next = n->base.head; n->base.head = adj; return TRUE; }
static VAttrList VGraphEncodeAttrMethod (VPointer value, size_t *lengthp) { VGraph graph = value; VAttrList list; size_t len, nadj; int i, slong, sfloat, spriv, nnodes; VNode n; VAdjacency adj; /* Compute the file space needed for the Graph's binary data: */ len = 0; slong = VRepnPrecision (VLongRepn) / 8; sfloat = VRepnPrecision (VFloatRepn) / 8; spriv = graph->nfields * VRepnPrecision (graph->node_repn) / 8; nnodes = 0; for (i = 1; i <= graph->size; i++) { n = VGraphGetNode(graph, i); if (n == 0) continue; ++nnodes; /* Count the number of adjacencies : */ for (adj = n->base.head, nadj = 0; adj; adj = adj->next) nadj++; /* each node contains: * an index and the number of adjacencies * the private data area * the list of adjacencies * optionally reserve space for weights */ len += 2 * slong + nadj * slong + spriv; if (graph->useWeights) len += (nadj+1) * sfloat; }; *lengthp = len; assert(nnodes == graph->nnodes); /* for debugging */ graph->nnodes = nnodes; /* just to be safe for now... */ /* Temporarily prepend several attributes to the graph's list: */ if ((list = VGraphAttrList (graph)) == NULL) list = VGraphAttrList (graph) = VCreateAttrList (); VPrependAttr (list, VRepnAttr, VNumericRepnDict, VLongRepn, (VLong) graph->node_repn); VPrependAttr (list, VNNodeFieldsAttr, NULL, VLongRepn, (VLong) graph->nfields); VPrependAttr (list, VNGraphSizeAttr, NULL, VLongRepn, (VLong) graph->size); VPrependAttr (list, VNNodeWeightsAttr, NULL, VLongRepn, (VLong) graph->useWeights); return list; }
int VGraphAddAndGrow(VGraph graph, VNode node, int pos) { VNode dst; if (graph->lastUsed == graph->size || pos > graph->size) if (growGraphPos(graph, pos) == 0) return 0; if (node == 0) return 0; VDestroyNode(graph, pos); dst = (VNode)VCalloc(1, VNodeSize(graph)); memcpy(dst, node, VNodeSize(graph)); dst->base.head = 0; VGraphGetNode(graph, pos) = dst; if (pos > graph->lastUsed) graph->lastUsed = pos; return pos; }
/* ** test adjacency */ VBoolean VGraphIsAdjacent(VGraph graph,int i,int j) { VNode node; VAdjacency neighb; VNodeBaseRec base; node = (VNode) VGraphGetNode(graph,i); base = node->base; neighb = base.head; while ((neighb != NULL)) { if (neighb->id == j) return TRUE; neighb = neighb->next; } return FALSE; }
VGraph VCopyGraph (VGraph src) { VGraph dst; int i; dst = VCreateGraph (src->size, src->nfields, src->node_repn, src->useWeights); /* copy each used node in table */ for (i = 1; i <= src->size; i++) dst->table[i-1] = VCopyNodeDeep(src, VGraphGetNode(src, i)); dst->nnodes = src->nnodes; dst->lastUsed = src->lastUsed; if (VGraphAttrList (dst)) VDestroyAttrList (VGraphAttrList (dst)); if (VGraphAttrList (src)) VGraphAttrList (dst) = VCopyAttrList (VGraphAttrList (src)); return dst; }
int VGraphUnlinkNodes (VGraph graph, int a, int b) { VNode n; VAdjacency adj, prev; if (VGraphNodeIsFree(graph, a) || VGraphNodeIsFree(graph, b)) return FALSE; n = VGraphGetNode(graph, a); prev = 0; for (adj = n->base.head; adj; adj = adj->next) { if (adj->id == (unsigned int)b) { if (prev) prev->next = adj->next; else n->base.head = adj->next; VFree(adj); return TRUE; }; prev = adj; }; return FALSE; }